replace : iotivity -> iotivity-sec 10/153710/3 accepted/tizen/unified/20171010.063815 submit/tizen/20171010.021131
authorHongkuk, Son <hongkuk.son@samsung.com>
Fri, 29 Sep 2017 07:24:47 +0000 (16:24 +0900)
committerHongkuk, Son <hongkuk.son@samsung.com>
Tue, 10 Oct 2017 01:49:42 +0000 (10:49 +0900)
Signed-off-by: Hongkuk, Son <hongkuk.son@samsung.com>
Change-Id: I5096b7e6faeadd98d5ee48279b24cb9fbdb1f24f

897 files changed:
.gitignore
NOTICE.md
Readme.scons.txt
SConstruct
android/android_api/SConscript
android/android_api/base/build.gradle
android/android_api/base/jni/Android.mk
android/android_api/base/jni/JniCaInterface.c
android/android_api/base/jni/JniCaInterface.h
android/android_api/base/jni/JniConfirmNumListener.cpp [new file with mode: 0644]
android/android_api/base/jni/JniConfirmNumListener.h [new file with mode: 0644]
android/android_api/base/jni/JniDisplayVerifyNumListener.cpp [new file with mode: 0644]
android/android_api/base/jni/JniDisplayVerifyNumListener.h [new file with mode: 0644]
android/android_api/base/jni/JniKeepAliveListener.cpp [new file with mode: 0644]
android/android_api/base/jni/JniKeepAliveListener.h [new file with mode: 0644]
android/android_api/base/jni/JniOcPlatform.cpp
android/android_api/base/jni/JniOcPlatform.h
android/android_api/base/jni/JniOcProvisioning.cpp
android/android_api/base/jni/JniOcProvisioning.h
android/android_api/base/jni/JniOcResource.cpp
android/android_api/base/jni/JniOcResource.h
android/android_api/base/jni/JniOcSecureResource.cpp
android/android_api/base/jni/JniOcSecurity.cpp [changed mode: 0644->0755]
android/android_api/base/jni/JniOcSecurity.h [changed mode: 0644->0755]
android/android_api/base/jni/JniUtils.h
android/android_api/base/src/main/java/org/iotivity/base/MVJustWorksOptionMask.java [new file with mode: 0644]
android/android_api/base/src/main/java/org/iotivity/base/OcPlatform.java
android/android_api/base/src/main/java/org/iotivity/base/OcProvisioning.java
android/android_api/base/src/main/java/org/iotivity/base/OcResource.java
android/android_api/base/src/main/java/org/iotivity/base/PinType.java [new file with mode: 0644]
android/android_api/base/src/main/java/org/iotivity/base/PlatformConfig.java
android/android_api/base/src/main/java/org/iotivity/ca/CaBtPairingInterface.java
android/android_api/base/src/main/java/org/iotivity/ca/CaEdrInterface.java
android/android_api/base/src/main/java/org/iotivity/ca/CaInterface.java
android/android_api/base/src/main/java/org/iotivity/ca/CaIpInterface.java
android/android_api/base/src/main/java/org/iotivity/ca/CaLeClientInterface.java
android/android_api/base/src/main/java/org/iotivity/ca/CaLeServerInterface.java
android/android_api/base/src/main/java/org/iotivity/ca/CaTransportFlags.java [new file with mode: 0644]
android/android_api/base/src/main/java/org/iotivity/ca/OicCipher.java
android/examples/cloudprovisioningclient/src/main/java/org/iotivity/base/examples/cloudprovisioningclient/CloudProvisioningClient.java [changed mode: 0755->0644]
android/examples/provisioningclient/src/main/AndroidManifest.xml
android/examples/provisioningclient/src/main/assets/oic_svr_db_client_default.dat [new file with mode: 0644]
android/examples/provisioningclient/src/main/assets/oic_svr_db_client_enc.dat [new file with mode: 0644]
android/examples/provisioningclient/src/main/assets/oic_svr_db_client_plain.dat [new file with mode: 0644]
android/examples/provisioningclient/src/main/assets/oic_svr_db_client_rescue.dat [new file with mode: 0644]
android/examples/provisioningclient/src/main/java/org/iotivity/base/examples/provisioningclient/ProvisioningClient.java
android/examples/provisioningclient/src/main/java/org/iotivity/base/examples/provisioningclient/StringConstants.java
android/examples/provisioningclient/src/main/res/menu/menu_secure_provision_client.xml
android/examples/settings.gradle [changed mode: 0755->0644]
android/examples/simplebase/src/main/AndroidManifest.xml
android/examples/simplebase/src/main/java/org/iotivity/base/examples/BluetoothFragment.java
android/examples/simplebase/src/main/java/org/iotivity/base/examples/Common.java
android/examples/simplebase/src/main/java/org/iotivity/base/examples/DrawerFragment.java
android/examples/simplebase/src/main/java/org/iotivity/base/examples/KeepAliveFragment.java [new file with mode: 0644]
android/examples/simplebase/src/main/java/org/iotivity/base/examples/MessageFragment.java
android/examples/simplebase/src/main/java/org/iotivity/base/examples/SimpleBase.java
android/examples/simplebase/src/main/res/layout/fragment_keepalive.xml [new file with mode: 0644]
android/examples/simplebase/src/main/res/values/strings.xml
build-da-checkout.sh [new file with mode: 0755]
build-im-sc-android.sh [new file with mode: 0755]
build-im-sc-android64.sh [new file with mode: 0755]
build-im-sc-ios.sh [new file with mode: 0644]
build-im-virtual_device-android.sh [new file with mode: 0755]
build-vd-tv-es-tizen30.sh [new file with mode: 0644]
build-vd-tv-tizen30.sh [new file with mode: 0755]
build_common/SConscript
build_common/android/SConscript
build_common/thread.scons
build_common/tizen/SConscript
build_common/tizenrt/SConscript [new file with mode: 0644]
build_common/tools/UnpackAll.py
cloud/resourcedirectory/src/test/java/org/iotivity/cloud/testrdserver/DiscoveryResourceTest.java
cloud/samples/client/thin_light/thin_room_light.cpp
extlibs/boost/SConscript
extlibs/libcoap/SConscript
extlibs/mbedtls/SConscript
extlibs/mbedtls/mbedtls/library/net.c [new file with mode: 0644]
extlibs/mbedtls/mbedtls/library/ssl_cli.c
extlibs/mbedtls/ocf.patch
extlibs/sqlite3/SConscript
extlibs/tinycbor/tinycbor/Makefile
extlibs/tinycbor/tinycbor/Makefile.configure [deleted file]
extlibs/tinycbor/tinycbor/Makefile.nmake [deleted file]
extlibs/tinycbor/tinycbor/VERSION
extlibs/tinycbor/tinycbor/src/cbor.h
extlibs/tinycbor/tinycbor/src/cborencoder.c
extlibs/tinycbor/tinycbor/src/cborencoder_close_container_checked.c
extlibs/tinycbor/tinycbor/tools/Makefile [deleted file]
extlibs/tinycbor/tinycbor/tools/json2cbor/json2cbor.c
extlibs/tinydtls/0001-Add-TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256-cipher-su.patch [deleted file]
extlibs/tinydtls/0001-Added-anonymous-ecdh-cipher-suite-into-tinydtls.patch [deleted file]
extlibs/tinydtls/0001-Added-support-in-tinyDTLS-to-support-rehandshake.patch [deleted file]
extlibs/tinydtls/0001-Adding-autoconf-generated-files-in-tinydtls-repo.patch [deleted file]
extlibs/tinydtls/0001-Bug-Fix-in-earlier-rehandhsake-implementation.patch [deleted file]
extlibs/tinydtls/0001-Fix-the-wrong-implementation-about-the-anonymous-cip.patch [deleted file]
extlibs/tinydtls/0001-Fixed-issue-to-pass-PSK-identity-hint-to-application.patch [deleted file]
extlibs/tinydtls/0001-Updated-tinyDTLS-test-apps-to-use-identity-hint.patch [deleted file]
extlibs/tinydtls/0001-add-support-of-X.509-into-tinyDTLS-external-library.patch [deleted file]
extlibs/tinydtls/Android.mk [deleted file]
extlibs/tinydtls/LICENSE [deleted file]
extlibs/tinydtls/Makefile.in [deleted file]
extlibs/tinydtls/Makefile.tinydtls [deleted file]
extlibs/tinydtls/README [deleted file]
extlibs/tinydtls/README_Iotivity [deleted file]
extlibs/tinydtls/SConscript [deleted file]
extlibs/tinydtls/aes/Makefile.in [deleted file]
extlibs/tinydtls/aes/rijndael.c [deleted file]
extlibs/tinydtls/aes/rijndael.h [deleted file]
extlibs/tinydtls/alert.h [deleted file]
extlibs/tinydtls/ccm.c [deleted file]
extlibs/tinydtls/ccm.h [deleted file]
extlibs/tinydtls/configure.in [deleted file]
extlibs/tinydtls/crypto.c [deleted file]
extlibs/tinydtls/crypto.h [deleted file]
extlibs/tinydtls/debug.c [deleted file]
extlibs/tinydtls/debug.h [deleted file]
extlibs/tinydtls/doc/Doxyfile.in [deleted file]
extlibs/tinydtls/doc/DoxygenLayout.xml [deleted file]
extlibs/tinydtls/doc/Makefile.in [deleted file]
extlibs/tinydtls/dtls.c [deleted file]
extlibs/tinydtls/dtls.h [deleted file]
extlibs/tinydtls/dtls_config.h [deleted file]
extlibs/tinydtls/dtls_config.h.in [deleted file]
extlibs/tinydtls/dtls_hal.h [deleted file]
extlibs/tinydtls/dtls_time.c [deleted file]
extlibs/tinydtls/dtls_time.h [deleted file]
extlibs/tinydtls/ecc/LICENSE.txt [deleted file]
extlibs/tinydtls/ecc/Makefile.contiki [deleted file]
extlibs/tinydtls/ecc/Makefile.ecc [deleted file]
extlibs/tinydtls/ecc/Makefile.in [deleted file]
extlibs/tinydtls/ecc/README.md [deleted file]
extlibs/tinydtls/ecc/asm_arm.inc [deleted file]
extlibs/tinydtls/ecc/asm_avr.inc [deleted file]
extlibs/tinydtls/ecc/ecc.c [deleted file]
extlibs/tinydtls/ecc/ecc.h [deleted file]
extlibs/tinydtls/ecc/test/ecc_test/ecc_test.ino [deleted file]
extlibs/tinydtls/ecc/test/emk_rules.py [deleted file]
extlibs/tinydtls/ecc/test/test_ecdh.c [deleted file]
extlibs/tinydtls/ecc/test/test_ecdsa.c [deleted file]
extlibs/tinydtls/examples/contiki/Makefile.in [deleted file]
extlibs/tinydtls/examples/contiki/dtls-client.c [deleted file]
extlibs/tinydtls/examples/contiki/dtls-server.c [deleted file]
extlibs/tinydtls/global.h [deleted file]
extlibs/tinydtls/hmac.c [deleted file]
extlibs/tinydtls/hmac.h [deleted file]
extlibs/tinydtls/netq.c [deleted file]
extlibs/tinydtls/netq.h [deleted file]
extlibs/tinydtls/numeric.h [deleted file]
extlibs/tinydtls/peer.c [deleted file]
extlibs/tinydtls/peer.h [deleted file]
extlibs/tinydtls/platform-specific/Makefile.in [deleted file]
extlibs/tinydtls/platform-specific/config-cc2538dk.h [deleted file]
extlibs/tinydtls/platform-specific/config-econotag.h [deleted file]
extlibs/tinydtls/platform-specific/config-minimal-net.h [deleted file]
extlibs/tinydtls/platform-specific/config-sky.h [deleted file]
extlibs/tinydtls/platform-specific/config-wismote.h [deleted file]
extlibs/tinydtls/prng.h [deleted file]
extlibs/tinydtls/session.c [deleted file]
extlibs/tinydtls/session.h [deleted file]
extlibs/tinydtls/sha2/Makefile.in [deleted file]
extlibs/tinydtls/sha2/README [deleted file]
extlibs/tinydtls/sha2/sha2.c [deleted file]
extlibs/tinydtls/sha2/sha2.h [deleted file]
extlibs/tinydtls/sha2/sha2prog.c [deleted file]
extlibs/tinydtls/sha2/sha2speed.c [deleted file]
extlibs/tinydtls/sha2/sha2test.pl [deleted file]
extlibs/tinydtls/sha2/testvectors/vector001.dat [deleted file]
extlibs/tinydtls/sha2/testvectors/vector001.info [deleted file]
extlibs/tinydtls/sha2/testvectors/vector002.dat [deleted file]
extlibs/tinydtls/sha2/testvectors/vector002.info [deleted file]
extlibs/tinydtls/sha2/testvectors/vector003.dat [deleted file]
extlibs/tinydtls/sha2/testvectors/vector003.info [deleted file]
extlibs/tinydtls/sha2/testvectors/vector004.dat [deleted file]
extlibs/tinydtls/sha2/testvectors/vector004.info [deleted file]
extlibs/tinydtls/sha2/testvectors/vector005.dat [deleted file]
extlibs/tinydtls/sha2/testvectors/vector005.info [deleted file]
extlibs/tinydtls/sha2/testvectors/vector006.dat [deleted file]
extlibs/tinydtls/sha2/testvectors/vector006.info [deleted file]
extlibs/tinydtls/sha2/testvectors/vector007.dat [deleted file]
extlibs/tinydtls/sha2/testvectors/vector007.info [deleted file]
extlibs/tinydtls/sha2/testvectors/vector008.dat [deleted file]
extlibs/tinydtls/sha2/testvectors/vector008.info [deleted file]
extlibs/tinydtls/sha2/testvectors/vector009.dat [deleted file]
extlibs/tinydtls/sha2/testvectors/vector009.info [deleted file]
extlibs/tinydtls/sha2/testvectors/vector010.dat [deleted file]
extlibs/tinydtls/sha2/testvectors/vector010.info [deleted file]
extlibs/tinydtls/sha2/testvectors/vector011.dat [deleted file]
extlibs/tinydtls/sha2/testvectors/vector011.info [deleted file]
extlibs/tinydtls/sha2/testvectors/vector012.dat [deleted file]
extlibs/tinydtls/sha2/testvectors/vector012.info [deleted file]
extlibs/tinydtls/sha2/testvectors/vector013.dat [deleted file]
extlibs/tinydtls/sha2/testvectors/vector013.info [deleted file]
extlibs/tinydtls/sha2/testvectors/vector014.dat [deleted file]
extlibs/tinydtls/sha2/testvectors/vector014.info [deleted file]
extlibs/tinydtls/sha2/testvectors/vector015.dat [deleted file]
extlibs/tinydtls/sha2/testvectors/vector015.info [deleted file]
extlibs/tinydtls/sha2/testvectors/vector016.dat [deleted file]
extlibs/tinydtls/sha2/testvectors/vector016.info [deleted file]
extlibs/tinydtls/sha2/testvectors/vector017.dat [deleted file]
extlibs/tinydtls/sha2/testvectors/vector017.info [deleted file]
extlibs/tinydtls/sha2/testvectors/vector018.dat [deleted file]
extlibs/tinydtls/sha2/testvectors/vector018.info [deleted file]
extlibs/tinydtls/state.h [deleted file]
extlibs/tinydtls/t_list.h [deleted file]
extlibs/tinydtls/tests/Makefile.in [deleted file]
extlibs/tinydtls/tests/cbc_aes128-test.c [deleted file]
extlibs/tinydtls/tests/cbc_aes128-testdata.c [deleted file]
extlibs/tinydtls/tests/ccm-test.c [deleted file]
extlibs/tinydtls/tests/ccm-testdata.c [deleted file]
extlibs/tinydtls/tests/dsrv-test.c [deleted file]
extlibs/tinydtls/tests/dtls-client.c [deleted file]
extlibs/tinydtls/tests/dtls-server.c [deleted file]
extlibs/tinydtls/tests/netq-test.c [deleted file]
extlibs/tinydtls/tests/pcap.c [deleted file]
extlibs/tinydtls/tests/prf-test.c [deleted file]
extlibs/tinydtls/tests/secure-server.c [deleted file]
extlibs/tinydtls/tinydtls.h [deleted file]
extlibs/tinydtls/tinydtls.h.in [deleted file]
extlibs/tinydtls/uthash.h [deleted file]
extlibs/tinydtls/utlist.h [deleted file]
gbsbuild.sh
iotivity.pc.in
packaging/iotivity.pc.in [new file with mode: 0644]
packaging/iotivity.spec [changed mode: 0644->0755]
packaging/snapshot_history.txt [new file with mode: 0755]
resource/SConscript
resource/c_common/SConscript
resource/c_common/ocrandom/src/ocrandom.c
resource/c_common/octhread/include/octhread.h [new file with mode: 0644]
resource/c_common/octhread/src/noop/octhread.c [moved from resource/csdk/connectivity/common/src/camutex_noop.c with 56% similarity]
resource/c_common/octhread/src/posix/octhread.c [moved from resource/csdk/connectivity/common/src/camutex_pthreads.c with 67% similarity]
resource/c_common/octhread/src/windows/octhread.c [new file with mode: 0644]
resource/c_common/platform_features.h
resource/c_common/utlist.h [new file with mode: 0644]
resource/csdk/SConscript
resource/csdk/connectivity/SConscript
resource/csdk/connectivity/api/cacommon.h
resource/csdk/connectivity/api/cainterface.h
resource/csdk/connectivity/api/casecurityinterface.h
resource/csdk/connectivity/api/cautilinterface.h
resource/csdk/connectivity/build/android/jni/Android.mk
resource/csdk/connectivity/build/tizen/Makefile
resource/csdk/connectivity/build/tizen/gbsbuild.sh
resource/csdk/connectivity/build/tizen/packaging/com.oic.ca.spec
resource/csdk/connectivity/build/tizen/scons/SConscript
resource/csdk/connectivity/common/SConscript
resource/csdk/connectivity/common/inc/camutex.h [deleted file]
resource/csdk/connectivity/common/inc/cathreadpool.h
resource/csdk/connectivity/common/inc/uarraylist.h
resource/csdk/connectivity/common/inc/uqueue.h
resource/csdk/connectivity/common/src/caremotehandler.c
resource/csdk/connectivity/common/src/cathreadpool_pthreads.c
resource/csdk/connectivity/common/src/uarraylist.c
resource/csdk/connectivity/common/src/uqueue.c
resource/csdk/connectivity/inc/ca_adapter_net_ssl.h
resource/csdk/connectivity/inc/caadapterinterface.h
resource/csdk/connectivity/inc/caadapternetdtls.h
resource/csdk/connectivity/inc/caadapterutils.h
resource/csdk/connectivity/inc/cablockwisetransfer.h
resource/csdk/connectivity/inc/caedrinterface.h
resource/csdk/connectivity/inc/cafragmentation.h
resource/csdk/connectivity/inc/cainterfacecontroller.h
resource/csdk/connectivity/inc/caipinterface.h
resource/csdk/connectivity/inc/caleadapter.h
resource/csdk/connectivity/inc/caleinterface.h
resource/csdk/connectivity/inc/camessagehandler.h
resource/csdk/connectivity/inc/canfcinterface.h
resource/csdk/connectivity/inc/caqueueingthread.h
resource/csdk/connectivity/inc/caretransmission.h
resource/csdk/connectivity/inc/catcpadapter.h
resource/csdk/connectivity/inc/catcpinterface.h
resource/csdk/connectivity/lib/libcoap-4.1.1/include/coap/address.h
resource/csdk/connectivity/lib/libcoap-4.1.1/include/coap/config.h
resource/csdk/connectivity/lib/libcoap-4.1.1/include/coap/encode.h
resource/csdk/connectivity/lib/libcoap-4.1.1/include/coap/net.h
resource/csdk/connectivity/lib/libcoap-4.1.1/resource.c
resource/csdk/connectivity/src/SConscript
resource/csdk/connectivity/src/adapter_util/ca_adapter_net_ssl.c
resource/csdk/connectivity/src/adapter_util/caadapterutils.c
resource/csdk/connectivity/src/adapter_util/cafragmentation.c
resource/csdk/connectivity/src/bt_edr_adapter/android/caedrclient.c
resource/csdk/connectivity/src/bt_edr_adapter/android/caedrnwmonitor.c
resource/csdk/connectivity/src/bt_edr_adapter/android/caedrserver.c
resource/csdk/connectivity/src/bt_edr_adapter/android/caedrutils.c
resource/csdk/connectivity/src/bt_edr_adapter/caedradapter.c
resource/csdk/connectivity/src/bt_edr_adapter/tizen/caedrclient.c
resource/csdk/connectivity/src/bt_edr_adapter/tizen/caedrendpoint.c
resource/csdk/connectivity/src/bt_edr_adapter/tizen/caedrendpoint.h
resource/csdk/connectivity/src/bt_edr_adapter/tizen/caedrserver.c
resource/csdk/connectivity/src/bt_le_adapter/android/SConscript
resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.c
resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.h
resource/csdk/connectivity/src/bt_le_adapter/android/calenwmonitor.c
resource/csdk/connectivity/src/bt_le_adapter/android/caleserver.c
resource/csdk/connectivity/src/bt_le_adapter/android/caleserver.h
resource/csdk/connectivity/src/bt_le_adapter/android/calestate.c [new file with mode: 0644]
resource/csdk/connectivity/src/bt_le_adapter/android/calestate.h [new file with mode: 0644]
resource/csdk/connectivity/src/bt_le_adapter/android/caleutils.c
resource/csdk/connectivity/src/bt_le_adapter/android/caleutils.h
resource/csdk/connectivity/src/bt_le_adapter/android/org_iotivity_ca_CaLeClientInterface.h
resource/csdk/connectivity/src/bt_le_adapter/android/org_iotivity_ca_CaLeServerInterface.h
resource/csdk/connectivity/src/bt_le_adapter/caleadapter.c [changed mode: 0644->0755]
resource/csdk/connectivity/src/bt_le_adapter/ios/SConscript [new file with mode: 0755]
resource/csdk/connectivity/src/bt_le_adapter/ios/caleclient.h [new file with mode: 0644]
resource/csdk/connectivity/src/bt_le_adapter/ios/caleclient.m [new file with mode: 0644]
resource/csdk/connectivity/src/bt_le_adapter/ios/calenwmonitor.h [new file with mode: 0644]
resource/csdk/connectivity/src/bt_le_adapter/ios/calenwmonitor.m [new file with mode: 0644]
resource/csdk/connectivity/src/bt_le_adapter/ios/caleserver.h [new file with mode: 0644]
resource/csdk/connectivity/src/bt_le_adapter/ios/caleserver.m [new file with mode: 0644]
resource/csdk/connectivity/src/bt_le_adapter/ios/caleutils.h [new file with mode: 0644]
resource/csdk/connectivity/src/bt_le_adapter/linux/caleinterface.c
resource/csdk/connectivity/src/bt_le_adapter/linux/central.c
resource/csdk/connectivity/src/bt_le_adapter/linux/characteristic.c
resource/csdk/connectivity/src/bt_le_adapter/linux/client.c
resource/csdk/connectivity/src/bt_le_adapter/linux/context.h
resource/csdk/connectivity/src/bt_le_adapter/linux/peripheral.c
resource/csdk/connectivity/src/bt_le_adapter/linux/peripheral.h
resource/csdk/connectivity/src/bt_le_adapter/linux/recv.c
resource/csdk/connectivity/src/bt_le_adapter/linux/utils.c
resource/csdk/connectivity/src/bt_le_adapter/tizen/SConscript
resource/csdk/connectivity/src/bt_le_adapter/tizen/caleclient.c
resource/csdk/connectivity/src/bt_le_adapter/tizen/caleclient.h
resource/csdk/connectivity/src/bt_le_adapter/tizen/calenwmonitor.c
resource/csdk/connectivity/src/bt_le_adapter/tizen/calenwmonitor_vd.c [new file with mode: 0644]
resource/csdk/connectivity/src/bt_le_adapter/tizen/caleserver.c
resource/csdk/connectivity/src/bt_le_adapter/tizen/caleserver.h
resource/csdk/connectivity/src/bt_le_adapter/tizen/caleserver_mcd.c [new file with mode: 0644]
resource/csdk/connectivity/src/bt_le_adapter/tizen/caleserver_vd.c [new file with mode: 0755]
resource/csdk/connectivity/src/cablockwisetransfer.c
resource/csdk/connectivity/src/caconnectivitymanager.c
resource/csdk/connectivity/src/cainterfacecontroller.c [changed mode: 0644->0755]
resource/csdk/connectivity/src/camessagehandler.c [changed mode: 0644->0755]
resource/csdk/connectivity/src/canetworkconfigurator.c
resource/csdk/connectivity/src/caprotocolmessage.c [changed mode: 0644->0755]
resource/csdk/connectivity/src/caqueueingthread.c
resource/csdk/connectivity/src/caretransmission.c
resource/csdk/connectivity/src/ip_adapter/SConscript
resource/csdk/connectivity/src/ip_adapter/android/caifaddrs.c
resource/csdk/connectivity/src/ip_adapter/android/caifaddrs.h
resource/csdk/connectivity/src/ip_adapter/caipadapter.c
resource/csdk/connectivity/src/ip_adapter/caipserver.c
resource/csdk/connectivity/src/ip_adapter/ios/caipnwmonitor.m [new file with mode: 0644]
resource/csdk/connectivity/src/ip_adapter/linux/caipnwmonitor.c
resource/csdk/connectivity/src/ip_adapter/tizen/caipnwmonitor.c
resource/csdk/connectivity/src/nfc_adapter/android/canfcserver.c
resource/csdk/connectivity/src/nfc_adapter/canfcadapter.c
resource/csdk/connectivity/src/ra_adapter/caraadapter.c
resource/csdk/connectivity/src/tcp_adapter/SConscript
resource/csdk/connectivity/src/tcp_adapter/arduino/catcpserver_eth.cpp
resource/csdk/connectivity/src/tcp_adapter/catcpadapter.c [changed mode: 0755->0644]
resource/csdk/connectivity/src/tcp_adapter/catcpserver.c
resource/csdk/connectivity/test/SConscript
resource/csdk/connectivity/test/ca_api_unittest.cpp
resource/csdk/connectivity/test/cablocktransfertest.cpp
resource/csdk/connectivity/test/octhread_tests.cpp [moved from resource/csdk/connectivity/test/camutex_tests.cpp with 82% similarity]
resource/csdk/connectivity/test/ssladapter_test.cpp
resource/csdk/connectivity/util/SConscript
resource/csdk/connectivity/util/inc/caconnectionmanager.h [new file with mode: 0644]
resource/csdk/connectivity/util/inc/camanagerleinterface.h
resource/csdk/connectivity/util/src/camanager/bt_le_manager/android/caleautoconnector.c [moved from resource/csdk/connectivity/util/src/camanager/android/caleautoconnector.c with 82% similarity]
resource/csdk/connectivity/util/src/camanager/bt_le_manager/android/caleautoconnector.h [moved from resource/csdk/connectivity/util/src/camanager/android/caleautoconnector.h with 100% similarity]
resource/csdk/connectivity/util/src/camanager/bt_le_manager/android/caleconnectionmanager.c [moved from resource/csdk/connectivity/util/src/camanager/android/caleconnectionmanager.c with 95% similarity]
resource/csdk/connectivity/util/src/camanager/bt_le_manager/android/camanagerdevice.c [moved from resource/csdk/connectivity/util/src/camanager/android/camanagerdevice.c with 85% similarity]
resource/csdk/connectivity/util/src/camanager/bt_le_manager/android/camanagerdevice.h [moved from resource/csdk/connectivity/util/src/camanager/android/camanagerdevice.h with 99% similarity]
resource/csdk/connectivity/util/src/camanager/bt_le_manager/android/camanagerleutil.c [moved from resource/csdk/connectivity/util/src/camanager/android/camanagerleutil.c with 97% similarity]
resource/csdk/connectivity/util/src/camanager/bt_le_manager/android/camanagerleutil.h [moved from resource/csdk/connectivity/util/src/camanager/android/camanagerleutil.h with 100% similarity]
resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/caleautoconnector.h [new file with mode: 0755]
resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/caleautoconnector.m [new file with mode: 0755]
resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/caleconnectionmanager.m [new file with mode: 0755]
resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/camanagerdevice.h [new file with mode: 0755]
resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/camanagerdevice.m [new file with mode: 0755]
resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/camanagerleutil.h [new file with mode: 0755]
resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/camanagerleutil.m [new file with mode: 0755]
resource/csdk/connectivity/util/src/camanager/bt_le_manager/tizen/caleconnectionmanager.c [moved from resource/csdk/connectivity/util/src/camanager/tizen/caleconnectionmanager.c with 54% similarity]
resource/csdk/connectivity/util/src/camanager/caconnectionmanager.c [new file with mode: 0644]
resource/csdk/connectivity/util/src/camanager/camanagerutil.c [new file with mode: 0644]
resource/csdk/connectivity/util/src/camanager/camanagerutil.h [new file with mode: 0644]
resource/csdk/connectivity/util/src/camanager/camessagearbiter.c [new file with mode: 0644]
resource/csdk/connectivity/util/src/camanager/camessagearbiter.h [new file with mode: 0644]
resource/csdk/connectivity/util/src/camanager/capolicymanager.c [new file with mode: 0644]
resource/csdk/connectivity/util/src/camanager/capolicymanager.h [new file with mode: 0644]
resource/csdk/connectivity/util/src/cautilinterface.c
resource/csdk/logger/SConscript
resource/csdk/logger/include/logger.h
resource/csdk/logger/include/tizenrt_logger.h [new file with mode: 0644]
resource/csdk/logger/include/trace.h [new file with mode: 0755]
resource/csdk/logger/src/logger.c
resource/csdk/logger/src/trace.c [new file with mode: 0755]
resource/csdk/octbstack_product.def
resource/csdk/octbstack_product_secured.def
resource/csdk/resource-directory/SConscript
resource/csdk/resource-directory/include/rd_client.h
resource/csdk/resource-directory/samples/rd_publishingClient.cpp
resource/csdk/resource-directory/src/RDClient.cpp
resource/csdk/resource-directory/src/rd_client.c
resource/csdk/resource-directory/src/rd_server.c
resource/csdk/resource-directory/unittests/rdtests.cpp
resource/csdk/routing/src/routingmanager.c
resource/csdk/routing/src/routingutility.c
resource/csdk/security/SConscript
resource/csdk/security/include/internal/aclresource.h
resource/csdk/security/include/internal/credresource.h
resource/csdk/security/include/internal/crlresource.h
resource/csdk/security/include/internal/doxmresource.h
resource/csdk/security/include/internal/policyengine.h
resource/csdk/security/include/internal/psinterface.h
resource/csdk/security/include/internal/psiutils.h [new file with mode: 0644]
resource/csdk/security/include/internal/pstatresource.h
resource/csdk/security/include/internal/secureresourcemanager.h
resource/csdk/security/include/internal/security_internals.h
resource/csdk/security/include/internal/srmresourcestrings.h
resource/csdk/security/include/internal/svcresource.h [deleted file]
resource/csdk/security/include/oxmverifycommon.h [new file with mode: 0644]
resource/csdk/security/include/pinoxmcommon.h
resource/csdk/security/include/pkix_interface.h
resource/csdk/security/include/securevirtualresourcetypes.h
resource/csdk/security/include/srmutility.h
resource/csdk/security/provisioning/SConscript
resource/csdk/security/provisioning/include/internal/multipleownershiptransfermanager.h
resource/csdk/security/provisioning/include/internal/otmcontextlist.h
resource/csdk/security/provisioning/include/internal/ownershiptransfermanager.h
resource/csdk/security/provisioning/include/internal/provisioningdatabasemanager.h
resource/csdk/security/provisioning/include/internal/secureresourceprovider.h
resource/csdk/security/provisioning/include/ocprovisioningmanager.h
resource/csdk/security/provisioning/include/oxm/oxmjustworks.h
resource/csdk/security/provisioning/include/oxm/oxmmanufacturercert.h
resource/csdk/security/provisioning/include/pmtypes.h
resource/csdk/security/provisioning/include/pmutility.h
resource/csdk/security/provisioning/sample/SConscript
resource/csdk/security/provisioning/sample/cloud/cloudAuth.c
resource/csdk/security/provisioning/sample/cloud/cloudCommon.c
resource/csdk/security/provisioning/sample/cloud/cloudDiscovery.c
resource/csdk/security/provisioning/sample/cloud/cloudWrapper.c
resource/csdk/security/provisioning/sample/hw_emul/hw_interface.c [new file with mode: 0644]
resource/csdk/security/provisioning/sample/hw_emul/hw_interface.h [new file with mode: 0644]
resource/csdk/security/provisioning/sample/hw_emul/ss_emul.c [new file with mode: 0644]
resource/csdk/security/provisioning/sample/hw_emul/ss_emul.h [new file with mode: 0644]
resource/csdk/security/provisioning/sample/oic_svr_db_client.dat
resource/csdk/security/provisioning/sample/oic_svr_db_randompin_with_empty_deviceid.dat
resource/csdk/security/provisioning/sample/oic_svr_db_randompin_with_empty_deviceid.json
resource/csdk/security/provisioning/sample/oic_svr_db_server_justworks.dat
resource/csdk/security/provisioning/sample/oic_svr_db_server_justworks.json
resource/csdk/security/provisioning/sample/oic_svr_db_server_justworks_default.dat [new file with mode: 0644]
resource/csdk/security/provisioning/sample/oic_svr_db_server_justworks_protectedDB_plain.dat [new file with mode: 0644]
resource/csdk/security/provisioning/sample/oic_svr_db_server_mvjustworks.dat [new file with mode: 0644]
resource/csdk/security/provisioning/sample/oic_svr_db_server_mvjustworks.json [new file with mode: 0644]
resource/csdk/security/provisioning/sample/oic_svr_db_server_preconfpin.dat [new file with mode: 0644]
resource/csdk/security/provisioning/sample/oic_svr_db_server_preconfpin.json [new file with mode: 0644]
resource/csdk/security/provisioning/sample/oic_svr_db_server_randompin.dat
resource/csdk/security/provisioning/sample/oic_svr_db_server_randompin.json
resource/csdk/security/provisioning/sample/provisioningclient.c
resource/csdk/security/provisioning/sample/rootca.crt
resource/csdk/security/provisioning/sample/sampleserver_justworks.cpp
resource/csdk/security/provisioning/sample/sampleserver_justworks_protectedDB.cpp [new file with mode: 0644]
resource/csdk/security/provisioning/sample/sampleserver_mfg.cpp
resource/csdk/security/provisioning/sample/sampleserver_mvjustworks.cpp [new file with mode: 0644]
resource/csdk/security/provisioning/sample/sampleserver_preconfpin.cpp [new file with mode: 0644]
resource/csdk/security/provisioning/sample/sampleserver_randompin.cpp
resource/csdk/security/provisioning/sample/subownerclient.c
resource/csdk/security/provisioning/src/cloud/aclid.c
resource/csdk/security/provisioning/src/cloud/csr.c
resource/csdk/security/provisioning/src/credentialgenerator.c
resource/csdk/security/provisioning/src/multipleownershiptransfermanager.c
resource/csdk/security/provisioning/src/ocprovisioningmanager.c
resource/csdk/security/provisioning/src/otmcontextlist.c
resource/csdk/security/provisioning/src/ownershiptransfermanager.c
resource/csdk/security/provisioning/src/oxmjustworks.c
resource/csdk/security/provisioning/src/oxmmanufacturercert.c
resource/csdk/security/provisioning/src/oxmpreconfpin.c
resource/csdk/security/provisioning/src/oxmrandompin.c
resource/csdk/security/provisioning/src/pmutility.c
resource/csdk/security/provisioning/src/provisioningdatabasemanager.c
resource/csdk/security/provisioning/src/secureresourceprovider.c
resource/csdk/security/provisioning/unittest/SConscript
resource/csdk/security/provisioning/unittest/otmunittest.cpp
resource/csdk/security/provisioning/unittest/sampleserver1.cpp
resource/csdk/security/provisioning/unittest/sampleserver2.cpp
resource/csdk/security/provisioning/unittest/secureresourceprovider.cpp
resource/csdk/security/src/aclresource.c
resource/csdk/security/src/credresource.c
resource/csdk/security/src/crlresource.c
resource/csdk/security/src/directpairing.c
resource/csdk/security/src/doxmresource.c
resource/csdk/security/src/dpairingresource.c
resource/csdk/security/src/oxmpincommon.c
resource/csdk/security/src/oxmverifycommon.c [new file with mode: 0644]
resource/csdk/security/src/pbkdf2.c
resource/csdk/security/src/pconfresource.c
resource/csdk/security/src/pkix_interface.c
resource/csdk/security/src/policyengine.c
resource/csdk/security/src/psinterface.c
resource/csdk/security/src/psiutils.c [new file with mode: 0755]
resource/csdk/security/src/pstatresource.c
resource/csdk/security/src/resourcemanager.c
resource/csdk/security/src/secureresourcemanager.c
resource/csdk/security/src/srmresourcestrings.c
resource/csdk/security/src/srmutility.c
resource/csdk/security/src/svcresource.c [deleted file]
resource/csdk/security/src/verresource.c
resource/csdk/security/tool/SConscript
resource/csdk/security/tool/json2cbor.c
resource/csdk/security/tool/svrdbeditor_src/svrdbeditor.c [new file with mode: 0644]
resource/csdk/security/tool/svrdbeditor_src/svrdbeditoracl.c [new file with mode: 0644]
resource/csdk/security/tool/svrdbeditor_src/svrdbeditoracl.h [new file with mode: 0644]
resource/csdk/security/tool/svrdbeditor_src/svrdbeditorcommon.c [new file with mode: 0644]
resource/csdk/security/tool/svrdbeditor_src/svrdbeditorcommon.h [new file with mode: 0644]
resource/csdk/security/tool/svrdbeditor_src/svrdbeditorcred.c [new file with mode: 0644]
resource/csdk/security/tool/svrdbeditor_src/svrdbeditorcred.h [new file with mode: 0644]
resource/csdk/security/tool/svrdbeditor_src/svrdbeditordoxm.c [new file with mode: 0644]
resource/csdk/security/tool/svrdbeditor_src/svrdbeditordoxm.h [new file with mode: 0644]
resource/csdk/security/tool/svrdbeditor_src/svrdbeditorpstat.c [new file with mode: 0644]
resource/csdk/security/tool/svrdbeditor_src/svrdbeditorpstat.h [new file with mode: 0644]
resource/csdk/security/unittest/SConscript
resource/csdk/security/unittest/aclresourcetest.cpp
resource/csdk/security/unittest/credentialresource.cpp
resource/csdk/security/unittest/crlresourcetest.cpp
resource/csdk/security/unittest/doxmresource.cpp
resource/csdk/security/unittest/psinterface.cpp [new file with mode: 0644]
resource/csdk/security/unittest/securityresourcemanager.cpp
resource/csdk/security/unittest/srmtestcommon.cpp
resource/csdk/security/unittest/srmutility.cpp
resource/csdk/security/unittest/svcresourcetest.cpp [deleted file]
resource/csdk/stack/include/internal/occlientcb.h
resource/csdk/stack/include/internal/ocresource.h
resource/csdk/stack/include/internal/ocstackinternal.h
resource/csdk/stack/include/internal/oickeepaliveinternal.h [moved from resource/csdk/stack/include/internal/oickeepalive.h with 64% similarity]
resource/csdk/stack/include/ocpayload.h
resource/csdk/stack/include/ocstack.h
resource/csdk/stack/include/ocstackconfig.h
resource/csdk/stack/include/octypes.h [changed mode: 0755->0644]
resource/csdk/stack/include/oickeepalive.h [new file with mode: 0644]
resource/csdk/stack/include/payload_logging.h
resource/csdk/stack/samples/linux/SimpleClientServer/SConscript
resource/csdk/stack/samples/linux/SimpleClientServer/occlient.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/occlientbasicops.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/occlientcoll.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/occlientslow.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/ocremoteaccessclient.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/ocserver.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/ocservercoll.cpp
resource/csdk/stack/samples/linux/SimpleClientServer/ocserverslow.cpp
resource/csdk/stack/samples/linux/secure/SConscript
resource/csdk/stack/samples/linux/secure/occlientbasicops.cpp
resource/csdk/stack/samples/linux/secure/occlientdirectpairing.cpp
resource/csdk/stack/samples/linux/secure/ocserverbasicops.cpp
resource/csdk/stack/samples/linux/secure/oic_svr_db_client_directpairing.dat
resource/csdk/stack/samples/linux/secure/oic_svr_db_client_directpairing.json
resource/csdk/stack/samples/linux/secure/oic_svr_db_server.dat
resource/csdk/stack/samples/linux/secure/oic_svr_db_server.json
resource/csdk/stack/samples/linux/secure/oic_svr_db_server_justworks.dat
resource/csdk/stack/samples/linux/secure/oic_svr_db_server_justworks.json
resource/csdk/stack/samples/tizen/SimpleClientServer/SConscript
resource/csdk/stack/samples/tizen/SimpleClientServer/occlient.cpp
resource/csdk/stack/samples/tizen/SimpleClientServer/occlient.h
resource/csdk/stack/samples/tizen/SimpleClientServer/ocserver.cpp
resource/csdk/stack/samples/tizen/SimpleClientServer/oic_svr_db_client.dat [new file with mode: 0644]
resource/csdk/stack/samples/tizen/SimpleClientServer/oic_svr_db_client.json [new file with mode: 0644]
resource/csdk/stack/samples/tizen/SimpleClientServer/oic_svr_db_server.dat [new file with mode: 0644]
resource/csdk/stack/samples/tizen/SimpleClientServer/oic_svr_db_server.json [new file with mode: 0644]
resource/csdk/stack/samples/tizen/SimpleClientServer/scons/SConscript
resource/csdk/stack/samples/tizen/build/gbsbuild.sh [changed mode: 0644->0755]
resource/csdk/stack/samples/tizen/build/packaging/com.oic.ri.spec
resource/csdk/stack/samples/tizen/build/scons/SConscript
resource/csdk/stack/src/occlientcb.c [changed mode: 0644->0755]
resource/csdk/stack/src/occollection.c
resource/csdk/stack/src/ocobserve.c
resource/csdk/stack/src/ocpayload.c [changed mode: 0644->0755]
resource/csdk/stack/src/ocpayloadconvert.c
resource/csdk/stack/src/ocpayloadparse.c
resource/csdk/stack/src/ocresource.c
resource/csdk/stack/src/ocserverrequest.c
resource/csdk/stack/src/ocstack.c
resource/csdk/stack/src/oicgroup.c
resource/csdk/stack/src/oickeepalive.c
resource/csdk/stack/test/linux/SConscript
resource/csdk/stack/test/linux/occlient.c
resource/csdk/stack/test/stacktests.cpp
resource/examples/SConscript
resource/examples/directpairingclient.cpp
resource/examples/oic_svr_db_client_directpairing.dat
resource/examples/oic_svr_db_client_directpairing.json
resource/examples/oic_svr_db_server.dat
resource/examples/oic_svr_db_server.json
resource/examples/rdclient.cpp
resource/examples/simpleclient.cpp
resource/examples/simpleserver.cpp
resource/include/CAManager.h
resource/include/IClientWrapper.h
resource/include/IServerWrapper.h
resource/include/InProcClientWrapper.h
resource/include/InProcServerWrapper.h
resource/include/OCApi.h
resource/include/OCCloudProvisioning.hpp
resource/include/OCPlatform.h
resource/include/OCPlatform_impl.h
resource/include/OCProvisioningManager.hpp
resource/include/OCRepresentation.h
resource/include/OCResource.h
resource/include/OCSerialization.h
resource/include/OutOfProcClientWrapper.h
resource/include/OutOfProcServerWrapper.h
resource/include/ResourceInitException.h
resource/include/StringConstants.h
resource/provisioning/SConscript
resource/provisioning/examples/SConscript
resource/provisioning/examples/cloudClient.cpp
resource/provisioning/examples/cloudWrapper.cpp
resource/provisioning/examples/oic_svr_db_subowner_client.dat [new file with mode: 0644]
resource/provisioning/examples/oic_svr_db_subowner_client.json [new file with mode: 0644]
resource/provisioning/examples/provisioningclient.cpp
resource/provisioning/examples/subownerclient.cpp [new file with mode: 0644]
resource/provisioning/src/OCProvisioningManager.cpp
resource/provisioning/unittests/OCProvisioningTest.cpp [changed mode: 0755->0644]
resource/provisioning/unittests/SConscript [changed mode: 0755->0644]
resource/src/CAManager.cpp
resource/src/InProcClientWrapper.cpp
resource/src/InProcServerWrapper.cpp
resource/src/OCException.cpp
resource/src/OCPlatform.cpp
resource/src/OCPlatform_impl.cpp [changed mode: 0644->0755]
resource/src/OCRepresentation.cpp
resource/src/OCResource.cpp
resource/src/SConscript
resource/unittests/OCExceptionTest.cpp
resource/unittests/OCRepresentationTest.cpp
service/SConscript
service/coap-http-proxy/include/CoapHttpMap.h
service/coap-http-proxy/src/CoapHttpHandler.c
service/coap-http-proxy/unittests/CoAPHttpUnitTest.cpp
service/coap-http-proxy/unittests/SConscript
service/easy-setup/enrollee/SConscript
service/easy-setup/enrollee/inc/ESEnrolleeCommon.h
service/easy-setup/enrollee/inc/easysetup.h
service/easy-setup/enrollee/inc/samsung/sc_easysetup.h [new file with mode: 0755]
service/easy-setup/enrollee/src/easysetup.c
service/easy-setup/enrollee/src/resourcehandler.c
service/easy-setup/enrollee/src/resourcehandler.h
service/easy-setup/enrollee/src/samsung/sc_easysetup.c [new file with mode: 0755]
service/easy-setup/enrollee/unittests/ESEnrolleeTest.cpp
service/easy-setup/enrollee/unittests/ESMediatorSimulator.h
service/easy-setup/inc/escommon.h
service/easy-setup/mediator/richsdk/SConscript [changed mode: 0644->0755]
service/easy-setup/mediator/richsdk/android/EasySetupCore/src/main/java/org/iotivity/service/easysetup/mediator/CloudProp.java
service/easy-setup/mediator/richsdk/android/EasySetupCore/src/main/java/org/iotivity/service/easysetup/mediator/ESConstants.java
service/easy-setup/mediator/richsdk/android/EasySetupCore/src/main/java/org/iotivity/service/easysetup/mediator/EasySetup.java
service/easy-setup/mediator/richsdk/android/EasySetupCore/src/main/java/org/iotivity/service/easysetup/mediator/EnrolleeConf.java
service/easy-setup/mediator/richsdk/android/EasySetupCore/src/main/java/org/iotivity/service/easysetup/mediator/enums/ESErrorCode.java
service/easy-setup/mediator/richsdk/android/EasySetupCore/src/main/java/org/iotivity/service/easysetup/mediator/enums/OAUTH_TOKENTYPE.java [new file with mode: 0755]
service/easy-setup/mediator/richsdk/android/EasySetupCore/src/main/java/org/iotivity/service/easysetup/mediator/samsung/SCDeviceProp.java [new file with mode: 0755]
service/easy-setup/mediator/richsdk/android/EasySetupCore/src/main/java/org/iotivity/service/easysetup/mediator/samsung/SCEnrolleeConf.java [new file with mode: 0755]
service/easy-setup/mediator/richsdk/android/EasySetupCore/src/main/jni/Application.mk
service/easy-setup/mediator/richsdk/android/EasySetupCore/src/main/jni/JniEasySetup.cpp
service/easy-setup/mediator/richsdk/android/EasySetupCore/src/main/jni/JniEsListenerManager.h
service/easy-setup/mediator/richsdk/android/EasySetupCore/src/main/jni/JniGetConfigurationStatusListener.cpp
service/easy-setup/mediator/richsdk/inc/ESRichCommon.h
service/easy-setup/mediator/richsdk/inc/ESSCCommon.h [new file with mode: 0755]
service/easy-setup/mediator/richsdk/inc/EasySetup.hpp
service/easy-setup/mediator/richsdk/inc/RemoteEnrollee.h
service/easy-setup/mediator/richsdk/src/CloudResource.cpp
service/easy-setup/mediator/richsdk/src/CloudResource.h [changed mode: 0644->0755]
service/easy-setup/mediator/richsdk/src/EasySetup.cpp
service/easy-setup/mediator/richsdk/src/EnrolleeResource.cpp
service/easy-setup/mediator/richsdk/src/EnrolleeResource.h [changed mode: 0644->0755]
service/easy-setup/mediator/richsdk/src/EnrolleeSecurity.cpp
service/easy-setup/mediator/richsdk/src/EnrolleeSecurity.h
service/easy-setup/mediator/richsdk/src/RemoteEnrollee.cpp
service/easy-setup/mediator/richsdk/unittests/ESEnrolleeSimulator.h
service/easy-setup/mediator/richsdk/unittests/ESMediatorTest.cpp
service/easy-setup/sampleapp/enrollee/linux-samsung/SConscript [new file with mode: 0755]
service/easy-setup/sampleapp/enrollee/linux-samsung/oic_svr_db_server.dat [new file with mode: 0644]
service/easy-setup/sampleapp/enrollee/linux-samsung/sc_enrollee.c [new file with mode: 0755]
service/easy-setup/sampleapp/enrollee/linux/SConscript
service/easy-setup/sampleapp/enrollee/linux/easysetup_x.c
service/easy-setup/sampleapp/enrollee/linux/enrolleewifi.c
service/easy-setup/sampleapp/enrollee/linux/oic_svr_db_server.dat
service/easy-setup/sampleapp/enrollee/linux/oic_svr_db_server_MOT.dat [new file with mode: 0644]
service/easy-setup/sampleapp/enrollee/tizen-sdb/EnrolleeSample/SConscript
service/easy-setup/sampleapp/enrollee/tizen-sdb/EnrolleeSample/build/tizen/gbsbuild.sh [changed mode: 0644->0755]
service/easy-setup/sampleapp/enrollee/tizen-sdb/EnrolleeSample/enrolleewifi.cpp
service/easy-setup/sampleapp/enrollee/tizen-sdb/EnrolleeSample/scons/SConscript
service/easy-setup/sampleapp/mediator/android-samsung/.gitignore [new file with mode: 0644]
service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/EasySetup.iml [new file with mode: 0755]
service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/EasySetupGradle.iml [new file with mode: 0644]
service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/app.iml [new file with mode: 0644]
service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/build.gradle [new file with mode: 0644]
service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/proguard-rules.pro [new file with mode: 0644]
service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/AndroidManifest.xml [new file with mode: 0644]
service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/assets/oic_svr_db_client.dat [new file with mode: 0644]
service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/assets/oic_svr_db_client.json [new file with mode: 0644]
service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/java/org/iotivity/service/easysetup/EasysetupActivity.java [new file with mode: 0755]
service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/java/org/iotivity/service/easysetup/LoginActivity.java [new file with mode: 0644]
service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/drawable-hdpi/background.png [new file with mode: 0644]
service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/drawable-hdpi/cancel.png [new file with mode: 0644]
service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/drawable-hdpi/ic_launcher.png [new file with mode: 0644]
service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/drawable-hdpi/icon.png [new file with mode: 0644]
service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/layout/activity_login.xml [new file with mode: 0644]
service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/layout/easysetup_main.xml [new file with mode: 0755]
service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/menu/main.xml [new file with mode: 0755]
service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/values/arrays.xml [new file with mode: 0644]
service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/values/dimens.xml [new file with mode: 0644]
service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/values/strings.xml [new file with mode: 0644]
service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/values/styles.xml [new file with mode: 0644]
service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/build.gradle [new file with mode: 0755]
service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/gradle.properties [new file with mode: 0644]
service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/settings.gradle [new file with mode: 0755]
service/easy-setup/sampleapp/mediator/android-samsung/SConscript [new file with mode: 0644]
service/easy-setup/sampleapp/mediator/android/EasySetup/app/src/main/assets/oic_svr_db_client.dat
service/easy-setup/sampleapp/mediator/android/EasySetup/app/src/main/assets/oic_svr_db_client.json
service/easy-setup/sampleapp/mediator/android/EasySetup/app/src/main/java/org/iotivity/service/easysetup/EasysetupActivity.java
service/easy-setup/sampleapp/mediator/linux-samsung/richsdk_sample/SConscript [new file with mode: 0755]
service/easy-setup/sampleapp/mediator/linux-samsung/richsdk_sample/mediator_sc.cpp [new file with mode: 0755]
service/easy-setup/sampleapp/mediator/linux-samsung/richsdk_sample/oic_svr_db_client.dat [new file with mode: 0755]
service/easy-setup/sampleapp/mediator/linux/richsdk_sample/SConscript
service/easy-setup/sampleapp/mediator/linux/richsdk_sample/mediator.cpp [new file with mode: 0755]
service/easy-setup/sampleapp/mediator/linux/richsdk_sample/oic_svr_db_subclient.dat [new file with mode: 0644]
service/easy-setup/sampleapp/mediator/linux/richsdk_sample/submediator.cpp [moved from service/easy-setup/sampleapp/mediator/linux/richsdk_sample/mediator_cpp.cpp with 78% similarity]
service/notification/SConscript
service/notification/android/SConscript
service/notification/android/notification-service/src/main/java/org/iotivity/service/ns/common/MediaContents.java
service/notification/android/notification-service/src/main/java/org/iotivity/service/ns/common/Message.java
service/notification/android/notification-service/src/main/java/org/iotivity/service/ns/common/NSErrorCode.java
service/notification/android/notification-service/src/main/java/org/iotivity/service/ns/common/NSException.java
service/notification/android/notification-service/src/main/java/org/iotivity/service/ns/common/SyncInfo.java
service/notification/android/notification-service/src/main/java/org/iotivity/service/ns/common/Topic.java
service/notification/android/notification-service/src/main/java/org/iotivity/service/ns/common/TopicsList.java
service/notification/android/notification-service/src/main/java/org/iotivity/service/ns/consumer/ConsumerService.java
service/notification/android/notification-service/src/main/java/org/iotivity/service/ns/consumer/Provider.java
service/notification/android/notification-service/src/main/java/org/iotivity/service/ns/provider/Consumer.java [changed mode: 0644->0755]
service/notification/android/notification-service/src/main/java/org/iotivity/service/ns/provider/ProviderService.java [changed mode: 0644->0755]
service/notification/android/notification-service/src/main/jni/Android.mk
service/notification/android/notification-service/src/main/jni/common/JniNotificationCommon.cpp
service/notification/android/notification-service/src/main/jni/common/JniNotificationCommon.h
service/notification/android/notification-service/src/main/jni/common/JniSharedObjectHolder.h [new file with mode: 0755]
service/notification/android/notification-service/src/main/jni/consumer/JniNotificationConsumer.cpp
service/notification/android/notification-service/src/main/jni/consumer/JniNotificationConsumer.h
service/notification/android/notification-service/src/main/jni/provider/JniNotificationProvider.cpp
service/notification/android/notification-service/src/main/jni/provider/JniNotificationProvider.h [changed mode: 0644->0755]
service/notification/cpp-wrapper/common/NSException.h [new file with mode: 0755]
service/notification/cpp-wrapper/common/NSTopicsList.cpp
service/notification/cpp-wrapper/common/NSTopicsList.h
service/notification/cpp-wrapper/consumer/SConscript
service/notification/cpp-wrapper/consumer/inc/NSAcceptedProviders.h [new file with mode: 0755]
service/notification/cpp-wrapper/consumer/inc/NSConsumerService.h
service/notification/cpp-wrapper/consumer/inc/NSProvider.h
service/notification/cpp-wrapper/consumer/src/NSAcceptedProviders.cpp [new file with mode: 0755]
service/notification/cpp-wrapper/consumer/src/NSConsumerService.cpp
service/notification/cpp-wrapper/consumer/src/NSProvider.cpp
service/notification/cpp-wrapper/examples/linux/SConscript
service/notification/cpp-wrapper/examples/linux/notificationserviceconsumer.cpp
service/notification/cpp-wrapper/examples/linux/notificationserviceprovider.cpp
service/notification/cpp-wrapper/provider/SConscript
service/notification/cpp-wrapper/provider/inc/NSAcceptedConsumers.h [new file with mode: 0755]
service/notification/cpp-wrapper/provider/inc/NSConsumer.h
service/notification/cpp-wrapper/provider/inc/NSProviderService.h
service/notification/cpp-wrapper/provider/src/NSAcceptedConsumers.cpp [new file with mode: 0755]
service/notification/cpp-wrapper/provider/src/NSConsumer.cpp
service/notification/cpp-wrapper/provider/src/NSProviderService.cpp
service/notification/cpp-wrapper/unittest/NSConsumerServiceSimulator.h
service/notification/cpp-wrapper/unittest/NSConsumerServiceTest.cpp
service/notification/cpp-wrapper/unittest/NSProviderServiceSimulator.h
service/notification/cpp-wrapper/unittest/NSProviderServiceTest.cpp
service/notification/cpp-wrapper/unittest/SConscript
service/notification/examples/android/NotiConsumerExample/SConscript
service/notification/examples/android/NotiConsumerExample/app/build.gradle
service/notification/examples/android/NotiConsumerExample/app/src/androidTest/java/org/iotivity/service/ns/sample/consumer/ExampleUnitTest.java [new file with mode: 0755]
service/notification/examples/android/NotiConsumerExample/app/src/androidTest/java/org/iotivity/service/ns/sample/consumer/ProviderSimulator.java [new file with mode: 0755]
service/notification/examples/android/NotiConsumerExample/app/src/main/AndroidManifest.xml
service/notification/examples/android/NotiConsumerExample/app/src/main/java/com/sec/noticonsumerexample/MainActivity.java [deleted file]
service/notification/examples/android/NotiConsumerExample/app/src/main/java/org/iotivity/service/ns/sample/consumer/ConsumerSample.java [moved from service/notification/examples/android/NotiConsumerExample/app/src/main/java/com/sec/noticonsumerexample/ConsumerSample.java with 52% similarity]
service/notification/examples/android/NotiConsumerExample/app/src/main/java/org/iotivity/service/ns/sample/consumer/LoginActivity.java [new file with mode: 0644]
service/notification/examples/android/NotiConsumerExample/app/src/main/java/org/iotivity/service/ns/sample/consumer/MainActivity.java [new file with mode: 0755]
service/notification/examples/android/NotiConsumerExample/app/src/main/res/layout/activity_login.xml [new file with mode: 0755]
service/notification/examples/android/NotiConsumerExample/app/src/main/res/layout/activity_main.xml
service/notification/examples/android/NotiConsumerExample/app/src/main/res/layout/dialog_auth.xml [new file with mode: 0644]
service/notification/examples/android/NotiConsumerExample/app/src/main/res/layout/dialog_entry.xml [new file with mode: 0644]
service/notification/examples/android/NotiConsumerExample/app/src/main/res/layout/dialog_mq.xml [new file with mode: 0644]
service/notification/examples/android/NotiConsumerExample/app/src/main/res/values/strings.xml
service/notification/examples/android/NotiProviderExample/SConscript
service/notification/examples/android/NotiProviderExample/app/build.gradle
service/notification/examples/android/NotiProviderExample/app/src/androidTest/java/org/iotivity/service/ns/sample/provider/ConsumerSimulator.java [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/app/src/androidTest/java/org/iotivity/service/ns/sample/provider/ExampleUnitTest.java [new file with mode: 0755]
service/notification/examples/android/NotiProviderExample/app/src/main/AndroidManifest.xml [changed mode: 0644->0755]
service/notification/examples/android/NotiProviderExample/app/src/main/java/com/sec/notiproviderexample/MainActivity.java [deleted file]
service/notification/examples/android/NotiProviderExample/app/src/main/java/com/sec/notiproviderexample/ProviderSample.java [deleted file]
service/notification/examples/android/NotiProviderExample/app/src/main/java/org/iotivity/service/ns/sample/provider/LoginActivity.java [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/app/src/main/java/org/iotivity/service/ns/sample/provider/MainActivity.java [new file with mode: 0755]
service/notification/examples/android/NotiProviderExample/app/src/main/java/org/iotivity/service/ns/sample/provider/NotiListener.java [moved from service/notification/examples/android/NotiProviderExample/app/src/main/java/com/sec/notiproviderexample/NotiListener.java with 70% similarity]
service/notification/examples/android/NotiProviderExample/app/src/main/java/org/iotivity/service/ns/sample/provider/ProviderSample.java [new file with mode: 0755]
service/notification/examples/android/NotiProviderExample/app/src/main/res/layout/activity_login.xml [new file with mode: 0755]
service/notification/examples/android/NotiProviderExample/app/src/main/res/layout/activity_main.xml [changed mode: 0644->0755]
service/notification/examples/android/NotiProviderExample/app/src/main/res/layout/dialog_auth.xml [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/app/src/main/res/layout/dialog_entry.xml [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/app/src/main/res/layout/dialog_mq.xml [new file with mode: 0644]
service/notification/examples/android/NotiProviderExample/app/src/main/res/values/strings.xml [changed mode: 0644->0755]
service/notification/examples/linux/SConscript
service/notification/examples/linux/notificationconsumer.c
service/notification/examples/linux/notificationprovider.c
service/notification/include/NSCommon.h
service/notification/include/NSConsumerInterface.h
service/notification/include/NSProviderInterface.h
service/notification/src/common/NSConstants.h
service/notification/src/common/NSStructs.h
service/notification/src/common/NSUtil.c
service/notification/src/common/NSUtil.h
service/notification/src/consumer/NSConsumerCommon.c
service/notification/src/consumer/NSConsumerCommon.h
service/notification/src/consumer/NSConsumerCommunication.c
service/notification/src/consumer/NSConsumerDiscovery.c
service/notification/src/consumer/NSConsumerInterface.c
service/notification/src/consumer/NSConsumerInternalTaskController.c
service/notification/src/consumer/NSConsumerMQPlugin.c [new file with mode: 0644]
service/notification/src/consumer/NSConsumerMQPlugin.h [new file with mode: 0644]
service/notification/src/consumer/NSConsumerMemoryCache.c
service/notification/src/consumer/NSConsumerNetworkEventListener.c
service/notification/src/consumer/NSConsumerScheduler.c
service/notification/src/provider/NSProviderCallbackResponse.c
service/notification/src/provider/NSProviderDiscovery.c
service/notification/src/provider/NSProviderInterface.c
service/notification/src/provider/NSProviderListener.c
service/notification/src/provider/NSProviderListener.h
service/notification/src/provider/NSProviderMemoryCache.c
service/notification/src/provider/NSProviderNotification.c
service/notification/src/provider/NSProviderResource.c
service/notification/src/provider/NSProviderScheduler.c
service/notification/src/provider/NSProviderSubscription.c
service/notification/src/provider/NSProviderSystem.c
service/notification/src/provider/NSProviderSystem.h
service/notification/src/provider/NSProviderTopic.c
service/notification/unittest/NSConsumerSimulator.h
service/notification/unittest/NSProviderSimulator.h
service/notification/unittest/SConscript
service/resource-container/examples/BMISensorBundle/src/BMISensor.cpp
service/resource-container/examples/BMISensorBundle/src/inputSensors/HeightSensorApp/src/HeightSensorApp.cpp
service/resource-container/examples/BMISensorBundle/src/inputSensors/WeightSensorApp/src/WeightSensorApp.cpp
service/resource-container/examples/ContainerSample.cpp
service/resource-container/examples/ContainerSampleClient.cpp
service/resource-container/examples/DiscomfortIndexSensorBundle/src/DiscomfortIndexSensor.cpp
service/resource-container/examples/DiscomfortIndexSensorBundle/src/DiscomfortIndexSensorResource.cpp
service/resource-container/examples/DiscomfortIndexSensorBundle/src/inputSensors/THSensorApp/src/ThingResourceServer.cpp
service/resource-container/examples/DiscomfortIndexSensorBundle/src/inputSensors/THSensorApp1/src/ThingResourceServer1.cpp
service/resource-container/examples/HueSampleBundle/src/HueConnector.cpp
service/resource-container/src/Configuration.cpp
service/resource-container/src/RemoteResourceUnit.cpp
service/resource-container/src/RemoteResourceUnit.h
service/resource-container/src/ResourceContainerImpl.cpp
service/resource-container/unittests/ResourceContainerTest.cpp
service/resource-encapsulation/SConscript
service/resource-encapsulation/android/service/src/main/java/org/iotivity/service/RcsByteString.java [new file with mode: 0644]
service/resource-encapsulation/android/service/src/main/java/org/iotivity/service/RcsValue.java
service/resource-encapsulation/android/service/src/main/java/org/iotivity/service/client/RcsRemoteResourceObject.java
service/resource-encapsulation/android/service/src/main/jni/JniRcsRemoteResourceObject.cpp
service/resource-encapsulation/android/service/src/main/jni/JniRcsValue.cpp
service/resource-encapsulation/android/service/src/main/jni/util/JNIEnvWrapper.h
service/resource-encapsulation/android/service/src/main/jni/util/JavaClasses.h
service/resource-encapsulation/examples/android/RESampleClientApp/app/src/main/java/org/iotivity/service/sample/client/ResourceClientActivity.java
service/resource-encapsulation/examples/linux/NestedAttributesClient.cpp
service/resource-encapsulation/examples/linux/NestedAttributesServer.cpp
service/resource-encapsulation/examples/linux/SampleResourceClient.cpp
service/resource-encapsulation/examples/linux/SampleResourceServer.cpp
service/resource-encapsulation/examples/linux/SeparateResponseServer.cpp
service/resource-encapsulation/examples/tizen/RESampleClientApp/src/reclient.cpp
service/resource-encapsulation/include/RCSRemoteResourceObject.h
service/resource-encapsulation/include/RCSResourceAttributes.h
service/resource-encapsulation/src/common/expiryTimer/unittests/ExpiryTimerTest.cpp
service/resource-encapsulation/src/common/primitiveResource/include/PrimitiveResource.h
service/resource-encapsulation/src/common/primitiveResource/include/PrimitiveResourceImpl.h
service/resource-encapsulation/src/common/primitiveResource/include/ResourceAttributesConverter.h
service/resource-encapsulation/src/common/primitiveResource/src/RCSResourceAttributes.cpp
service/resource-encapsulation/src/common/primitiveResource/unittests/PrimitiveResourceTest.cpp
service/resource-encapsulation/src/common/primitiveResource/unittests/ResourceAttributesTest.cpp
service/resource-encapsulation/src/resourceBroker/unittest/ResourceBrokerUnitTest.cpp
service/resource-encapsulation/src/resourceBroker/unittest/ResourcePresenceUnitTest.cpp
service/resource-encapsulation/src/resourceCache/include/CacheTypes.h
service/resource-encapsulation/src/resourceCache/include/DataCache.h
service/resource-encapsulation/src/resourceCache/include/ObserveCache.h
service/resource-encapsulation/src/resourceCache/src/DataCache.cpp
service/resource-encapsulation/src/resourceCache/src/ObserveCache.cpp
service/resource-encapsulation/src/resourceCache/src/ResourceCacheManager.cpp
service/resource-encapsulation/src/resourceCache/unittests/DataCacheTest.cpp
service/resource-encapsulation/src/resourceCache/unittests/ResourceCacheTest.cpp
service/resource-encapsulation/src/resourceClient/RCSDiscoveryManagerImpl.cpp
service/resource-encapsulation/src/resourceClient/RCSRemoteResourceObject.cpp
service/resource-encapsulation/unittests/ResourceClientTest.cpp
service/scene-manager/SConscript
service/simulator/ramlparser/raml/IncludeResolver.h
service/simulator/ramlparser/raml/jsonSchemaParser/JsonSchema.cpp
service/simulator/ramlparser/raml/jsonSchemaParser/JsonSchema.h
service/simulator/ramlparser/raml/jsonSchemaParser/Properties.h
service/simulator/ramlparser/raml/model/Raml.h
service/simulator/ramlparser/raml/model/Schema.h
tools/scons/URLDownload.py
tools/scons/UnpackAll.py
tools/tizen/.gbs.conf
tools/tizen/.gbs.vd.tv.tizen30.conf [new file with mode: 0755]
tools/tizen/iotivity-vd-tv-es-tizen30.spec [new file with mode: 0644]
tools/tizen/iotivity-vd-tv-tizen30.spec [new file with mode: 0644]
tools/tizen/iotivity.spec [changed mode: 0755->0644]

index fa14905..a6a0722 100644 (file)
@@ -117,7 +117,7 @@ build_common/arduino/extlibs/arduino/arduino-1.5.8
 extlibs/tinydtls/dtls-client
 extlibs/tinydtls/dtls-server
 extlibs/bluez/bluez
-extlibs/mbedtls/mbedtls
+extlibs/mbedtls/mbedtls
 extlibs/raxmpp/raxmpp
 extlibs/yaml/yaml
 
@@ -136,7 +136,7 @@ extlibs/yaml/yaml
 *.memcheck
 
 # Ignore  generated files
-*.dat
+*.dat
 
 # Ignore debian generated files
 debian/files
index 027511d..89c49b3 100644 (file)
--- a/NOTICE.md
+++ b/NOTICE.md
@@ -25,13 +25,11 @@ 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 TLS/DTLS protocol is provided by the mbedTLS package,
+which is open source software, written and copyright by ARM
+with an Apache 2.0 license.
 The original software is available from
-  http://sourceforge.net/projects/tinydtls/
+  https://github.com/ARMmbed/mbedtls
 
 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
@@ -50,3 +48,8 @@ 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/
 
+The Linked List macro(utlist.h) is provided by the uthash package,
+which is open source software, written and copyright by Troy D. Hanson
+with an BSD license.
+The original software is available from
+  https://github.com/troydhanson/uthash
index 57f531e..9b2b590 100644 (file)
@@ -31,7 +31,7 @@ message to install tinycbor)
 ('<iotivity>' is the path to 'iotivity' project. If your device is x86, arm,
 or arm64, please change 'x86_64' to the proper arch)
 
-3. To build and test IoTivity with Security enabled (required for certification) 
+3. To build and test IoTivity with Security enabled (required for certification)
 follow the instructions found in:
   <iotivity>/resource/csdk/security/README-building-and-running-secure-IoTivity-stack.txt
 
@@ -284,6 +284,16 @@ See run.bat for more example usage parameters
  * SIMULATOR=true or false (Build with simulator module)
  * Possible values for <WITH_MQ> are: PUB,SUB,BROKER (Build including Message Queue)
    -> PUB : publisher, SUB : subscriber, BROKER : MQ broker(not supported yet)
+ * LOG_LEVEL=DEBUG or INFO or WARNING or ERROR or FATAL
+   (select log level to print, LOGGING option should be true)
+   default is debug level with no private log.
+    ex) LOG_LEVEL=DEBUG : All logs including DEBUG, INFO, WARNING, ERROR, FATAL level is printed.
+                          and private log is disabled.
+        LOG_LEVEL=INFO : The logs including INFO, WARNING, ERROR, FATAL level is printed.
+                         and private log is disabled.
+        LOG_LEVEL=WARNING : The logs including WARNING, ERROR, FATAL level is printed.
+        LOG_LEVEL=ERROR : The logs including ERROR, FATAL level is printed.
+        LOG_LEVEL=FATAL : FATAL level is printed.
 
 Note:
 1) for convenience, a script (auto_build.sh) is provided to run possible build
index ac76f39..3a69fe5 100644 (file)
@@ -56,17 +56,22 @@ build_dir = env.get('BUILD_DIR')
 # Build 'resource' sub-project
 SConscript(build_dir + 'resource/SConscript')
 
-if target_os not in ['arduino','darwin','ios', 'android', 'msys_nt', 'windows']:
+if target_os not in ['arduino','darwin','ios', 'android', 'msys_nt', 'windows', 'tizenrt']:
        SConscript(build_dir + 'examples/OICMiddle/SConscript')
 
 # Build 'service' sub-project
-SConscript(build_dir + 'service/SConscript')
+if target_os not in ['tizenrt']:
+       SConscript(build_dir + 'service/SConscript')
 
 # Build "cloud" sub-project
 SConscript(build_dir + 'cloud/SConscript')
 
 # Build "plugin interface" sub-project
-SConscript(build_dir + 'plugins/SConscript')
+if target_os not in ['tizenrt']:
+       SConscript(build_dir + 'plugins/SConscript')
+
+if target_os == 'tizenrt':
+       SConscript('../apps' + '/SConscript')
 
 # Append targets information to the help information, to see help info, execute command line:
 #     $ scon [options] -h
index 895ebb6..7e79144 100644 (file)
@@ -54,14 +54,21 @@ else:
 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'):
+if ('ALL' in ANDROID_TRANSPORT) or ('BLE' in ANDROID_TRANSPORT):
+       ANDROID_API_LEVEL = '22'
+       ANDROID_VER = '5.1'
+else:
+       ANDROID_API_LEVEL = '21'
+       ANDROID_VER = '5.0.1'
+
+if not os.path.exists(android_home + '/platforms/android-' + ANDROID_API_LEVEL) 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      *
+*   Either 'Android API %s' 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"               *
+*       2. Under "Android %s (API %s)" 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  *
@@ -80,7 +87,7 @@ if not os.path.exists(android_home + '/platforms/android-21') or not os.path.exi
 *******************************************************************************
 
 ...Opening Android SDK Manager now. Once you are finished, the build will continue.
-'''
+''' % (ANDROID_API_LEVEL, ANDROID_VER, ANDROID_API_LEVEL) 
     os.system(android_home + '/tools/android')
 
 def ensure_libs(target, source, env):
@@ -92,10 +99,10 @@ jdk_env['BUILDERS']['Gradle'] = Builder(action = env.get('ANDROID_GRADLE') + ' b
 jdk_env['BUILD_DIR'] = env.get('BUILD_DIR')
 cmdBuildApi=jdk_env.Gradle(target="base/objs", source="base/src/main/java/org/iotivity/base/OcResource.java")
 
-jdk_env['BUILDERS']['Gradle'] = Builder(action = env.get('ANDROID_GRADLE') + ' build -b' + 'android/examples/build.gradle -DWITH_TRANSPORT_EDR=%s -DWITH_TRANSPORT_BLE=%s -DWITH_TRANSPORT_NFC=%s -PTARGET_ARCH=%s -PRELEASE=%s -PSECURED=%s -DSECURE=%s -PWITH_CLOUD=%s -PRD_MODE=%s -PWITH_MQ_PUB=%s -PWITH_MQ_SUB=%s -PWITH_MQ_BROKER=%s -PWITH_TCP=%s --stacktrace' %(ANDROID_TRANSPORT_EDR, ANDROID_TRANSPORT_BLE, ANDROID_TRANSPORT_NFC, ANDROID_TARGET_ARCH, ANDROID_RELEASE, ANDROID_SECURED, ANDROID_SECURED, ANDROID_CLOUD, ANDROID_RD_MODE, ANDROID_MQ_PUB, ANDROID_MQ_SUB, ANDROID_MQ_BROKER, ANDROID_TCP))
-cmdBuildExamples=jdk_env.Gradle(target="../examples/devicediscoveryclient/apk", source="../examples/devicediscoveryclient/src/main/java/org/iotivity/base/examples/DeviceDiscoveryClient.java")
+#jdk_env['BUILDERS']['Gradle'] = Builder(action = env.get('ANDROID_GRADLE') + ' build -b' + 'android/examples/build.gradle -DWITH_TRANSPORT_EDR=%s -DWITH_TRANSPORT_BLE=%s -DWITH_TRANSPORT_NFC=%s -PTARGET_ARCH=%s -PRELEASE=%s -PSECURED=%s -DSECURE=%s -PWITH_CLOUD=%s -PRD_MODE=%s -PWITH_MQ_PUB=%s -PWITH_MQ_SUB=%s -PWITH_MQ_BROKER=%s -PWITH_TCP=%s --stacktrace' %(ANDROID_TRANSPORT_EDR, ANDROID_TRANSPORT_BLE, ANDROID_TRANSPORT_NFC, ANDROID_TARGET_ARCH, ANDROID_RELEASE, ANDROID_SECURED, ANDROID_SECURED, ANDROID_CLOUD, ANDROID_RD_MODE, ANDROID_MQ_PUB, ANDROID_MQ_SUB, ANDROID_MQ_BROKER, ANDROID_TCP))
+#cmdBuildExamples=jdk_env.Gradle(target="../examples/devicediscoveryclient/apk", source="../examples/devicediscoveryclient/src/main/java/org/iotivity/base/examples/DeviceDiscoveryClient.java")
 
 # android examples require android api to be built before being invoked
-Depends(cmdBuildExamples, cmdBuildApi)
+#Depends(cmdBuildExamples, cmdBuildApi)
 
 env.AppendUnique(baseAAR = cmdBuildApi)
index e496be0..2d8cbcb 100755 (executable)
 apply plugin: 'com.android.library'\r
 \r
 android {\r
-    compileSdkVersion 21\r
+    if (WITH_TRANSPORT_BLE == "0") {\r
+        compileSdkVersion 21\r
+    }else{\r
+        compileSdkVersion 22\r
+    }\r
     buildToolsVersion "20.0.0"\r
     archivesBaseName = "iotivity-base"\r
 \r
index 59400f2..4210502 100644 (file)
@@ -3,6 +3,7 @@ TARGET_ARCH_ABI := $(APP_ABI)
 SECURED := $(SECURE)
 WITH_CLOUD := $(WITH_CLOUD)
 WITH_TCP := $(WITH_TCP)
+TCP_ADAPTER := $(WITH_TCP)
 WITH_MQ_PUB := $(WITH_MQ_PUB)
 WITH_MQ_SUB := $(WITH_MQ_SUB)
 WITH_MQ_BROKER := $(WITH_MQ_BROKER)
@@ -41,6 +42,12 @@ include $(PREBUILT_SHARED_LIBRARY)
 ifeq ($(SECURED), 1)
 include $(CLEAR_VARS)
 OIC_LIB_PATH := ../../../../out/android/$(APP_ABI)/$(APP_OPTIM)
+LOCAL_MODULE := libandroid-mbedtls
+LOCAL_SRC_FILES := $(OIC_LIB_PATH)/libmbedtls.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+OIC_LIB_PATH := ../../../../out/android/$(APP_ABI)/$(APP_OPTIM)
 LOCAL_MODULE := libandroid-ocprovision
 LOCAL_SRC_FILES := $(OIC_LIB_PATH)/libocprovision.so
 include $(PREBUILT_SHARED_LIBRARY)
@@ -72,9 +79,15 @@ ifeq ($(WITH_CLOUD), 1)
 endif
 
 ifeq ($(WITH_TCP), 1)
-    LOCAL_CPPFLAGS += -D__WITH_TLS__
+    LOCAL_CPPFLAGS += -D__WITH_TLS__ \
+                      -DWITH_TCP
 endif
 
+ifeq ($(TCP_ADAPTER), 1)
+    LOCAL_CPPFLAGS += -DTCP_ADAPTER
+endif
+
+
 MQ_FLAG = 0
 ifeq ($(WITH_MQ_PUB), 1)
 LOCAL_CFLAGS += -DWITH_MQ -DMQ_PUBLISHER
@@ -129,14 +142,17 @@ ifeq ($(SECURED), 1)
                         JniSecureUtils.cpp \
                         JniProvisionResultListner.cpp \
                         JniPinCheckListener.cpp \
-                        JniDisplayPinListener.cpp
+                        JniDisplayPinListener.cpp \
+                        JniDisplayVerifyNumListener.cpp \
+                        JniConfirmNumListener.cpp
 endif
 
 ifeq ($(WITH_CLOUD), 1)
     LOCAL_SRC_FILES +=  JniOcAccountManager.cpp
 endif
 
-ifeq ($(WITH_TCP), 1)
+ifeq ($(TCP_ADAPTER), 1)
+    LOCAL_SRC_FILES += JniKeepAliveListener.cpp
 ifeq ($(SECURED), 1)
     LOCAL_SRC_FILES +=  JniOcCloudProvisioning.cpp \
                         JniOcCloudResultListener.cpp \
@@ -154,6 +170,7 @@ LOCAL_STATIC_LIBRARIES += android_cpp11_compat
 ifeq ($(SECURED), 1)
 LOCAL_STATIC_LIBRARIES += android-ocprovision
 LOCAL_STATIC_LIBRARIES += android-ocpmapi
+LOCAL_STATIC_LIBRARIES += android-mbedtls
 endif
 LOCAL_SHARED_LIBRARIES += android-rd
 
@@ -173,6 +190,7 @@ 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)/../extlibs/cjson
 LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/../extlibs/tinycbor/tinycbor/src
+LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/../extlibs/mbedtls/mbedtls/include/
 LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/../build_common/android/compatibility
 LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/csdk/security/provisioning/include
 LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/csdk/security/provisioning/include/oxm/
index 8fdedd9..2a7861b 100644 (file)
@@ -356,6 +356,43 @@ Java_org_iotivity_ca_CaInterface_setLeScanIntervalTimeImpl(JNIEnv *env, jclass c
     CAUtilSetLEScanInterval(intervalTime, workignCount);
 }
 
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaInterface_stopLeScanImpl(JNIEnv *env, jclass clazz)
+{
+    LOGI("stopLeScan");
+    (void)env;
+    (void)clazz;
+    CAUtilStopLEScan();
+}
+
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaInterface_startLeAdvertisingImpl(JNIEnv *env, jclass clazz)
+{
+    LOGI("startLeAdvertising");
+    (void)env;
+    (void)clazz;
+    CAUtilStartLEAdvertising();
+}
+
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaInterface_stopLeAdvertisingImpl(JNIEnv *env, jclass clazz)
+{
+    LOGI("stopLeAdvertising");
+    (void)env;
+    (void)clazz;
+    CAUtilStopLEAdvertising();
+}
+
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaInterface_setBTConfigureImpl(JNIEnv *env, jclass clazz, jint flag)
+{
+    LOGI("setConfigureImpl");
+    (void)env;
+    (void)clazz;
+    CAUtilConfig_t configs = {(CATransportBTFlags_t)flag};
+    CAUtilSetBTConfigure(configs);
+}
+
 JNIEXPORT jint JNICALL Java_org_iotivity_ca_CaInterface_setCipherSuiteImpl
   (JNIEnv *env, jclass clazz, jint cipherSuite, jint adapter)
 {
@@ -370,3 +407,33 @@ JNIEXPORT jint JNICALL Java_org_iotivity_ca_CaInterface_setCipherSuiteImpl
     return ret;
 }
 
+JNIEXPORT jint JNICALL Java_org_iotivity_ca_CaInterface_disconnectTCPSessionImpl
+ (JNIEnv *env, jclass clazz, jstring address, jint port, jint transportFlags)
+{
+    LOGI("disconnectTCPSessionImpl");
+    (void)env;
+    (void)clazz;
+
+    if(!address)
+    {
+        LOGE("Java address is null");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    //convert java string to native string
+    const char* nativeAddress = (*env)->GetStringUTFChars(env, address, NULL);
+    if (!nativeAddress)
+    {
+        LOGE("Native address is null");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    CAResult_t result = CAUtilTCPDisconnectSession(nativeAddress, (int)port,
+                                            (CATransportFlags_t)transportFlags);
+    if (CA_STATUS_OK != result)
+    {
+        LOGE("disconnectTCPSessionImpl failed");
+    }
+    return result;
+}
+
index 663aef3..d13b47e 100644 (file)
@@ -136,6 +136,14 @@ extern "C" {
     JNIEXPORT jint JNICALL Java_org_iotivity_ca_CaInterface_setCipherSuiteImpl
      (JNIEnv *, jclass, jint, jint);
 
+    /*
+     * Class:     org_iotivity_ca_CaInterface
+     * Method:    disconnectTCPSessionImpl
+     * Signature: (Ljava/lang/String;II)I
+     */
+    JNIEXPORT jint JNICALL Java_org_iotivity_ca_CaInterface_disconnectTCPSessionImpl
+     (JNIEnv *, jclass, jstring, jint, jint);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/android/android_api/base/jni/JniConfirmNumListener.cpp b/android/android_api/base/jni/JniConfirmNumListener.cpp
new file mode 100644 (file)
index 0000000..402f3e1
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+* //******************************************************************
+* //
+* // Copyright 2016 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 "JniConfirmNumListener.h"
+
+JniConfirmNumListener::JniConfirmNumListener(JNIEnv *env, jobject jListener)
+{
+    m_jgListener = env->NewGlobalRef(jListener);
+}
+
+JniConfirmNumListener::~JniConfirmNumListener()
+{
+    LOGI("~JniConfirmNumListener()");
+    if (m_jgListener)
+    {
+        jint ret = JNI_ERR;
+        JNIEnv *env = GetJNIEnv(ret);
+        if (NULL == env) return;
+        env->DeleteGlobalRef(m_jgListener);
+        if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread();
+    }
+}
+
+OCStackResult JniConfirmNumListener::confirmMutualVerifNumCallback()
+{
+    jint ret = JNI_ERR;
+    JNIEnv *env = GetJNIEnv(ret);
+    if (NULL == env)
+    {
+        return OC_STACK_ERROR;
+    }
+
+    jclass clsL = env->GetObjectClass(m_jgListener);
+
+    if (!clsL)
+    {
+        if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread();
+        return OC_STACK_ERROR;
+    }
+
+    jmethodID midL = env->GetMethodID(clsL, "confirmNumListener", "()I");
+    if (!midL)
+    {
+        if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread();
+        return OC_STACK_ERROR;
+    }
+
+    OCStackResult result = (OCStackResult) env->CallIntMethod(m_jgListener, midL);
+
+    if (env->ExceptionCheck())
+    {
+        LOGE("Java exception is thrown");
+        env->ExceptionClear();
+    }
+
+    if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread();
+    return result;
+}
diff --git a/android/android_api/base/jni/JniConfirmNumListener.h b/android/android_api/base/jni/JniConfirmNumListener.h
new file mode 100644 (file)
index 0000000..13b30ec
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+* //******************************************************************
+* //
+* // Copyright 2016 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 <jni.h>
+#include "JniOcStack.h"
+#include "OCProvisioningManager.hpp"
+
+#ifndef _Included_org_iotivity_base_JniConfirmNumListener
+#define _Included_org_iotivity_base_JniConfirmNumListener
+
+class JniConfirmNumListener
+{
+    public:
+        JniConfirmNumListener(JNIEnv *env, jobject jListener);
+        ~JniConfirmNumListener();
+
+        OCStackResult confirmMutualVerifNumCallback();
+
+    private:
+        jobject m_jgListener;
+};
+#endif
diff --git a/android/android_api/base/jni/JniDisplayVerifyNumListener.cpp b/android/android_api/base/jni/JniDisplayVerifyNumListener.cpp
new file mode 100644 (file)
index 0000000..20112d9
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+* //******************************************************************
+* //
+* // Copyright 2016 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 "JniDisplayVerifyNumListener.h"
+#include "oic_malloc.h"
+
+JniDisplayVerifyNumListener::JniDisplayVerifyNumListener(JNIEnv *env, jobject jListener)
+{
+    m_jgListener = env->NewGlobalRef(jListener);
+}
+
+JniDisplayVerifyNumListener::~JniDisplayVerifyNumListener()
+{
+    LOGI("~JniDisplayVerifyNumListener()");
+    if (m_jgListener)
+    {
+        jint ret = JNI_ERR;
+        JNIEnv *env = GetJNIEnv(ret);
+        if (NULL == env) return;
+        env->DeleteGlobalRef(m_jgListener);
+        if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread();
+    }
+}
+
+OCStackResult JniDisplayVerifyNumListener::displayMutualVerifNumCallback(uint8_t verifNum[3])
+{
+    jint ret = JNI_ERR;
+    JNIEnv *env = GetJNIEnv(ret);
+    char *byteArray;
+
+    if (NULL == env)
+    {
+        return OC_STACK_ERROR;
+    }
+
+    jclass clsL = env->GetObjectClass(m_jgListener);
+
+    if (!clsL)
+    {
+        if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread();
+        return OC_STACK_ERROR;
+    }
+
+    jmethodID midL = env->GetMethodID(clsL, "displayNumListener", "(Ljava/lang/String;)I");
+    if (!midL)
+    {
+        if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread();
+        return OC_STACK_ERROR;
+    }
+
+    byteArray = (char*)OICCalloc(20, sizeof(char));
+
+    if (NULL == byteArray)
+    {
+        if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread();
+        return OC_STACK_NO_MEMORY;
+    }
+
+    sprintf(byteArray, "%02X%02X%02X",  verifNum[0], verifNum[1], verifNum[2]);
+
+    jstring jStr = env->NewStringUTF(byteArray);
+    if (!jStr)
+    {
+        if (JNI_EDETACHED == ret)
+        {
+            g_jvm->DetachCurrentThread();
+        }
+        return OC_STACK_ERROR;
+    }
+    OCStackResult result = (OCStackResult)env->CallIntMethod(m_jgListener, midL, jStr);
+
+    if (env->ExceptionCheck())
+    {
+        LOGE("Java exception is thrown");
+        env->ExceptionClear();
+    }
+
+    if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread();
+    free(byteArray);
+    return result;
+}
diff --git a/android/android_api/base/jni/JniDisplayVerifyNumListener.h b/android/android_api/base/jni/JniDisplayVerifyNumListener.h
new file mode 100644 (file)
index 0000000..ed06859
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+* //******************************************************************
+* //
+* // Copyright 2016 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 <jni.h>
+#include "JniOcStack.h"
+#include "OCProvisioningManager.hpp"
+
+#ifndef _Included_org_iotivity_base_JniDisplayVerifyNumListener
+#define _Included_org_iotivity_base_JniDisplayVerifyNumListener
+
+class JniDisplayVerifyNumListener
+{
+    public:
+        JniDisplayVerifyNumListener(JNIEnv *env, jobject jListener);
+        ~JniDisplayVerifyNumListener();
+
+        OCStackResult displayMutualVerifNumCallback(uint8_t verfNum[3]);
+
+    private:
+        jobject m_jgListener;
+};
+#endif
diff --git a/android/android_api/base/jni/JniKeepAliveListener.cpp b/android/android_api/base/jni/JniKeepAliveListener.cpp
new file mode 100644 (file)
index 0000000..b875a3e
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+* //******************************************************************
+* //
+* // Copyright 2017 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 "JniKeepAliveListener.h"
+#include "OCApi.h"
+#include "JniOcRepresentation.h"
+using namespace OC;
+
+JniKeepAliveListener::JniKeepAliveListener(JNIEnv *env, jobject jListener,
+        RemoveListenerCallback removeListenerCallback)
+{
+    m_jwListener = env->NewWeakGlobalRef(jListener);
+    m_removeListenerCallback = removeListenerCallback;
+}
+
+JniKeepAliveListener::~JniKeepAliveListener()
+{
+    LOGI("~JniKeepAliveListener()");
+    if (m_jwListener)
+    {
+        jint ret = JNI_ERR;
+        JNIEnv *env = GetJNIEnv(ret);
+        if (nullptr == env)
+        {
+            return;
+        }
+        env->DeleteWeakGlobalRef(m_jwListener);
+        m_jwListener = nullptr;
+        if (JNI_EDETACHED == ret)
+        {
+            g_jvm->DetachCurrentThread();
+        }
+    }
+}
+
+void JniKeepAliveListener::onKeepAliveListener(const int result, const OC::OCRepresentation& rep)
+{
+    jint ret = JNI_ERR;
+    JNIEnv *env = GetJNIEnv(ret);
+    if (nullptr == env)
+    {
+        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;
+    }
+
+    //create java OCRep
+    OCRepresentation* nRep = new OCRepresentation(rep);
+    jlong handle = reinterpret_cast<jlong>(nRep);
+    jobject jRep = env->NewObject(g_cls_OcRepresentation, g_mid_OcRepresentation_N_ctor_bool,
+                                  handle, true);
+
+    if (!jRep)
+    {
+        delete nRep;
+        checkExAndRemoveListener(env);
+        if (JNI_EDETACHED == ret)
+        {
+            g_jvm->DetachCurrentThread();
+        }
+        return;
+    }
+
+
+    jint jRet = static_cast<jint>(result);
+
+    jmethodID midL = env->GetMethodID(clsL, "onKeepAliveListener",
+                                      "(Lorg/iotivity/base/OcRepresentation;I)V");
+
+    if (!midL)
+    {
+        checkExAndRemoveListener(env);
+        if (JNI_EDETACHED == ret)
+        {
+            g_jvm->DetachCurrentThread();
+        }
+        return;
+    }
+
+    env->CallVoidMethod(jListener, midL, jRep, jRet);
+    if (env->ExceptionCheck())
+    {
+        LOGE("Java exception is thrown");
+        delete nRep;
+    }
+
+    checkExAndRemoveListener(env);
+
+    if (JNI_EDETACHED == ret)
+    {
+        g_jvm->DetachCurrentThread();
+    }
+}
+
+void JniKeepAliveListener::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/JniKeepAliveListener.h b/android/android_api/base/jni/JniKeepAliveListener.h
new file mode 100644 (file)
index 0000000..e1ab0f4
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+* //******************************************************************
+* //
+* // Copyright 2017 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 <jni.h>
+#include "JniOcStack.h"
+
+#ifndef _Included_org_iotivity_base_OcPlatform_PingListener
+#define _Included_org_iotivity_base_OcPlatform_PingListener
+
+class JniKeepAliveListener
+{
+public:
+    JniKeepAliveListener(JNIEnv *env, jobject jListener,
+        RemoveListenerCallback removeListenerCallback);
+    ~JniKeepAliveListener();
+
+    void onKeepAliveListener(const int result, const OC::OCRepresentation& rep);
+
+private:
+    RemoveListenerCallback m_removeListenerCallback;
+    jweak m_jwListener;
+    void checkExAndRemoveListener(JNIEnv* env);
+};
+#endif
\ No newline at end of file
index 8f76dc8..87d08a2 100644 (file)
@@ -24,6 +24,7 @@
 #include "JniOcResourceHandle.h"
 #include "JniOcPresenceHandle.h"
 #include "JniOcResourceResponse.h"
+#include "JniOcRepresentation.h"
 #include "JniOcSecurity.h"
 #include "JniOcDirectPairDevice.h"
 #include "JniUtils.h"
@@ -34,6 +35,8 @@
 #include "JniOcAccountManager.h"
 #endif
 
+#define AES_KEY_SIZE 32
+
 using namespace OC;
 
 JniOnResourceFoundListener* AddOnResourceFoundListener(JNIEnv* env, jobject jListener)
@@ -537,19 +540,92 @@ void RemoveOnDirectPairingListener(JNIEnv* env, jobject jListener)
     directPairingListenerMapLock.unlock();
 }
 
+#ifdef TCP_ADAPTER
+JniKeepAliveListener* AddKeepAliveListener(JNIEnv* env, jobject jListener)
+{
+    JniKeepAliveListener *KeepAliveListener = nullptr;
+
+    KeepAliveListenerMapLock.lock();
+
+    for (auto it = KeepAliveListenerMap.begin(); it !=
+        KeepAliveListenerMap.end(); ++it)
+    {
+        if (env->IsSameObject(jListener, it->first))
+        {
+            auto refPair = it->second;
+            KeepAliveListener = refPair.first;
+            refPair.second++;
+            it->second = refPair;
+            KeepAliveListenerMap.insert(*it);
+            LOGD("KeepAliveListener: ref. count incremented");
+            break;
+        }
+    }
+    if (!KeepAliveListener)
+    {
+         KeepAliveListener = new JniKeepAliveListener(env, jListener, RemoveKeepAliveListener);
+         jobject jgListener = env->NewGlobalRef(jListener);
+         KeepAliveListenerMap.insert(std::pair<jobject, std::pair<JniKeepAliveListener*, int>>(
+            jgListener,
+            std::pair<JniKeepAliveListener*, int>(KeepAliveListener, 1)));
+         LOGI("KeepAliveListener: new listener");
+    }
+    KeepAliveListenerMapLock.unlock();
+    return KeepAliveListener;
+}
+#endif
+#ifdef TCP_ADAPTER
+void RemoveKeepAliveListener(JNIEnv* env, jobject jListener)
+{
+    KeepAliveListenerMapLock.lock();
+    bool isFound = false;
+    for (auto it = KeepAliveListenerMap.begin(); it !=
+        KeepAliveListenerMap.end(); ++it)
+    {
+        if (env->IsSameObject(jListener, it->first))
+        {
+            auto refPair = it->second;
+            if (refPair.second > 1)
+            {
+                refPair.second--;
+                it->second = refPair;
+                KeepAliveListenerMap.insert(*it);
+                LOGI("KeepAliveListener: ref.count decremented");
+            }
+            else
+            {
+                env->DeleteGlobalRef(it->first);
+                JniKeepAliveListener* listener = refPair.first;
+                delete listener;
+                KeepAliveListenerMap.erase(it);
+                LOGI("KeepAliveListener is removed");
+            }
+            isFound = true;
+            break;
+        }
+    }
+    if (!isFound)
+    {
+        ThrowOcException(JNI_EXCEPTION, "KeepAliveListener not found");
+    }
+    KeepAliveListenerMapLock.unlock();
+}
+#endif
 /*
 * Class:     org_iotivity_base_OcPlatform
 * Method:    configure
-* Signature: (IILjava/lang/String;II)V
+* Signature: (IILjava/lang/String;IILjava/lang/String;I)V
 */
 JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_configure
 (JNIEnv *env, jclass clazz, jint jServiceType, jint jModeType, jstring jIpAddress, jint jPort,
-                                                                 jint jQOS, jstring jDbPath)
+ jint jQOS, jstring jDbPath, jstring jDbPathDefault , jstring jRescueDBPath, jint jkeySize,
+jbyteArray data, jint jTransport)
 {
     LOGI("OcPlatform_configure");
 
     std::string ipAddress;
-    std::string dbfile;
+    std::string dbfile, defaultPath, rescuePath;
+    static unsigned char *aesKey = NULL;
     if (jIpAddress)
     {
         ipAddress = env->GetStringUTFChars(jIpAddress, nullptr);
@@ -559,6 +635,39 @@ JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_configure
         dbfile = env->GetStringUTFChars(jDbPath, nullptr);
         JniOcSecurity::StoreDbPath(dbfile);
     }
+    //Either we have both paths or neither of them.
+    if ((jDbPathDefault && !jRescueDBPath) || (!jDbPathDefault && jRescueDBPath))
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "path cannot be null");
+        return;
+    }
+
+    if (!jDbPathDefault && !jRescueDBPath)
+    {
+        LOGI("Secure SVR DB feature not enable!!");
+    }
+    else
+    {
+        aesKey = (unsigned char*)calloc(1, sizeof(unsigned char) * AES_KEY_SIZE);
+        defaultPath = env->GetStringUTFChars(jDbPathDefault, nullptr);
+        rescuePath = env->GetStringUTFChars(jRescueDBPath, nullptr);
+        OC::JniOcSecurity::StoreDefault_DbPath(defaultPath, rescuePath, (int)jkeySize);
+
+        jbyte* key = env->GetByteArrayElements(data, 0);
+        jsize arrayLength = env->GetArrayLength(data);
+        if(arrayLength != AES_KEY_SIZE)
+        {
+            ThrowOcException(OC_STACK_INVALID_PARAM, "key size mismatch");
+        }
+        else
+        {
+            for(int i=0;i < AES_KEY_SIZE; i++)
+            {
+                aesKey[i]=(jbyte)key[i];
+            }
+        }
+
+    }
     uint16_t port = 0;
     if (jPort > 0)
     {
@@ -570,10 +679,66 @@ JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_configure
         JniUtils::getModeType(env, jModeType),
         ipAddress,
         port,
+        JniUtils::getOCTransportAdapter(jTransport),
         JniUtils::getQOS(env, static_cast<int>(jQOS)),
-        JniOcSecurity::getOCPersistentStorage()
+        aesKey,
+        JniOcSecurity::getOCPersistentStorage(),
+        JniOcSecurity::getOCPersistentStorageEnc(),
+        JniOcSecurity::getOCPersistentStorageRescue()
     };
+
     OCPlatform::Configure(cfg);
+
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    stop
+* Signature: ()V
+*/
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_stop
+(JNIEnv *env, jclass clazz)
+{
+    LOGI("OcPlatform.stop");
+
+    try {
+        OCStackResult result = OCPlatform::stop();
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Failed to stop ocplatform");
+            return;
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(e.code(), e.reason().c_str());
+    }
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    start
+* Signature: ()V
+*/
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_start
+(JNIEnv *env, jclass clazz)
+{
+    LOGI("OcPlatform.start");
+
+    try {
+        OCStackResult result = OCPlatform::start();
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Failed to start ocplatform");
+            return;
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(e.code(), e.reason().c_str());
+    }
 }
 
 /*
@@ -1473,7 +1638,7 @@ JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_registerDeviceInfo0(
             jstring jStr = (jstring)env->GetObjectArrayElement(jDeviceTypes, i);
             if (!jStr)
             {
-                delete deviceInfo.deviceName;
+                delete[] deviceInfo.deviceName;
                 ThrowOcException(OC_STACK_INVALID_PARAM, "device type cannot be null");
                 return;
             }
@@ -1481,7 +1646,7 @@ JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_registerDeviceInfo0(
             OCResourcePayloadAddStringLL(&deviceInfo.types, env->GetStringUTFChars(jStr, nullptr));
             if (env->ExceptionCheck())
             {
-                delete deviceInfo.deviceName;
+                delete[] deviceInfo.deviceName;
                 return;
             }
 
@@ -1498,7 +1663,7 @@ JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_registerDeviceInfo0(
     {
         OCStackResult result = OCPlatform::registerDeviceInfo(deviceInfo);
 
-        delete deviceInfo.deviceName;
+        delete[] deviceInfo.deviceName;
 
         if (OC_STACK_OK != result)
         {
@@ -1619,17 +1784,17 @@ JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_registerPlatformInfo0(
         {
             OCStackResult result = OCPlatform::registerPlatformInfo(platformInfo);
 
-            delete platformInfo.platformID;
-            delete platformInfo.manufacturerName;
-            delete platformInfo.manufacturerUrl;
-            delete platformInfo.modelNumber;
-            delete platformInfo.dateOfManufacture;
-            delete platformInfo.platformVersion;
-            delete platformInfo.operatingSystemVersion;
-            delete platformInfo.hardwareVersion;
-            delete platformInfo.firmwareVersion;
-            delete platformInfo.supportUrl;
-            delete platformInfo.systemTime;
+            delete[] platformInfo.platformID;
+            delete[] platformInfo.manufacturerName;
+            delete[] platformInfo.manufacturerUrl;
+            delete[] platformInfo.modelNumber;
+            delete[] platformInfo.dateOfManufacture;
+            delete[] platformInfo.platformVersion;
+            delete[] platformInfo.operatingSystemVersion;
+            delete[] platformInfo.hardwareVersion;
+            delete[] platformInfo.firmwareVersion;
+            delete[] platformInfo.supportUrl;
+            delete[] platformInfo.systemTime;
 
             if (OC_STACK_OK != result)
             {
@@ -2706,3 +2871,118 @@ JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_setDeviceId(
         ThrowOcException(e.code(), e.reason().c_str());
     }
 }
+
+/*
+ * Class:     org_iotivity_base_OcPlatform
+ * Method:    findKeepAliveResourceImpl
+ * Signature: (Ljava/lang/String;Lorg/iotivity/base/OcPlatform/KeepAliveListener;)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_findKeepAliveResourceImpl(
+        JNIEnv *env, jclass clazz, jstring jHost, jobject jListener)
+{
+#ifndef TCP_ADAPTER
+    ThrowOcException(OC_STACK_ERROR,
+                     "findKeepAliveResource is not supported. (Please build with WITH_TCP=1 option)");
+    return;
+#else
+    LOGI("OcPlatform_findKeepAliveResource");
+    std::string host;
+    if (!jHost)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "host cannot be null");
+        return;
+    }
+    else
+    {
+        host = env->GetStringUTFChars(jHost, nullptr);
+    }
+
+    if (!jListener)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "onKeepAliveFoundListener cannot be null");
+        return;
+    }
+
+    JniKeepAliveListener *onKeepAliveFoundListener = AddKeepAliveListener(env, jListener);
+
+    KeepAliveCallback KeepAliveCallback = [onKeepAliveFoundListener](const int ret,
+                                                                   const OCRepresentation& rep)
+    {
+        onKeepAliveFoundListener->onKeepAliveListener(ret, rep);
+    };
+
+    try
+    {
+        OCStackResult result = OCPlatform::findKeepAliveResource(host, KeepAliveCallback);
+
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "findKeepAliveResource has failed");
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(e.code(), e.reason().c_str());
+        return;
+    }
+#endif
+}
+
+/*
+ * Class:     org_iotivity_base_OcPlatform
+ * Method:    sendKeepAliveRequestImpl
+ * Signature: (Ljava/lang/String;ILorg/iotivity/base/OcPlatform/KeepAliveListener;)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_sendKeepAliveRequestImpl(
+        JNIEnv *env, jclass clazz, jstring jHost, jobject jRep, jobject jListener)
+{
+#ifndef TCP_ADAPTER
+    ThrowOcException(OC_STACK_ERROR,
+                     "sendKeepAlive is not supported. (Please build with WITH_TCP=1 option)");
+    return;
+#else
+    LOGI("OcPlatform_sendKeepAliveRequest");
+    std::string host;
+    if (!jHost)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "host cannot be null");
+        return;
+    }
+    else
+    {
+        host = env->GetStringUTFChars(jHost, nullptr);
+    }
+
+    if (!jListener)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "keepAliveResponseListener cannot be null");
+        return;
+    };
+
+    JniKeepAliveListener *KeepAliveResponseListener = AddKeepAliveListener(env, jListener);
+
+    KeepAliveCallback KeepAliveCallback = [KeepAliveResponseListener](const int ret,
+                                                         const OCRepresentation& rep)
+    {
+        KeepAliveResponseListener->onKeepAliveListener(ret, rep);
+    };
+
+    try
+    {
+        OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, jRep);
+        OCStackResult result = OCPlatform::sendKeepAliveRequest(host, *rep, KeepAliveCallback);
+
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "sendKeepAliveRequest has failed");
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(e.code(), e.reason().c_str());
+        return;
+    }
+#endif
+}
index cff6800..cd8a6ae 100644 (file)
@@ -27,7 +27,9 @@
 #include "JniOnDirectPairingListener.h"
 #include "JniOnPresenceListener.h"
 #include "JniOnObserveListener.h"
-
+#ifdef TCP_ADAPTER
+#include "JniKeepAliveListener.h"
+#endif
 #include <mutex>
 
 #ifndef _Included_org_iotivity_base_OcPlatform
@@ -56,6 +58,10 @@ void RemoveOnDPDevicesFoundListener(JNIEnv* env, jobject jListener);
 JniOnDirectPairingListener* AddOnDirectPairingListener(JNIEnv* env, jobject jListener);
 void RemoveOnDirectPairingListener(JNIEnv* env, jobject jListener);
 
+#ifdef TCP_ADAPTER
+JniKeepAliveListener* AddKeepAliveListener(JNIEnv* env, jobject jListener);
+void RemoveKeepAliveListener(JNIEnv* env, jobject jListener);
+#endif
 std::map<jobject, std::pair<JniOnResourceFoundListener*, int>> onResourceFoundListenerMap;
 std::map<jobject, std::pair<JniOnDeviceInfoListener*, int>> onDeviceInfoListenerMap;
 std::map<jobject, std::pair<JniOnPlatformInfoListener*, int>> onPlatformInfoListenerMap;
@@ -63,7 +69,9 @@ std::map<jobject, std::pair<JniOnPresenceListener*, int>> onPresenceListenerMap;
 std::map<jobject, std::pair<JniOnObserveListener*, int>> onObserveListenerMap;
 std::map<jobject, std::pair<JniOnDPDevicesFoundListener*, int>> onDPDevicesFoundListenerMap;
 std::map<jobject, std::pair<JniOnDirectPairingListener*, int>> directPairingListenerMap;
-
+#ifdef TCP_ADAPTER
+std::map<jobject, std::pair<JniKeepAliveListener*, int>> KeepAliveListenerMap;
+#endif
 std::mutex resourceFoundMapLock;
 std::mutex deviceInfoMapLock;
 std::mutex platformInfoMapLock;
@@ -71,6 +79,9 @@ std::mutex presenceMapLock;
 std::mutex observeMapLock;
 std::mutex dpDevicesFoundListenerMapLock;
 std::mutex directPairingListenerMapLock;
+#ifdef TCP_ADAPTER
+std::mutex KeepAliveListenerMapLock;
+#endif
 
 #ifdef __cplusplus
 extern "C" {
@@ -78,10 +89,27 @@ extern "C" {
     /*
     * Class:     org_iotivity_base_OcPlatform
     * Method:    configure
-    * Signature: (IILjava/lang/String;II)V
+    * Signature: (IILjava/lang/String;IILjava/lang/String;I)V
     */
     JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_configure
-        (JNIEnv *, jclass, jint, jint, jstring, jint, jint, jstring);
+        (JNIEnv *, jclass, jint, jint, jstring, jint, jint, jstring, jstring,
+         jstring, jint, jbyteArray, jint);
+
+    /*
+    * Class:     org_iotivity_base_OcPlatform
+    * Method:    stop
+    * Signature: ()V
+    */
+    JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_stop
+        (JNIEnv *, jclass);
+
+    /*
+    * Class:     org_iotivity_base_OcPlatform
+    * Method:    start
+    * Signature: ()V
+    */
+    JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_start
+        (JNIEnv *, jclass);
 
     /*
     * Class:     org_iotivity_base_OcPlatform
@@ -389,6 +417,21 @@ extern "C" {
     JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_setDeviceId(
             JNIEnv *, jobject, jbyteArray);
 
+    /*
+     * Class:     org_iotivity_base_OcPlatform
+     * Method:    findKeepAliveResourceImpl
+     * Signature: (Ljava/lang/String;Lorg/iotivity/base/OcPlatform/KeepAliveListener;)V
+     */
+    JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_findKeepAliveResourceImpl(
+            JNIEnv *, jclass, jstring, jobject);
+
+    /*
+     * Class:     org_iotivity_base_OcPlatform
+     * Method:    sendKeepAliveRequestImpl
+     * Signature: (Ljava/lang/String;ILorg/iotivity/base/OcPlatform/KeepAliveListener;)V
+     */
+    JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_sendKeepAliveRequestImpl(
+            JNIEnv *, jclass, jstring, jobject, jobject);
 #ifdef __cplusplus
 }
 #endif
index 5fe0b90..e66a873 100644 (file)
 #include "JniOcProvisioning.h"
 #include "JniPinCheckListener.h"
 #include "JniDisplayPinListener.h"
+#include "oic_malloc.h"
+#include "aclresource.h"
+#include "oxmverifycommon.h"
+#include "JniDisplayVerifyNumListener.h"
+#include "JniConfirmNumListener.h"
 
 using namespace OC;
 namespace PH = std::placeholders;
 
 static JniPinCheckListener *jniPinListener = nullptr;
 static JniDisplayPinListener *jniDisplayPinListener = nullptr;
+static JniDisplayVerifyNumListener *jniDisplayMutualVerifyNumListener = nullptr;
+static JniConfirmNumListener *jniConfirmMutualVerifyNumListener = nullptr;
 
 void Callback(char *buf, size_t size)
 {
@@ -54,6 +61,38 @@ void displayPinCB(char *pinBuf, size_t pinSize)
     }
 }
 
+OCStackResult displayMutualVerifNumCB(uint8_t *verifyNum)
+{
+    OCStackResult res;
+
+    if (jniDisplayMutualVerifyNumListener)
+    {
+        res = jniDisplayMutualVerifyNumListener->displayMutualVerifNumCallback(verifyNum);
+    }
+    else
+    {
+        res = OC_STACK_ERROR;
+        LOGE("DisplayMutualVerifyNumListener is null");
+    }
+    return res;
+}
+
+OCStackResult confirmMutualVerifNumCB()
+{
+    OCStackResult res;
+
+    if (jniConfirmMutualVerifyNumListener)
+    {
+        res = jniConfirmMutualVerifyNumListener->confirmMutualVerifNumCallback();
+    }
+    else
+    {
+        res = OC_STACK_ERROR;
+        LOGE("ConfirmMutualVerifyNumListener is null");
+    }
+    return res;
+}
+
 /*
  * Class:     org_iotivity_base_OcProvisioning
  * Method:    ownershipTransferCDdata
@@ -70,13 +109,8 @@ JNIEXPORT void JNICALL Java_org_iotivity_base_OcProvisioning_ownershipTransferCB
         OTMCallbackData_t CBData = {0};
         if (OIC_JUST_WORKS == (OicSecOxm_t)OxmType)
         {
-            CBData.loadSecretCB = LoadSecretJustWorksCallback;
-            CBData.createSecureSessionCB = CreateSecureSessionJustWorksCallback;
-            CBData.createSelectOxmPayloadCB = CreateJustWorksSelectOxmPayload;
-            CBData.createOwnerTransferPayloadCB = CreateJustWorksOwnerTransferPayload;
-
-            result = OCSecure::setOwnerTransferCallbackData((OicSecOxm_t)OxmType,
-                    &CBData, NULL);
+            /*NO callback required for JUST_WORKS*/
+            result = OCSecure::setInputPinCallback(NULL);
         }
         if (OIC_RANDOM_DEVICE_PIN == (OicSecOxm_t)OxmType)
         {
@@ -84,12 +118,7 @@ JNIEXPORT void JNICALL Java_org_iotivity_base_OcProvisioning_ownershipTransferCB
             {
                 delete jniPinListener;
                 jniPinListener = new JniPinCheckListener(env, jListener);
-                CBData.loadSecretCB = InputPinCodeCallback;
-                CBData.createSecureSessionCB = CreateSecureSessionRandomPinCallback;
-                CBData.createSelectOxmPayloadCB = CreatePinBasedSelectOxmPayload;
-                CBData.createOwnerTransferPayloadCB = CreatePinBasedOwnerTransferPayload;
-                result = OCSecure::setOwnerTransferCallbackData((OicSecOxm_t)OxmType,
-                        &CBData, Callback);
+                result = OCSecure::setInputPinCallback(Callback);
             }
             else
             {
@@ -256,6 +285,163 @@ JNIEXPORT jobjectArray JNICALL Java_org_iotivity_base_OcProvisioning_getDeviceSt
 
 /*
  * Class:     org_iotivity_base_OcProvisioning
+ * Method:    setDisplayNumListener
+ * Signature: (Lorg/iotivity/base/OcProvisioning/DisplayNumListener;)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcProvisioning_setDisplayNumListener
+  (JNIEnv *env, jclass clazz, jobject jListener)
+{
+    LOGI("OcProvisioning_setDisplayNumListener");
+
+    if (!jListener)
+    {
+        ThrowOcException(OC_STACK_INVALID_CALLBACK, "Listner can't be null");
+        return;
+    }
+    delete jniDisplayMutualVerifyNumListener;
+    jniDisplayMutualVerifyNumListener = new JniDisplayVerifyNumListener(env, jListener);
+
+    try
+    {
+        OCStackResult result = OCSecure::registerDisplayNumCallback(displayMutualVerifNumCB);
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Failed to set Listner");
+            return;
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+        return;
+    }
+}
+
+/*
+ * Class:     org_iotivity_base_OcProvisioning
+ * Method:    unsetDisplayNumListener
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_org_iotivity_base_OcProvisioning_unsetDisplayNumListener
+  (JNIEnv * env, jclass clazz)
+{
+    LOGI("OcProvisioning_unsetDisplayNumListener");
+
+    OCStackResult result = OCSecure::deregisterDisplayNumCallback();
+
+    if (OC_STACK_OK != result)
+    {
+        ThrowOcException(OC_STACK_INVALID_CALLBACK, "Failed to unset Listener");
+    }
+
+    return result;
+}
+
+/*
+ * Class:     org_iotivity_base_OcProvisioning
+ * Method:    setPinType0
+ * Signature: (II)I
+ */
+JNIEXPORT jint JNICALL Java_org_iotivity_base_OcProvisioning_setPinType0
+  (JNIEnv *env, jclass thiz, jint pinSize, jint pinType)
+{
+    LOGI("OcProvisioning_setPinType0");
+
+    OCStackResult result = OC_STACK_ERROR;
+    try
+    {
+        result = OCSecure::setRandomPinPolicy((size_t)pinSize, (OicSecPinType_t)pinType);
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Failed to set PinType");
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+    }
+    return result;
+}
+
+/*
+ * Class:     org_iotivity_base_OcProvisioning
+ * Method:    setConfirmNumListener
+ * Signature: (Lorg/iotivity/base/OcProvisioning/ConfirmNumListener;)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcProvisioning_setConfirmNumListener
+  (JNIEnv *env, jclass clazz, jobject jListener)
+{
+    LOGI("OcProvisioning_setConfirmNumListener");
+
+    if (!jListener)
+    {
+        ThrowOcException(OC_STACK_INVALID_CALLBACK, "Listner can't be null");
+        return;
+    }
+    delete jniConfirmMutualVerifyNumListener;
+    jniConfirmMutualVerifyNumListener = new JniConfirmNumListener(env, jListener);
+
+    try
+    {
+        OCStackResult result = OCSecure::registerUserConfirmCallback(confirmMutualVerifNumCB);
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Failed to set Listner");
+            return;
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+        return;
+    }
+}
+
+/*
+ * Class:     org_iotivity_base_OcProvisioning
+ * Method:    unsetConfirmNumListener
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_org_iotivity_base_OcProvisioning_unsetConfirmNumListener
+  (JNIEnv *env, jclass clazz)
+{
+    LOGI("OcProvisioning_unsetConfirmNumListener");
+
+    OCStackResult result = OCSecure::deregisterUserConfirmCallback();
+
+    if (OC_STACK_OK != result)
+    {
+        ThrowOcException(OC_STACK_INVALID_CALLBACK, "Failed to unser Listener");
+    }
+
+    return result;
+}
+/*
+ * Class:     org_iotivity_base_OcProvisioning
+ * Method:    setMVJustWorksOptions0
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_org_iotivity_base_OcProvisioning_setMVJustWorksOptions0
+  (JNIEnv *env, jclass clazz, jint options)
+{
+    LOGI("OcProvisioning_setMVJustWorksOptions0");
+
+    OCStackResult result = OCSecure::setVerifyOptionMask((VerifyOptionBitmask_t)options);
+
+    if (OC_STACK_OK != result)
+    {
+        ThrowOcException(OC_STACK_INVALID_CALLBACK, "setMVJustWorksOptions Failed");
+    }
+
+    return result;
+}
+
+
+/*
+ * Class:     org_iotivity_base_OcProvisioning
  * Method:    setDisplayPinListener
  * Signature: (Lorg/iotivity/base/OcProvisioning/DisplayPinListener;)V
  */
@@ -300,7 +486,7 @@ JNIEXPORT void JNICALL Java_org_iotivity_base_OcProvisioning_setDisplayPinListen
 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
     jbyte* trustCertChainBytes = env->GetByteArrayElements(trustCertChain, 0);
     jsize arrayLength = env->GetArrayLength(trustCertChain);
-    uint16_t credId;
+    uint16_t credId = -1;
     unsigned char* trustedCertChar = new unsigned char[arrayLength];
     try
     {
@@ -324,3 +510,110 @@ JNIEXPORT void JNICALL Java_org_iotivity_base_OcProvisioning_setDisplayPinListen
     return -1;
 #endif // __WITH_DTLS__ || __WITH_TLS__
 }
+
+/*
+ * Class:     org_iotivity_base_OcProvisioning
+ * Method:    setDeviceIdSeed1
+ * Signature: (Lorg/iotivity/base/OcProvisioning/provisionTrustCertChain1;)V
+ */
+    JNIEXPORT jint JNICALL Java_org_iotivity_base_OcProvisioning_setDeviceIdSeed1
+(JNIEnv *env, jobject thiz, jbyteArray seed)
+{
+  LOGD("OcProvisioning_setDeviceIdSeed1");
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+       jbyte* byteSeed = env->GetByteArrayElements(seed, 0);
+       jsize arrayLength = env->GetArrayLength(seed);
+       try
+       {
+    env->GetByteArrayRegion (seed, 0, arrayLength, byteSeed);
+               OCStackResult result = OCSecure::setDeviceIdSeed((uint8_t*)byteSeed, arrayLength);
+               if (OC_STACK_OK != result)
+               {
+                 ThrowOcException(result, "OcProvisioning_setDeviceIdSeed");
+                       return -1;
+               }
+       }
+       catch (OCException& e)
+       {
+                                       LOGE("%s", e.reason().c_str());
+                                       ThrowOcException(e.code(), e.reason().c_str());
+       }
+       return 0;
+#else
+       ThrowOcException(OC_STACK_INVALID_PARAM, "WITH_TLS not enabled");
+       return -1;
+#endif // __WITH_DTLS__ || __WITH_TLS__
+}
+
+/*
+ * Class:     org_iotivity_base_OcProvisioning
+ * Method:    saveACL
+ * Signature: (Ljava/lang/Object;)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcProvisioning_saveACL
+  (JNIEnv *env , jclass thiz, jobject jacl)
+{
+    LOGD("OcProvisioning_saveACL");
+
+    if (!jacl)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "acl can't be null");
+    }
+
+    OicSecAcl_t *acl = (OicSecAcl_t*)OICCalloc(1, sizeof(OicSecAcl_t));
+    if (!acl)
+    {
+        ThrowOcException(OC_STACK_NO_MEMORY, "acl allocation failed");
+        return;
+    }
+
+    if (OC_STACK_OK != JniSecureUtils::convertJavaACLToOCAcl(env, jacl, acl))
+    {
+        DeleteACLList(acl);
+        ThrowOcException(OC_STACK_INVALID_PARAM, "Failed to convert Java acl to OC acl");
+        return ;
+    }
+
+    try
+    {
+        OCStackResult result = OCSecure::saveACL(acl);
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "OCSecure::saveACL Failed");
+            return;
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+       ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+    }
+}
+
+/*
+ * Class:     org_iotivity_base_OcProvisioning
+ * Method:    doSelfOwnershiptransfer
+ * Signature: ()V
+ */
+       JNIEXPORT void JNICALL Java_org_iotivity_base_OcProvisioning_doSelfOwnershiptransfer
+(JNIEnv *env, jclass thiz)
+{
+
+  LOGD("OcProvisioning_doSelfOwnershiptransfer");
+
+  try
+  {
+         OCStackResult result = OCSecure::configSelfOwnership();
+         if (OC_STACK_OK != result)
+         {
+                 ThrowOcException(result, "OCSecure::configSelfOwnership Failed");
+                 return;
+         }
+  }
+  catch (OCException& e)
+  {
+         LOGE("%s", e.reason().c_str());
+         ThrowOcException(e.code(), e.reason().c_str());
+         return;
+  }
+}
index 3b8fa0b..72645bd 100644 (file)
@@ -80,11 +80,52 @@ JNIEXPORT void JNICALL Java_org_iotivity_base_OcProvisioning_setDisplayPinListen
 
 /*
  * Class:     org_iotivity_base_OcProvisioning
+ * Method:    setDisplayNumListener
+ * Signature: (Lorg/iotivity/base/OcProvisioning/DisplayNumListener;)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcProvisioning_setDisplayNumListener
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     org_iotivity_base_OcProvisioning
+ * Method:    unsetDisplayNumListener
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_org_iotivity_base_OcProvisioning_unsetDisplayNumListener
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_iotivity_base_OcProvisioning
+ * Method:    setConfirmNumListener
+ * Signature: (Lorg/iotivity/base/OcProvisioning/ConfirmNumListener;)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcProvisioning_setConfirmNumListener
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     org_iotivity_base_OcProvisioning
+ * Method:    unsetConfirmNumListener
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_org_iotivity_base_OcProvisioning_unsetConfirmNumListener
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     org_iotivity_base_OcProvisioning
+ * Method:    setMVJustWorksOptions0
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_org_iotivity_base_OcProvisioning_setMVJustWorksOptions0
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     org_iotivity_base_OcProvisioning
  * Method:    getDevicestatusLists
  * Signature: (I)[Lorg/iotivity/base/OcSecureResource;
  */
 JNIEXPORT jobjectArray JNICALL Java_org_iotivity_base_OcProvisioning_getDeviceStatusList1
   (JNIEnv *, jclass, jint);
+
 /*
  * Class:     org_iotivity_base_OcProvisioning
  * Method:    saveTrustCertChain1
@@ -92,6 +133,38 @@ JNIEXPORT jobjectArray JNICALL Java_org_iotivity_base_OcProvisioning_getDeviceSt
  */
 JNIEXPORT jint JNICALL Java_org_iotivity_base_OcProvisioning_saveTrustCertChain1
     (JNIEnv *, jobject, jbyteArray, jint);
+
+/*
+ * Class:     org_iotivity_base_OcProvisioning
+ * Method:    setPinType0
+ * Signature: (II)I
+ */
+JNIEXPORT jint JNICALL Java_org_iotivity_base_OcProvisioning_setPinType0
+  (JNIEnv *, jclass, jint, jint);
+
+/*
+ * Class:     org_iotivity_base_OcProvisioning
+ * Method:    setDeviceIdSeed1
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_org_iotivity_base_OcProvisioning_setDeviceIdSeed1
+  (JNIEnv *, jobject, jbyteArray);
+
+/*
+ * Class:     org_iotivity_base_OcProvisioning
+ * Method:    saveACL
+ * Signature: (Ljava/lang/Object;)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcProvisioning_saveACL
+  (JNIEnv *, jclass, jobject);
+
+/*
+ * Class:     org_iotivity_base_OcProvisioning
+ * Method:    doSelfOwnershiptransfer
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcProvisioning_doSelfOwnershiptransfer
+  (JNIEnv *, jclass);
 #ifdef __cplusplus
 }
 #endif
index 44f1eb3..9d30ba2 100644 (file)
@@ -356,6 +356,11 @@ std::string JniOcResource::sid() const
     return m_sharedResource->sid();
 }
 
+std::string JniOcResource::deviceName() const
+{
+    return m_sharedResource->deviceName();
+}
+
 JniOnGetListener* JniOcResource::addOnGetListener(JNIEnv* env, jobject jListener)
 {
     return this->m_onGetManager.addListener(env, jListener, this);
@@ -1705,6 +1710,24 @@ JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcResource_getServerId
 
 /*
 * Class:     org_iotivity_base_OcResource
+* Method:    getDeviceName
+* Signature: ()Ljava/lang/String;
+*/
+JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcResource_getDeviceName
+(JNIEnv *env, jobject thiz)
+{
+    LOGD("OcResource_getDeviceName");
+    JniOcResource *resource = JniOcResource::getJniOcResourcePtr(env, thiz);
+    if (!resource)
+    {
+        return nullptr;
+    }
+
+    return env->NewStringUTF(resource->deviceName().c_str());
+}
+
+/*
+* Class:     org_iotivity_base_OcResource
 * Method:    dispose
 * Signature: ()V
 */
index 7dfacd3..e05da82 100644 (file)
@@ -92,6 +92,7 @@ public:
     std::vector< std::string >  getResourceInterfaces(void) const;
     OCResourceIdentifier uniqueIdentifier() const;
     std::string sid() const;
+    std::string deviceName() const;
 
     JniOnGetListener* addOnGetListener(JNIEnv* env, jobject jListener);
     JniOnPutListener* addOnPutListener(JNIEnv* env, jobject jListener);
@@ -374,6 +375,14 @@ extern "C" {
 
     /*
     * Class:     org_iotivity_base_OcResource
+    * Method:    getDeviceName
+    * Signature: ()Ljava/lang/String;
+    */
+    JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcResource_getDeviceName
+        (JNIEnv *, jobject);
+
+    /*
+    * Class:     org_iotivity_base_OcResource
     * Method:    dispose
     * Signature: ()V
     */
index 2c6274b..3e63572 100644 (file)
@@ -315,7 +315,7 @@ OCStackResult JniOcSecureResource::provisionDirectPairing(JNIEnv* env, jobjectAr
                 tmp1 = tmp2;
             }
 
-            delete pconf->prm;
+            delete[] pconf->prm;
             delete pconf;
             resultListener->ProvisionResultCallback(result, hasError, ListenerFunc::PROVISIONDIRECTPAIRING);
         };
@@ -333,7 +333,7 @@ OCStackResult JniOcSecureResource::provisionDirectPairing(JNIEnv* env, jobjectAr
             tmp1 = tmp2;
         }
 
-        delete pconf->prm;
+        delete[] pconf->prm;
         delete pconf;
     }
     return ret;
old mode 100644 (file)
new mode 100755 (executable)
index 54821ee..0a194dd
@@ -20,6 +20,7 @@
  ******************************************************************/
 #include "JniOcSecurity.h"
 #include "JniOcStack.h"
+#include "ocstack.h"
 
 /*
  * TODO: Persistant Storage Handling should be done by App.
@@ -29,6 +30,8 @@
 using namespace std;
 namespace PH = std::placeholders;
 namespace OC {
+    static string s_enc_dbpath, s_rescue_path;
+    static int AES_KEY_SZ;
 
     string& JniOcSecurity::store_path()
     {
@@ -36,11 +39,51 @@ namespace OC {
         return s_dbPath;
     }
 
+    string& JniOcSecurity::getEncDbPath()
+    {
+        return s_enc_dbpath;
+    }
+    string& JniOcSecurity::getRescueDbPath()
+    {
+        return s_rescue_path;
+    }
+
     void JniOcSecurity::StoreDbPath(const string &path)
     {
         store_path() = path;
     }
 
+    void JniOcSecurity::StoreDefault_DbPath(const string &path, const string &rescue_path, int key_size)
+    {
+        s_enc_dbpath = path;
+        s_rescue_path = rescue_path;
+        AES_KEY_SZ = key_size;
+    }
+
+    OCPersistentStorage* JniOcSecurity::getOCPersistentStorageEnc()
+    {
+        if (getEncDbPath().empty())
+        {
+            return nullptr;
+        }
+        static OCPersistentStorage s_psEnc { &JniOcSecurity::client_open_enc, fread,
+            fwrite, fclose, unlink, &JniOcSecurity::client_encrypt,
+            &JniOcSecurity::client_decrypt};
+        return &s_psEnc;
+    }
+
+    OCPersistentStorage* JniOcSecurity::getOCPersistentStorageRescue()
+    {
+        if (getRescueDbPath().empty())
+        {
+            return nullptr;
+        }
+        static OCPersistentStorage s_psRescue { &JniOcSecurity::client_open_rescue, fread,
+            fwrite, fclose, unlink, &JniOcSecurity::client_encrypt,
+            &JniOcSecurity::client_decrypt};
+        return &s_psRescue;
+    }
+
     OCPersistentStorage* JniOcSecurity::getOCPersistentStorage()
     {
         if (store_path().empty())
@@ -48,13 +91,173 @@ namespace OC {
             return nullptr;
         }
         static OCPersistentStorage s_ps { &JniOcSecurity::client_open, fread,
-            fwrite, fclose, unlink };
+            fwrite, fclose, &JniOcSecurity::client_unlink, NULL, NULL};
         return &s_ps;
     }
+        int JniOcSecurity::client_encrypt(const unsigned char *pt, size_t pt_len,
+            unsigned char **ct, size_t *ct_len)
+    {
+        if (OC_STACK_OK != OCEncrypt(pt, pt_len, ct, ct_len))
+            return 1;
+        return 0;
+    }
+
+    int JniOcSecurity::client_decrypt(const unsigned char *ct, size_t ct_len,
+            unsigned char **pt, size_t *pt_len)
+    {
+        if (OC_STACK_OK != OCDecrypt(ct, ct_len, pt, pt_len))
+            return 1;
+        return 0;
+    }
 
     FILE* JniOcSecurity::client_open(const char *path, const char *mode)
     {
         LOGI("Opening SVR Database file '%s' with mode '%s'\n", store_path().c_str(), mode);
         return fopen(store_path().c_str(), mode);
     }
+
+
+    FILE* JniOcSecurity::client_open_enc(const char *path, const char *mode)
+    {
+        LOGI("Opening SVR Database file '%s' with mode '%s'\n", getEncDbPath().c_str(), mode);
+        return fopen(getEncDbPath().c_str(), mode);
+    }
+
+    FILE* JniOcSecurity::client_open_rescue(const char *path, const char *mode)
+    {
+        LOGI("Opening SVR Database file '%s' with mode '%s'\n", getRescueDbPath().c_str(), mode);
+        return fopen(getRescueDbPath().c_str(), mode);
+    }
+
+    int JniOcSecurity::client_unlink(const char *path)
+    {
+        LOGI("unlink SVR Database file '%s' \n", store_path().c_str());
+        return unlink(store_path().c_str());
+    }
+
+    size_t JniOcSecurity::getDBSize(const char *filepath)
+    {
+        FILE *fp = fopen(filepath, "rb");
+        if (!fp) return 0;
+
+        size_t size = 0;
+        char buffer[1023];
+        if (fp)
+        {
+            size_t bytesRead = 0;
+            do
+            {
+                bytesRead = fread(buffer, 1, 1023, fp); //we here read encrypted data
+                size += bytesRead;
+            } while (bytesRead);
+        }
+        if (fp) fclose(fp);
+        return size;
+    }
+
+    OCStackResult JniOcSecurity::ResetDBFile(const char *cred_file)
+    {
+
+        size_t fileSize = getDBSize(s_rescue_path.c_str());
+        unsigned char *data  = (unsigned char *)calloc(1, sizeof(unsigned char) * fileSize);
+        unsigned char *ct = NULL;
+        size_t ct_len;
+
+        OCPersistentStorage *ps = JniOcSecurity::getOCPersistentStorage();
+
+        FILE *fp = fopen(s_rescue_path.c_str(), "rb");
+        FILE *filep = fopen(cred_file, "wb");
+        OCStackResult ret = OC_STACK_OK;
+
+        if (!fp || !filep)
+        {
+            LOGE("Failed to open %s\n", s_rescue_path.c_str());
+            ret = OC_STACK_ERROR;
+            goto exit;
+        }
+        if (fread(data, 1, fileSize, fp) != fileSize)
+        {
+            LOGE("Failed to read %s\n", s_rescue_path.c_str());
+            ret = OC_STACK_ERROR;
+            goto exit;
+        }
+        if (OC_STACK_OK != ps->encrypt(data, fileSize, &ct, &ct_len))
+        {
+            LOGE("Encryption Failed %d\n",__LINE__);
+        }
+        if (fwrite(ct, 1, ct_len, filep) != ct_len)
+        {
+            LOGE("Failed to write encrypted data to %s\n", cred_file);
+            ret = OC_STACK_ERROR;
+            goto exit;
+        }
+exit:
+        if (filep) fclose(filep);
+        if (fp) fclose(fp);
+        free(data);
+        return ret;
+    }
+#if 0
+    size_t JniOcSecurity::client_read(void *buffer, size_t size, size_t nmemb, FILE *fp)
+    {
+        size_t fileSize = size * nmemb;
+        size_t pt_len;
+        unsigned char *pt = NULL;
+
+        OCPersistentStorage *ps = JniOcSecurity::getOCPersistentStorage();
+        unsigned char *buf = (unsigned char*)calloc(1, sizeof(unsigned char) * fileSize);
+
+        LOGE("In JniOcSecurity::client_read ps = %p, fileSize = %d\n", ps, fileSize);
+
+        if (fileSize == fread(buf, 1, fileSize, fp))
+        {
+            if (OC_STACK_OK != ps->decrypt(buf, fileSize, &pt, &pt_len))
+            {
+                LOGE( "ps->decrypt() Failed !!");
+                fileSize = 0;
+                goto exit;
+            }
+            else
+            {
+                memcpy(buffer, pt, pt_len);
+                fileSize = pt_len;
+            }
+        }
+        else
+        {
+            LOGE("Failed fileSize == fread(buf, 1, fileSize, fp)");
+            fileSize = 0;
+        }
+exit:
+        free(buf);
+        return fileSize;
+    }
+
+    size_t JniOcSecurity::client_write(const void *buffer, size_t size,
+            size_t nmemb, FILE *fp)
+    {
+        size_t fileSize = size * nmemb;
+        unsigned char *ct = NULL;
+        size_t ct_len = 0;
+        OCPersistentStorage *ps = JniOcSecurity::getOCPersistentStorage();
+
+        if (0 != ps->encrypt((const unsigned char*)buffer, fileSize, &ct, &ct_len))
+        {
+            LOGE( "ps->encrypt() Failed !!");
+            fileSize = 0;
+            goto exit;
+        }
+
+        fileSize = ct_len;
+        if (fileSize != fwrite(ct, 1, fileSize,fp))
+        {
+            LOGE( "fwrite() Failed !!");
+            fileSize = 0;
+            goto exit;
+        }
+exit:
+        free(ct);
+        return fileSize;
+    }
+#endif
 }
old mode 100644 (file)
new mode 100755 (executable)
index 78293e6..53aa296
@@ -33,11 +33,30 @@ namespace OC
     class JniOcSecurity
     {
         private:
+            static size_t getDBSize(const char *filepath);
+            static OCStackResult ResetDBFile(const char *cred_file);
+            static size_t client_read(void *buffer, size_t size, size_t nmemb, FILE *fp);
+
+            static size_t client_write(const void *buffer, size_t size,
+                    size_t nmemb, FILE *fp);
             static FILE* client_open(const char*, const char*);
+            static FILE* client_open_enc(const char*, const char*);
+            static FILE* client_open_rescue(const char*, const char*);
+            static int client_unlink(const char *path);
+            static int client_encrypt(const unsigned char *pt, size_t pt_len,
+                                unsigned char **ct, size_t *ct_len);
+            static int client_decrypt(const unsigned char *ct, size_t ct_len,
+                                unsigned char **pt, size_t *pt_len);
         public:
             static std::string& store_path(void);
+            static std::string& getEncDbPath(void);
+            static std::string& getRescueDbPath(void);
             static void StoreDbPath(const std::string&);
+            static void StoreDefault_DbPath(const std::string&, const std::string&, int);
             static OCPersistentStorage* getOCPersistentStorage(void);
+            static OCPersistentStorage* getOCPersistentStorageEnc(void);
+            static OCPersistentStorage* getOCPersistentStorageRescue(void);
+
     };
 }
 #endif //__JNIOCSECURITY_H
index 74e48e6..ebcec3d 100644 (file)
@@ -133,6 +133,36 @@ public:
         };
     }
 
+    static OCTransportAdapter getOCTransportAdapter(int adapter)
+    {
+        int transport = OCTransportAdapter::OC_DEFAULT_ADAPTER;
+        if (adapter & CT_ADAPTER_IP)
+        {
+            transport |= OCTransportAdapter::OC_ADAPTER_IP;
+        }
+
+        if (adapter & CT_ADAPTER_GATT_BTLE)
+        {
+            transport |= OCTransportAdapter::OC_ADAPTER_GATT_BTLE;
+        }
+
+        if (adapter & CT_ADAPTER_RFCOMM_BTEDR)
+        {
+            transport |= OCTransportAdapter::OC_ADAPTER_RFCOMM_BTEDR;
+        }
+
+        if (adapter & CT_ADAPTER_TCP)
+        {
+            transport |= OCTransportAdapter::OC_ADAPTER_TCP;
+        }
+
+        if (adapter & CT_ADAPTER_NFC)
+        {
+            transport |= OCTransportAdapter::OC_ADAPTER_NFC;
+        }
+        return (OCTransportAdapter)transport;
+    }
+
     static std::string stackResultToStr(const int result)
     {
         switch (result)
@@ -207,6 +237,8 @@ public:
             case OC_STACK_INVALID_JSON:
                 return "INVALID_JSON";
             /** Request is not authorized by Resource Server. */
+            case OC_STACK_NOT_ACCEPTABLE:
+                return "NOT_ACCEPTABLE";
             case OC_STACK_UNAUTHORIZED_REQ:
                 return "UNAUTHORIZED_REQ";
             /** Error code from PDM */
@@ -216,6 +248,8 @@ public:
                 return "DUPLICATE_UUID";
             case OC_STACK_INCONSISTENT_DB:
                 return "INCONSISTENT_DB";
+            case OC_STACK_SVR_DB_NOT_EXIST:
+                return "SVR_DB_NOT_EXIST";
             /** Error code from OTM */
             case OC_STACK_AUTHENTICATION_FAILURE:
                 return "AUTHENTICATION_FAILURE";
diff --git a/android/android_api/base/src/main/java/org/iotivity/base/MVJustWorksOptionMask.java b/android/android_api/base/src/main/java/org/iotivity/base/MVJustWorksOptionMask.java
new file mode 100644 (file)
index 0000000..7e111ca
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ *******************************************************************
+ *
+ * Copyright 2016 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.
+ *
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.base;
+
+import java.security.InvalidParameterException;
+import java.util.EnumSet;
+
+public enum MVJustWorksOptionMask {
+    NOT_APPLICABLE (0x0),
+    DISPLAY_MUTUAL_VERIF_NUM  (0x1 << 0),
+    CONFIRM_MUTUAL_VERIF_NUM  (0x1 << 1),
+    ;
+
+    private int value;
+
+    private MVJustWorksOptionMask(int value) {
+        this.value = value;
+    }
+
+    public int getValue() {
+        return this.value;
+    }
+
+    public static EnumSet<MVJustWorksOptionMask> convertToEnumSet(int value) {
+        EnumSet<MVJustWorksOptionMask> typeSet = null;
+
+        for (MVJustWorksOptionMask v : values()) {
+            if (0 != (value & v.getValue())) {
+                if (null == typeSet) {
+                    typeSet = EnumSet.of(v);
+                } else {
+                    typeSet.add(v);
+                }
+            }
+        }
+
+        if (null == typeSet || typeSet.isEmpty()) {
+            throw new InvalidParameterException("Unexpected MVJustWorksOptionMask value:" + value);
+        }
+
+        return typeSet;
+    }
+
+}
index 89e7fae..954eab2 100644 (file)
@@ -77,6 +77,8 @@ public final class OcPlatform {
     private static volatile boolean sIsPlatformInitialized = false;
     private static QualityOfService sPlatformQualityOfService = QualityOfService.NA;
 
+    private static volatile boolean sIsStopPlatform = false;
+
     private OcPlatform() {
     }
 
@@ -89,6 +91,12 @@ public final class OcPlatform {
      * @param platformConfig platform configuration
      */
     public synchronized static void Configure(PlatformConfig platformConfig) {
+        if (sIsStopPlatform)
+        {
+            OcPlatform.start();
+            sIsStopPlatform = false;
+        }
+
         if (!sIsPlatformInitialized) {
             CaInterface.initialize(platformConfig.getActivity(), platformConfig.getContext());
 
@@ -100,7 +108,12 @@ public final class OcPlatform {
                     platformConfig.getIpAddress(),
                     platformConfig.getPort(),
                     platformConfig.getQualityOfService().getValue(),
-                    platformConfig.getSvrDbPath()
+                    platformConfig.getSvrDbPath(),
+                    platformConfig.getDBDefaultPath(),
+                    platformConfig.getDBRescuePath(),
+                    platformConfig.getKeySize(),
+                    platformConfig.getKey(),
+                    platformConfig.getAvailableTransportType()
             );
 
             sIsPlatformInitialized = true;
@@ -112,7 +125,33 @@ public final class OcPlatform {
                                          String ipAddress,
                                          int port,
                                          int qualityOfService,
-                                         String dbPath);
+                                         String dbPath,
+                                         String dbPathDefault,
+                                         String dbRescuePath,
+                                         int keySize,
+                                         byte[] key,
+                                         int transport);
+
+    /**
+     * API for stop all process of the OcPlatform.
+     * All of threads and memory will be terminated by this API.
+     * Iotivity Core can be started again through Configure(PlatformConfig platformConfig) API.
+     * Both Configure and Shutdown API is filtering for duplicated calling even while processing.
+     * <p>
+     * Note: This API is for both server and client side.
+     * </p>
+     */
+    public synchronized static void Shutdown() {
+        if (!sIsStopPlatform)
+        {
+            OcPlatform.stop();
+            sIsStopPlatform = true;
+            sIsPlatformInitialized = false;
+        }
+    }
+
+    private static native void stop();
+    private static native void start();
 
     /**
      * API for notifying base that resource's attributes have changed.
@@ -1122,6 +1161,16 @@ public final class OcPlatform {
         public EntityHandlerResult handleEntity(OcResourceRequest ocResourceRequest);
     }
 
+    /**
+     * Listner to get result of findKeepAliveResource and sendKeepAliveRequest.
+     * An PingListener can be registered via the OcPlatform.KeepAliveListener and
+     * OcPlatform.sendKeepAliveRequest call.
+     * Event listeners are notified asynchronously
+     */
+    public interface KeepAliveListener {
+        public void onKeepAliveListener(OcRepresentation ocRepresentation, int result);
+    }
+
     private static void initCheck() {
         if (!sIsPlatformInitialized) {
             throw new IllegalStateException("OcPlatform must be configured by making a call to " +
@@ -1183,4 +1232,42 @@ public final class OcPlatform {
      * Method to set DeviceId.
      */
     public static native void setDeviceId(byte[] deviceId) throws OcException;
+
+    /**
+    * gets OCRepresentation of KeepAlive resource from given host.
+    *
+    * @param host                   Host IP Address of pingResource
+    * @param onKeepAliveFoundListener Function to callback with result code and OCRepresentation.
+    * @throws OcException if failure
+    */
+    public static void findKeepAliveResource(String host,
+                                             KeepAliveListener onKeepAliveFoundListener)
+                                             throws OcException {
+        OcPlatform.initCheck();
+        OcPlatform.findKeepAliveResourceImpl(host, onKeepAliveFoundListener);
+    }
+
+    private static native void findKeepAliveResourceImpl(String host,
+                                                         KeepAliveListener onKeepAliveFoundListener)
+                                                         throws OcException;
+
+    /**
+    * send KeepAlive request to given host.
+    *
+    * @param interval             interval time of expected pong response
+    * @param keepAliveResponseListener handles callback
+    * @throws OcException if failure
+    *
+    */
+    public static void sendKeepAliveRequest(String host, OcRepresentation ocRepresentation,
+                                            KeepAliveListener keepAliveResponseListener)
+                                            throws OcException {
+        OcPlatform.initCheck();
+        OcPlatform.sendKeepAliveRequestImpl(host, ocRepresentation, keepAliveResponseListener);
+    }
+
+    private static native void sendKeepAliveRequestImpl(String host,
+                                                        OcRepresentation ocRepresentation,
+                                                        KeepAliveListener keepAliveResponseListener)
+                                                        throws OcException;
 }
index 8cb282b..395021f 100644 (file)
@@ -25,6 +25,7 @@ package org.iotivity.base;
 import java.util.List;
 import java.util.Arrays;
 import java.util.Map;
+import java.util.EnumSet;
 
 /**
  * OcProvisionig represents functions corresponding to the provisioing of
@@ -101,6 +102,68 @@ public class OcProvisioning {
     }
 
     /**
+     * API to Set callback for displaying verifNum in verified Just-Works.
+     *
+     *@param DisplayNumListener callback Listener to be registered for
+                                            displaying VerifyNUm.
+     *@throws OcException
+     */
+    public static native void setDisplayNumListener(
+            DisplayNumListener displayNumListener) throws OcException;
+
+    public static interface DisplayNumListener {
+        public int displayNumListener(String verifyNum);
+    }
+
+    /**
+     * API to unregister DisplayNumListener Listener
+     *
+     *@return  0 on success, 1 on failure
+     *@throws OcException
+     */
+    public static native int unsetDisplayNumListener() throws OcException;
+
+    /**
+     * API to Set callback for getting user confirmation in verified
+     * Just-Works
+     *
+     *@param ConfirmNumListener callback Listener to be registered for getting user confirmation.
+     *@throws OcException
+     */
+    public static native void setConfirmNumListener(ConfirmNumListener
+            confirmNumListener) throws OcException;
+
+    public static interface ConfirmNumListener {
+        public int confirmNumListener();
+    }
+
+    /**
+     * API to unregister ConfirmMutualVerifyNum Listener
+     *
+     *@return  0 on success, 1 on failure
+     *@throws OcException
+     */
+    public static native int unsetConfirmNumListener() throws OcException;
+
+    /**
+     * API to set options for Mutual Verified Just-works
+     * Default is  for both screen PIN display and get user confirmation.
+     *
+     */
+    public static int setMVJustWorksOptions(EnumSet<MVJustWorksOptionMask> optionMask) throws OcException {
+
+        int optionMaskInt = 0;
+
+        for (MVJustWorksOptionMask ops : MVJustWorksOptionMask.values()) {
+            if (optionMask.contains(ops))
+                optionMaskInt |= ops.getValue();
+        }
+        return setMVJustWorksOptions0(optionMaskInt);
+    }
+
+    private static native int setMVJustWorksOptions0(int optionsMask) throws OcException;
+
+    /**
      * Method to get Array of owned and un-owned devices in the current subnet.
      *
      * @param timeout    timeout in sec for the API to return.
@@ -125,4 +188,50 @@ public class OcProvisioning {
     }
     private static native int saveTrustCertChain1(byte[] trustCertChain, int encodingType)
         throws OcException;
+
+    /**
+     *  Method to save pin type.
+     *
+     *  @param pinSize Byte Len of Random pin.
+     *  @param pinType Enumset of pin, see PinType for enums
+     *  @throws OcException
+     */
+    public static int setPinType(int pinSize, EnumSet<PinType>  pinType) throws OcException {
+
+        int pinTypeInt = 0;
+
+        for (PinType ops : PinType.values()) {
+            if (pinType.contains(ops))
+                pinTypeInt |= ops.getValue();
+        }
+        return setPinType0(pinSize, pinTypeInt);
+    }
+    private static native int setPinType0(int pinSize, int pinType) throws OcException;
+
+    /**
+     *  Method to save the seed value to generate device UUID
+     *
+     *  @param seed   buffer of seed value
+     *  @throws OcException
+     */
+    public static int setDeviceIdSeed(byte[] seed) throws OcException {
+        return setDeviceIdSeed1(seed);
+    }
+    private static native int setDeviceIdSeed1(byte[] seed)
+        throws OcException;
+    
+    /**
+     * API to save ACL, having multiple ACE's
+     *
+     *@param acl object
+     *@throws OcException
+     */
+    public static native void saveACL(Object acl) throws OcException;
+
+    /**
+     * API to do self ownership transfer.
+     *
+     *@throws OcException
+     */
+    public static native void doSelfOwnershiptransfer() throws OcException;
 }
index f9cc04f..0ea863f 100644 (file)
@@ -574,6 +574,13 @@ public class OcResource {
     public native String getServerId();
 
     /**
+     * Method to get a string representation of the human friendly name defined by the vendor.
+     *
+     * @return human friendly name
+     */
+    public native String getDeviceName();
+
+    /**
      * An OnGetListener can be registered via the resource get call.
      * Event listeners are notified asynchronously
      */
diff --git a/android/android_api/base/src/main/java/org/iotivity/base/PinType.java b/android/android_api/base/src/main/java/org/iotivity/base/PinType.java
new file mode 100644 (file)
index 0000000..65759fd
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ *******************************************************************
+ *
+ * Copyright 2016 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.
+ *
+ *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.base;
+
+import java.security.InvalidParameterException;
+import java.util.EnumSet;
+
+public enum PinType {
+    NUM_PIN (0x1 << 0),
+    UPPERCASE_CHAR_PIN  (0x1 << 1),
+    LOWERCASE_CHAR_PIN  (0x1 << 2),
+    ;
+
+    private int value;
+
+    private PinType(int value) {
+        this.value = value;
+    }
+
+    public int getValue() {
+        return this.value;
+    }
+
+    public static EnumSet<PinType> convertToEnumSet(int value) {
+        EnumSet<PinType> typeSet = null;
+
+        for (PinType v : values()) {
+            if (0 != (value & v.getValue())) {
+                if (null == typeSet) {
+                    typeSet = EnumSet.of(v);
+                } else {
+                    typeSet.add(v);
+                }
+            }
+        }
+
+        if (null == typeSet || typeSet.isEmpty()) {
+            throw new InvalidParameterException("Unexpected PinType value:" + value);
+        }
+        return typeSet;
+    }
+}
index b41b65c..e02602c 100644 (file)
@@ -24,7 +24,7 @@ package org.iotivity.base;
 
 import android.content.Context;
 import android.app.Activity;
-
+import java.util.EnumSet;
 /**
  * Data structure to provide the configuration.
  */
@@ -38,6 +38,11 @@ public class PlatformConfig {
     private QualityOfService mQualityOfService;
     private String mSvrDbPath; //TODO: Instead of SVRDB file, it should be Persistent Storage.
                               //this is only for 0.9.2
+    private String mSvrDbPathDefault;
+    private String mSvrDbPathRescue;
+    private int mKeySize;
+    private byte[] mKey;
+    private int mTransportType;
     /**
      * @param activity         app activity
      * @param context          app context
@@ -68,8 +73,33 @@ public class PlatformConfig {
         this.mPort = port;
         this.mQualityOfService = qualityOfService;
         this.mSvrDbPath = dbPath;
+        this.mTransportType = 0;
     }
 
+    public PlatformConfig(Context context,
+                          ServiceType serviceType,
+                          ModeType modeType,
+                          String ipAddress,
+                          int port,
+                          QualityOfService qualityOfService,
+                          String dbPath,
+                          String dbPathDefault,
+                          String dbPathRescue,
+                          int keySize,
+                          byte[] key) {
+        this.mContext = context;
+        this.mServiceType = serviceType;
+        this.mModeType = modeType;
+        this.mIpAddress = ipAddress;
+        this.mPort = port;
+        this.mQualityOfService = qualityOfService;
+        this.mSvrDbPath = dbPath;
+        this.mSvrDbPathDefault = dbPathDefault;
+        this.mSvrDbPathRescue = dbPathRescue;
+        this.mKeySize = keySize;
+        this.mKey = key;
+        this.mTransportType = 0;
+    }
     /**
      * @param context          app context
      * @param serviceType      indicate IN_PROC or OUT_OF_PROC
@@ -170,4 +200,32 @@ public class PlatformConfig {
         return mActivity;
     }
 
+    public String getDBDefaultPath() {
+        return mSvrDbPathDefault;
+    }
+
+    public String getDBRescuePath() {
+        return mSvrDbPathRescue;
+    }
+
+    public int getKeySize()
+    {
+        return mKeySize;
+    }
+
+    public byte[] getKey()
+    {
+        return mKey;
+    }
+
+    public void setAvailableTransportType(EnumSet<OcConnectivityType> type) {
+        for (OcConnectivityType connType : OcConnectivityType.values()) {
+            if (type.contains(connType))
+                mTransportType |= connType.getValue();
+        }
+    }
+
+    public int getAvailableTransportType() {
+        return mTransportType;
+    }
 }
index e06d574..5811afd 100644 (file)
@@ -29,12 +29,16 @@ import android.content.IntentFilter;
 
 public class CaBtPairingInterface {
     private static Context mContext;
+    private static volatile boolean isBtInitialized = false;
 
     private CaBtPairingInterface(Context context) {
         synchronized(CaBtPairingInterface.class) {
             mContext = context;
         }
-        registerIntentFilter();
+        if (!isBtInitialized) {
+            registerIntentFilter();
+            isBtInitialized = true;
+        }
     }
 
     private static IntentFilter registerIntentFilter() {
@@ -47,7 +51,10 @@ public class CaBtPairingInterface {
     }
 
     public static void destroyEdrInterface() {
-        mContext.unregisterReceiver(mReceiver);
+        if (isBtInitialized) {
+            mContext.unregisterReceiver(mReceiver);
+            isBtInitialized = false;
+        }
     }
 
     private native static void oicEdrStateChangedCallback(int state);
index aaf8bc6..067dbf3 100644 (file)
@@ -30,12 +30,16 @@ import android.util.Log;
 
 public class CaEdrInterface {
     private static Context mContext;
+    private static volatile boolean isEdrInitialized = false;
 
     private CaEdrInterface(Context context) {
         synchronized(CaEdrInterface.class) {
             mContext = context;
         }
-        registerIntentFilter();
+        if (!isEdrInitialized) {
+            registerIntentFilter();
+            isEdrInitialized = true;
+        }
     }
 
     private static IntentFilter registerIntentFilter() {
@@ -48,7 +52,10 @@ public class CaEdrInterface {
     }
 
     public static void destroyEdrInterface() {
-        mContext.unregisterReceiver(mReceiver);
+        if (isEdrInitialized) {
+            mContext.unregisterReceiver(mReceiver);
+            isEdrInitialized = false;
+        }
     }
 
     // Network Monitor
index 6924eb4..73fec6c 100644 (file)
@@ -28,6 +28,8 @@ import android.bluetooth.BluetoothDevice;
 import org.iotivity.base.OcException;
 import org.iotivity.base.OcConnectivityType;
 
+import java.util.EnumSet;
+
 public class CaInterface {
     static {
         System.loadLibrary("connectivity_abstraction");
@@ -186,17 +188,72 @@ public class CaInterface {
      *  @param intervalTime                  interval time(Seconds).
      *  @param workingCount                  working count with interval time.
      */
-
     public synchronized static void setLeScanIntervalTime(int intervalTime, int workingCount){
         CaInterface.setLeScanIntervalTimeImpl(intervalTime, workingCount);
     }
-
     private static native void setLeScanIntervalTimeImpl(int intervalTime, int workingCount);
 
+    /**
+     *  stop BLE scan.
+     *  if you want to start scan, it can be triggered by setLeScanIntervalTime or
+     *  other request API like findResource.
+     */
+    public synchronized static void stopLeScan(){
+        CaInterface.stopLeScanImpl();
+    }
+    private static native void stopLeScanImpl();
+
+    /**
+     *  start BLE Advertising.
+     */
+    public synchronized static void startLeAdvertising(){
+        CaInterface.startLeAdvertisingImpl();
+    }
+    private static native void startLeAdvertisingImpl();
+
+    /**
+     *  stop BLE Advertising.
+     */
+    public synchronized static void stopLeAdvertising(){
+        CaInterface.stopLeAdvertisingImpl();
+    }
+    private static native void stopLeAdvertisingImpl();
+
+    /**
+     *  set BT configure
+     */
+    public synchronized static void setBTConfigure(int flag){
+        CaInterface.setBTConfigureImpl(flag);
+    }
+    private static native void setBTConfigureImpl(int flag);
 
     public synchronized static int setCipherSuite(OicCipher cipher, OcConnectivityType connType){
         return CaInterface.setCipherSuiteImpl(cipher.getValue(), connType.getValue());
     }
     private static native int setCipherSuiteImpl(int cipher, int adapter);
 
+    /**
+    *  Disconnect TCP session.
+    *  It will disconnect the current TCP session.
+    *
+    *  @param address host address [IP address].
+    *  @param port Port number.
+    *  @param transportFlags Set of Transport flags.
+    *
+    *  @return Result of the API call.
+    *
+    *  @see CaTransportFlags
+    */
+    public synchronized static int disconnectTCPSession(String address, int port,
+                                     EnumSet<CaTransportFlags> transportFlags) {
+        int transPortFlagsInt = 0;
+        for (CaTransportFlags flag : CaTransportFlags.values()) {
+            if (transportFlags.contains(flag)) {
+                transPortFlagsInt |= flag.getValue();
+            }
+        }
+
+        return CaInterface.disconnectTCPSessionImpl(address, port, transPortFlagsInt);
+    }
+    private static native int disconnectTCPSessionImpl(String address, int port, int flags);
 }
index a747953..e2da3ec 100644 (file)
-/******************************************************************\r
- *\r
- * Copyright 2014 Samsung Electronics All Rights Reserved.\r
- *\r
- *\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *      http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- *\r
- ******************************************************************/\r
-\r
-package org.iotivity.ca;\r
-\r
-import android.content.BroadcastReceiver;\r
-import android.content.Context;\r
-import android.content.Intent;\r
-import android.content.IntentFilter;\r
-import android.net.ConnectivityManager;\r
-import android.net.NetworkInfo;\r
-import android.net.wifi.WifiManager;\r
-import android.util.Log;\r
-\r
-public class CaIpInterface {\r
-    private static Context mContext;\r
-\r
-    public enum WifiAPState{\r
-        WIFI_AP_STATE_DISABLING (10),\r
-        WIFI_AP_STATE_DISABLED (11),\r
-        WIFI_AP_STATE_ENABLING (12),\r
-        WIFI_AP_STATE_ENABLED (13),\r
-        WIFI_AP_STATE_FAILED (14)\r
-        ; // semicolon needed when fields / methods follow\r
-\r
-\r
-        private final int apstate;\r
-\r
-        WifiAPState(int apstate)\r
-        {\r
-            this.apstate = apstate;\r
-        }\r
-        public int getIntValue() {\r
-           return this.apstate;\r
-        }\r
-    }\r
-\r
-    private CaIpInterface(Context context) {\r
-        synchronized(CaIpInterface.class) {\r
-            mContext = context;\r
-        }\r
-        registerIpStateReceiver();\r
-    }\r
-\r
-    private void registerIpStateReceiver() {\r
-        IntentFilter intentFilter = new IntentFilter();\r
-        intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);\r
-        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);\r
-        intentFilter.addAction("android.net.wifi.WIFI_AP_STATE_CHANGED");\r
-\r
-        mContext.registerReceiver(mReceiver, intentFilter);\r
-    }\r
-\r
-    public static void destroyIpInterface() {\r
-        mContext.unregisterReceiver(mReceiver);\r
-    }\r
-\r
-    private static BroadcastReceiver mReceiver = new BroadcastReceiver() {\r
-        @Override\r
-        public void onReceive(Context context, Intent intent) {\r
-            if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {\r
-                ConnectivityManager manager = (ConnectivityManager)\r
-                        mContext.getSystemService(Context.CONNECTIVITY_SERVICE);\r
-                NetworkInfo wifiInfo = manager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);\r
-                NetworkInfo mobileInfo = manager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);\r
-\r
-                if (mobileInfo != null && mobileInfo.isConnected() || wifiInfo.isConnected()) {\r
-                    caIpStateEnabled();\r
-                } else {\r
-                    caIpStateDisabled();\r
-                }\r
-            }\r
-\r
-            if (intent.getAction().equals("android.net.wifi.WIFI_AP_STATE_CHANGED")) {\r
-                if (intent.getIntExtra("wifi_state",\r
-                    WifiAPState.WIFI_AP_STATE_DISABLED.getIntValue())\r
-                    == WifiAPState.WIFI_AP_STATE_DISABLED.getIntValue())\r
-                {\r
-                    caIpStateDisabled();\r
-                }else if(intent.getIntExtra("wifi_state",\r
-                    WifiAPState.WIFI_AP_STATE_DISABLED.getIntValue())\r
-                    == WifiAPState.WIFI_AP_STATE_ENABLED.getIntValue())\r
-                {\r
-                    try {\r
-                        Thread.sleep(1000);\r
-                    } catch (InterruptedException e) {\r
-                        // TODO Auto-generated catch block\r
-                        e.printStackTrace();\r
-                    }\r
-                    caIpStateEnabled();\r
-                }\r
-           }\r
-        }\r
-    };\r
-\r
-    private native static void caIpStateEnabled();\r
-\r
-    private native static void caIpStateDisabled();\r
-}\r
+/******************************************************************
+ *
+ * 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.
+ *
+ ******************************************************************/
+
+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;
+import android.util.Log;
+
+public class CaIpInterface {
+    private static Context mContext;
+    private static volatile boolean isIpInitialized = false;
+    private static String TAG          = "OIC_IP_CB_INTERFACE";
+
+    private CaIpInterface(Context context) {
+        synchronized(CaIpInterface.class) {
+            mContext = context;
+        }
+        if (!isIpInitialized) {
+            registerIpStateReceiver();
+            isIpInitialized = true;
+        }
+    }
+
+    private void registerIpStateReceiver() {
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+        intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+
+        mContext.registerReceiver(mReceiver, intentFilter);
+    }
+
+    public static void destroyIpInterface() {
+        if (isIpInitialized) {
+            mContext.unregisterReceiver(mReceiver);
+            isIpInitialized = false;
+        }
+    }
+
+    private static BroadcastReceiver mReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
+                NetworkInfo activeNetwork = ((ConnectivityManager) mContext
+                        .getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
+                if (activeNetwork != null) {
+                    Log.d(TAG, "CONNECTIVITY_ACTION - activeNetwork: "
+                        + activeNetwork.getTypeName()
+                        + " isConnected: " + activeNetwork.isConnected());
+                    caIpStateEnabled();
+                } else {
+                    Log.d(TAG, "CONNECTIVITY_ACTION - activeNetwork: NONE");
+                    caIpStateDisabled();
+                }
+            } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
+                NetworkInfo netInfo = (NetworkInfo) intent
+                        .getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
+                if (ConnectivityManager.TYPE_WIFI == netInfo.getType()) {
+                    NetworkInfo.State netState = netInfo.getState();
+                    if (NetworkInfo.State.CONNECTED == netState) {
+                        Log.d(TAG, "NETWORK_STATE_CHANGED_ACTION - CONNECTED: TYPE_WIFI");
+                        caIpStateEnabled();
+                    } else if (NetworkInfo.State.DISCONNECTED == netState) {
+                        Log.d(TAG, "NETWORK_STATE_CHANGED_ACTION - DISCONNECTED: TYPE_WIFI");
+                    }
+                }
+            }
+        }
+    };
+
+    private native static void caIpStateEnabled();
+
+    private native static void caIpStateDisabled();
+}
index 695359b..fc1db0d 100644 (file)
@@ -38,25 +38,47 @@ import android.content.Intent;
 import android.content.IntentFilter;
 import android.util.Log;
 
+// For using bluetooth.le APIs
+import android.bluetooth.le.BluetoothLeScanner;
+import android.bluetooth.le.ScanCallback;
+import android.bluetooth.le.ScanFilter;
+import android.bluetooth.le.ScanResult;
+import android.bluetooth.le.ScanSettings;
+import android.os.ParcelUuid;
+import java.util.Iterator;
+import android.os.Build;
+
 public class CaLeClientInterface {
 
     private static String SERVICE_UUID = "ADE3D529-C784-4F63-A987-EB69F70EE816";
     private static String TAG          = "OIC_LE_CB_INTERFACE";
     private static Context mContext;
+    private static volatile boolean isLeClientInitialized = false;
+
+    //For custom uuid ble server
+    final static String CUSTOM_UUID   = "75004209-0000-0000-0000-000000000000";
+    final static String CUSTOM_UUID2  = "75004204-0000-0000-0000-000000000000";
+    final static int custom_uuid_len1 = 9;
+    final static int custom_uuid_strlen1 = 4;
 
     private CaLeClientInterface(Context context) {
-        caLeRegisterLeScanCallback(mLeScanCallback);
+        getLeScanCallback();
         caLeRegisterGattCallback(mGattCallback);
         synchronized(CaLeClientInterface.class) {
             mContext = context;
         }
-        registerIntentFilter();
+        if (!isLeClientInitialized) {
+            registerIntentFilter();
+            isLeClientInitialized = true;
+        }
     }
 
-
-
     public static void getLeScanCallback() {
-        caLeRegisterLeScanCallback(mLeScanCallback);
+//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+//            caLeRegisterLeScanCallbackForV21(mLeScanCallbackForV21);
+//        } else {
+            caLeRegisterLeScanCallback(mLeScanCallback);
+//        }
     }
 
     public static void getLeGattCallback() {
@@ -72,16 +94,36 @@ public class CaLeClientInterface {
     }
 
     public static void destroyLeInterface() {
-        mContext.unregisterReceiver(mReceiver);
+        if (isLeClientInitialized) {
+            mContext.unregisterReceiver(mReceiver);
+            isLeClientInitialized = false;
+        }
+    }
+
+    public static BluetoothGatt connectGattforHidden(BluetoothDevice device,
+            String address, boolean autoConnect) {
+        if (isLeClientInitialized) {
+            BluetoothAdapter mbluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+            BluetoothDevice mDevice = mbluetoothAdapter.getRemoteDevice(address);
+            Log.d(TAG, "connectGattforHidden method : getAddress : " + mDevice.getAddress() 
+                    + ", autoconnect : " + autoConnect);
+            return mDevice.connectGatt(mContext, autoConnect, mGattCallback);
+        }
+        return null;
     }
 
     private native static void caLeRegisterLeScanCallback(BluetoothAdapter.LeScanCallback callback);
 
+    private native static void caLeRegisterLeScanCallbackForV21(ScanCallback callback);
+
     private native static void caLeRegisterGattCallback(BluetoothGattCallback callback);
 
     // BluetoothAdapter.LeScanCallback
     private native static void caLeScanCallback(BluetoothDevice device);
 
+    // scan failed callback for ca layer
+    private native static void caLeScanFailedCallback(int errorCode);
+
     // BluetoothGattCallback
     private native static void caLeGattConnectionStateChangeCallback(
             BluetoothGatt gatt, int status, int newState);
@@ -132,36 +174,70 @@ public class CaLeClientInterface {
     private native static void caManagerLeRemoteRssiCallback(BluetoothGatt gatt, int rssi,
                                                              int status);
 
-    // Callback
+    private native static void caLeGattMtuChangedCallback(BluetoothGatt gatt, int mtu,
+                                                          int status);
+
+    // Le Scan Callback which lower than API 21
     private static BluetoothAdapter.LeScanCallback mLeScanCallback =
                    new BluetoothAdapter.LeScanCallback() {
 
         @Override
         public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
+            filteringScanResult(device, scanRecord);
+        }
+    };
 
-            try {
-                List<UUID> uuids = getUuids(scanRecord);
-                for (UUID uuid : uuids) {
-                    Log.d(TAG, "UUID : " + uuid.toString());
-                    if(uuid.toString().contains(SERVICE_UUID.toLowerCase())) {
-                        Log.d(TAG, "we found that has the Device");
-                        Log.d(TAG, "scanned device address : " + device.getAddress());
-                        caLeScanCallback(device);
-                    }
-                }
-            } catch(UnsatisfiedLinkError e) {
+    // Le Scan Callback which upper than API 21
+    private static ScanCallback mLeScanCallbackForV21 = new ScanCallback() {
+        @Override
+        public void onScanResult(int callbackType, ScanResult result) {
+            super.onScanResult(callbackType, result);
+            Log.d(TAG, "onScanResult from ScanCallback");
+            filteringScanResult(result.getDevice(), result.getScanRecord().getBytes());
+        }
 
+        @Override
+        public void onBatchScanResults(List<ScanResult> results) {
+            super.onBatchScanResults(results);
+            Iterator<ScanResult> itr = results.iterator();
+            while (itr.hasNext()) {
+                filteringScanResult(itr.next().getDevice(),
+                        itr.next().getScanRecord().getBytes());
             }
         }
+
+        @Override
+        public void onScanFailed(int errorCode) {
+            super.onScanFailed(errorCode);
+            caLeScanFailedCallback(errorCode);
+        }
     };
 
+    private static void filteringScanResult(BluetoothDevice device, byte[] scanRecord) {
+        try {
+            List<UUID> uuids = getUuids(scanRecord);
+            for (UUID uuid : uuids) {
+                if(uuid.toString().contains(SERVICE_UUID.toLowerCase())) {
+                    caLeScanCallback(device);
+                } else if(uuid.toString().contains(CUSTOM_UUID.toLowerCase()) ||
+                         uuid.toString().contains(CUSTOM_UUID2.toLowerCase())) {
+                    Log.d(TAG, "we found that has the Device [" + device.getAddress() +
+                               "] which has custom adv");
+                    caLeScanCallback(device);
+                }
+            }
+        } catch(UnsatisfiedLinkError e) {
+            e.printStackTrace();
+        }
+    }
+
     private static List<UUID> getUuids(final byte[] scanRecord) {
         List<UUID> uuids = new ArrayList<UUID>();
 
         int offset = 0;
         while (offset < (scanRecord.length - 2)) {
             int len = scanRecord[offset++];
-            if (len == 0)
+            if (len <= 0)
                 break;
 
             int type = scanRecord[offset++];
@@ -196,7 +272,28 @@ public class CaLeClientInterface {
                 }
                 break;
             default:
-                offset += (len - 1);
+                if (len >= custom_uuid_len1) {
+                    StringBuffer strbuf1 = new StringBuffer();
+                    int strcnt = 0;
+                    int backlen = len;
+                    while (backlen > 1) {
+                        String str = String.format("%02x", scanRecord[offset++]);
+                        backlen -= 1;
+                        if (strcnt < custom_uuid_strlen1) {
+                            strbuf1.append(str);
+                        }
+                        else {
+                            break;
+                        }
+                        strcnt++;
+                    }
+                    offset += (backlen - 1);
+                    uuids.add(UUID.fromString(String.format(
+                            "%4s-0000-0000-0000-000000000000",
+                            strbuf1.toString())));
+                } else {
+                    offset += (len - 1);
+                }
                 break;
             }
         }
@@ -270,6 +367,12 @@ public class CaLeClientInterface {
             super.onReadRemoteRssi(gatt, rssi, status);
             caManagerLeRemoteRssiCallback(gatt, rssi, status);
         }
+
+        @Override
+        public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
+            super.onMtuChanged(gatt, mtu, status);
+            caLeGattMtuChangedCallback(gatt, mtu, status);
+        }
     };
 
     private static final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@@ -312,4 +415,3 @@ public class CaLeClientInterface {
     };
 }
 
-
index 0a4bb5c..fa71719 100644 (file)
@@ -62,11 +62,13 @@ public class CaLeServerInterface {
             BluetoothDevice device, byte[] data);
 
     private native static void caLeGattServerCharacteristicWriteRequestCallback(
-            BluetoothDevice device, byte[] data);
+            BluetoothDevice device, byte[] data, int id, int offset, byte[] value);
 
     private native static void caLeGattServerNotificationSentCallback(BluetoothDevice device,
                                                                      int status);
 
+    private native static void caLeGattServerMtuChangedCallback(BluetoothDevice gatt, int mtu);
+
     // AdvertiseCallback
     private native static void caLeAdvertiseStartSuccessCallback(
             AdvertiseSettings settingsInEffect);
@@ -108,7 +110,8 @@ public class CaLeServerInterface {
             super.onCharacteristicWriteRequest(device, requestId, characteristic,
                     preparedWrite, responseNeeded, offset, value);
 
-            caLeGattServerCharacteristicWriteRequestCallback(device, value);
+            caLeGattServerCharacteristicWriteRequestCallback(device, value, requestId,
+                                                             offset, value);
         }
 
         @Override
@@ -138,6 +141,13 @@ public class CaLeServerInterface {
 
             caLeGattServerNotificationSentCallback(device, status);
         }
+
+        @Override
+        public void onMtuChanged(BluetoothDevice device, int mtu) {
+            super.onMtuChanged(device, mtu);
+
+            caLeGattServerMtuChangedCallback(device, mtu);
+        }
     };
 
     private static final AdvertiseCallback mAdvertiseCallback = new AdvertiseCallback() {
diff --git a/android/android_api/base/src/main/java/org/iotivity/ca/CaTransportFlags.java b/android/android_api/base/src/main/java/org/iotivity/ca/CaTransportFlags.java
new file mode 100644 (file)
index 0000000..468b344
--- /dev/null
@@ -0,0 +1,79 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ ******************************************************************/
+
+package org.iotivity.ca;
+
+import java.util.EnumSet;
+import java.security.InvalidParameterException;
+
+public enum CaTransportFlags {
+
+    CA_DEFAULT_FLAGS(0),
+
+    /** Insecure transport is the default (subject to change) */
+    CA_SECURE (1 << 4),   // secure the transport path
+
+    /** IPv4 & IPv6 autoselection is the default */
+    CA_IPV6 (1 << 5),   // IP adapter only
+    CA_IPV4 (1 << 6),   // IP adapter only
+
+    /** Indication that a message was received by multicast. */
+    CA_MULTICAST (1 << 7),
+
+    /** Link-Local multicast is the default multicast scope for IPv6.
+     *These correspond in both value and position to the IPv6 address bits. */
+    CA_SCOPE_INTERFACE (0x1), // IPv6 Interface-Local scope
+    CA_SCOPE_LINK (0x2), // IPv6 Link-Local scope (default)
+    CA_SCOPE_REALM (0x3), // IPv6 Realm-Local scope
+    CA_SCOPE_ADMIN (0x4), // IPv6 Admin-Local scope
+    CA_SCOPE_SITE (0x5), // IPv6 Site-Local scope
+    CA_SCOPE_ORG (0x8), // IPv6 Organization-Local scope
+    CA_SCOPE_GLOBAL (0xE), // IPv6 Global scope
+    ;
+    private int value;
+
+    private CaTransportFlags(int value) {
+        this.value = value;
+    }
+
+    public int getValue() {
+        return this.value;
+    }
+
+    public static EnumSet<CaTransportFlags> convertToEnumSet(int value) {
+
+        EnumSet<CaTransportFlags> typeSet = null;
+        for (CaTransportFlags v : values()) {
+            if (0 != (value & v.getValue())) {
+                if (null == typeSet) {
+                    typeSet = EnumSet.of(v);
+                } else {
+                    typeSet.add(v);
+                }
+            }
+        }
+
+        if (null == typeSet || typeSet.isEmpty()) {
+            throw new InvalidParameterException("Unexpected CaTransportFlag value:" + value);
+        }
+
+        return typeSet;
+    }
+}
index 60f9f16..030217f 100644 (file)
@@ -1,38 +1,45 @@
-/* ****************************************************************\r
- *\r
- * Copyright 2016 Samsung Electronics All Rights Reserved.\r
- *\r
- *\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *      http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- *\r
- ******************************************************************/\r
-\r
-package org.iotivity.ca;\r
-\r
-public enum OicCipher {\r
-    TLS_ECDH_anon_WITH_AES_128_CBC_SHA(0xC018),\r
-    TLS_PSK_WITH_AES_128_CCM_8(0xC0A8),\r
-    TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8(0xC0AE),\r
-    TLS_RSA_WITH_AES_256_CBC_SHA(0x35);\r
-\r
-    private int cipher;\r
-\r
-    private OicCipher(int cipher) {\r
-        this.cipher = cipher;\r
-    }\r
-\r
-    public int getValue(){\r
-        return cipher;\r
-    }\r
-}\r
+/* ****************************************************************
+ *
+ * Copyright 2016 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.
+ *
+ ******************************************************************/
+
+package org.iotivity.ca;
+
+public enum OicCipher {
+    TLS_RSA_WITH_AES_256_CBC_SHA256(0x3D),
+    TLS_RSA_WITH_AES_128_GCM_SHA256(0x009C),
+    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256(0xC02B),
+    TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8(0xC0AE),
+    TLS_ECDHE_ECDSA_WITH_AES_128_CCM(0xC0AC),
+    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256(0xC023),
+    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384(0xC024),
+    TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384(0xC02C),
+    TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256(0xC037),
+    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256(0xC027),
+    TLS_ECDH_anon_WITH_AES_128_CBC_SHA(0xC018);
+
+    private int cipher;
+
+    private OicCipher(int cipher) {
+        this.cipher = cipher;
+    }
+
+    public int getValue(){
+        return cipher;
+    }
+}
index 93a375b..1ab6976 100644 (file)
@@ -1,7 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="org.iotivity.base.examples.provisioningclient" >
-
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <application
         android:allowBackup="true"
         android:icon="@mipmap/ic_launcher"
diff --git a/android/examples/provisioningclient/src/main/assets/oic_svr_db_client_default.dat b/android/examples/provisioningclient/src/main/assets/oic_svr_db_client_default.dat
new file mode 100644 (file)
index 0000000..f3cf369
Binary files /dev/null and b/android/examples/provisioningclient/src/main/assets/oic_svr_db_client_default.dat differ
diff --git a/android/examples/provisioningclient/src/main/assets/oic_svr_db_client_enc.dat b/android/examples/provisioningclient/src/main/assets/oic_svr_db_client_enc.dat
new file mode 100644 (file)
index 0000000..f3cf369
Binary files /dev/null and b/android/examples/provisioningclient/src/main/assets/oic_svr_db_client_enc.dat differ
diff --git a/android/examples/provisioningclient/src/main/assets/oic_svr_db_client_plain.dat b/android/examples/provisioningclient/src/main/assets/oic_svr_db_client_plain.dat
new file mode 100644 (file)
index 0000000..f3cf369
Binary files /dev/null and b/android/examples/provisioningclient/src/main/assets/oic_svr_db_client_plain.dat differ
diff --git a/android/examples/provisioningclient/src/main/assets/oic_svr_db_client_rescue.dat b/android/examples/provisioningclient/src/main/assets/oic_svr_db_client_rescue.dat
new file mode 100644 (file)
index 0000000..f3cf369
Binary files /dev/null and b/android/examples/provisioningclient/src/main/assets/oic_svr_db_client_rescue.dat differ
index 820eddf..0686000 100644 (file)
@@ -1,6 +1,8 @@
 package org.iotivity.base.examples.provisioningclient;
 
 import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -14,6 +16,10 @@ import android.util.Log;
 import android.view.Gravity;
 import android.widget.LinearLayout;
 import android.widget.TextView;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.os.Environment;
+import android.widget.Toast;
 
 import org.iotivity.base.CredType;
 import org.iotivity.base.EncodingType;
@@ -23,6 +29,7 @@ import org.iotivity.base.ModeType;
 import org.iotivity.base.OcException;
 import org.iotivity.base.OcPlatform;
 import org.iotivity.base.OcProvisioning;
+import org.iotivity.base.MVJustWorksOptionMask;
 import org.iotivity.base.OcSecureResource;
 import org.iotivity.base.OicSecAcl;
 import org.iotivity.base.OicSecAce;
@@ -38,6 +45,7 @@ import org.iotivity.base.ServiceType;
 
 import java.io.File;
 import java.io.FileNotFoundException;
+import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -45,6 +53,7 @@ import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.EnumSet;
 import java.util.List;
+import java.nio.channels.FileChannel;
 
 import org.iotivity.ca.OicCipher;
 import org.iotivity.base.OcConnectivityType;
@@ -57,6 +66,8 @@ OcSecureResource.DoOwnershipTransferListener, OcSecureResource.ProvisionPairwise
     private static final String TAG = "Provisioning Client: ";
     private static final int BUFFER_SIZE = 1024;
     private int credId=0;
+    private int verifyVal=1;
+    private String verifyNumber;
     int unownedDevCount = StringConstants.NUMBER_ZERO;
     OcProvisioning.PinCallbackListener pinCallbackListener =
         new OcProvisioning.PinCallbackListener() {
@@ -93,6 +104,72 @@ OcSecureResource.DoOwnershipTransferListener, OcSecureResource.ProvisionPairwise
                 }
         };
 
+    OcProvisioning.DisplayNumListener displayNumListener = new OcProvisioning.DisplayNumListener() {
+        @Override
+            public int displayNumListener(String verifyNum) {
+                Log.d(TAG, "Inside verifySecretListener ");
+                logMessage(TAG + "DisplayMutualVerifyNumListener verify Number = " + verifyNum);
+                verifyNumber = verifyNum;
+                return 0;
+            }
+    };
+
+    OcProvisioning.ConfirmNumListener confirmNumListener = new OcProvisioning.ConfirmNumListener() {
+        @Override
+        public int confirmNumListener() {
+            Log.d(TAG, "Inside confirmMutualVerifyNumListener ");
+            final String message = "Is number matches with " + verifyNumber;
+            final Object lock = new Object();
+            runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+
+                    AlertDialog.Builder alertDialog = new AlertDialog.Builder(ProvisioningClient.this);
+                    alertDialog.setTitle("Confirm Number");
+                    alertDialog.setMessage(message);
+                    alertDialog.setCancelable(false);
+                    alertDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
+                        @Override
+                        public void onClick(DialogInterface dialog, int which) {
+                            dialog.dismiss();
+                            try {
+                                synchronized (lock) {
+                                    verifyVal = 0;
+                                    lock.notifyAll();
+                                }
+                            } catch (Exception e) {
+                                Log.d(TAG, e + "");
+                            }
+                        }
+                    });
+                    alertDialog.setNegativeButton("No", new DialogInterface.OnClickListener() {
+                        @Override
+                        public void onClick(DialogInterface dialog, int which) {
+                            dialog.dismiss();
+                            try {
+                                synchronized (lock) {
+                                    lock.notifyAll();
+                                }
+                            } catch (Exception e) {
+                                Log.d(TAG, e + "");
+                            }
+                        }
+                    }).show();
+                }
+            });
+            synchronized (lock) {
+                try {
+                    lock.wait();
+                } catch (InterruptedException e) {
+                    Log.d(TAG, e + "");
+                }
+            }
+            Log.d(TAG, "VerifyVal after submit =" + verifyVal);
+            logMessage(TAG + " confirmMutualVerifyNumListener " + verifyVal);
+            return verifyVal;
+        }
+    };
+
     OcSecureResource.ProvisionAclListener provisionAclListener =
         new OcSecureResource.ProvisionAclListener() {
             @Override
@@ -180,7 +257,9 @@ OcSecureResource.DoOwnershipTransferListener, OcSecureResource.ProvisionPairwise
             SharedPreferences wmbPreference = PreferenceManager.getDefaultSharedPreferences(this);
             boolean isFirstRun = wmbPreference.getBoolean("FIRSTRUN", true);
             if (isFirstRun) {
-                copyCborFromAsset();
+                copyCborFromAsset(StringConstants.OIC_CLIENT_CBOR_DB_FILE_PLAIN);
+                copyCborFromAsset(StringConstants.OIC_CLIENT_CBOR_DB_FILE_ENC);
+                copyCborFromAsset(StringConstants.OIC_CLIENT_CBOR_DB_FILE_RESCUE);
                 SharedPreferences.Editor editor = wmbPreference.edit();
                 editor.putBoolean("FIRSTRUN", false);
                 editor.commit();
@@ -196,6 +275,11 @@ OcSecureResource.DoOwnershipTransferListener, OcSecureResource.ProvisionPairwise
      * configure OIC platform and call findResource
      */
     private void initOICStack() {
+        byte [] key = {(byte)0xa5, (byte)0x84, (byte)0x99, (byte)0x8d, (byte)0x0d, (byte)0xbd, (byte)0xb1, (byte)0x54,
+            (byte)0xbb, (byte)0xc5, (byte)0x4f, (byte)0xed, (byte)0x86, (byte)0x9a, (byte)0x66, (byte)0x11,
+            (byte)0xa5, (byte)0x84, (byte)0x99, (byte)0x8d, (byte)0x0d, (byte)0xbd, (byte)0xb1, (byte)0x54,
+            (byte)0xbb, (byte)0xc5, (byte)0x4f, (byte)0xed, (byte)0x86, (byte)0x9a, (byte)0x66, (byte)0x11
+        };
         //create platform config
         PlatformConfig cfg = new PlatformConfig(
                 this,
@@ -203,22 +287,27 @@ OcSecureResource.DoOwnershipTransferListener, OcSecureResource.ProvisionPairwise
                 ModeType.CLIENT_SERVER,
                 "0.0.0.0", // bind to all available interfaces
                 0,
-                QualityOfService.LOW, filePath + StringConstants.OIC_CLIENT_CBOR_DB_FILE);
+                QualityOfService.LOW, filePath + StringConstants.OIC_CLIENT_CBOR_DB_FILE_PLAIN,
+                filePath + StringConstants.OIC_CLIENT_CBOR_DB_FILE_ENC,
+                filePath + StringConstants.OIC_CLIENT_CBOR_DB_FILE_RESCUE, 256, key);
         OcPlatform.Configure(cfg);
 
         //Get deviceId
-        byte [] deviceIdBytes= OcPlatform.getDeviceId();
-        String devId = new String(deviceIdBytes);
-        Log.d(TAG, "Get Device Id "+devId);
+        /*byte [] deviceIdBytes= OcPlatform.getDeviceId();
+          String devId = new String(deviceIdBytes);
+          Log.d(TAG, "Get Device Id "+devId);
         //Set deviceId
         try {
-            String setId = "adminDeviceUuid1";
-            OcPlatform.setDeviceId(setId.getBytes());
-            Log.d(TAG, "Set Device Id done");
+        String setId = "adminDeviceUuid1";
+        OcPlatform.setDeviceId(setId.getBytes());
+        Log.d(TAG, "Set Device Id done");
+        setId = "adminDeviceUuid0";
+        OcPlatform.setDeviceId(setId.getBytes());
+        Log.d(TAG, "Set Device Id Reverted");
         }
         catch (OcException e) {
-            Log.d(TAG, e.getMessage());
-        }
+        Log.d(TAG, e.getMessage());
+        }*/
 
         try {
             /*
@@ -234,6 +323,15 @@ OcSecureResource.DoOwnershipTransferListener, OcSecureResource.ProvisionPairwise
             }
             Log.d(TAG, "Sql db directory exists at " + sqlDbPath);
             OcProvisioning.provisionInit(sqlDbPath + StringConstants.OIC_SQL_DB_FILE);
+
+            try {
+                OcProvisioning.setMVJustWorksOptions(EnumSet.of(MVJustWorksOptionMask.DISPLAY_MUTUAL_VERIF_NUM,
+                            MVJustWorksOptionMask.CONFIRM_MUTUAL_VERIF_NUM));
+                OcProvisioning.setDisplayNumListener(displayNumListener);
+                OcProvisioning.setConfirmNumListener(confirmNumListener);
+            } catch (OcException e) {
+                e.printStackTrace();
+            }
         } catch (OcException e) {
             logMessage(TAG + "provisionInit error: " + e.getMessage());
             Log.e(TAG, e.getMessage());
@@ -412,19 +510,19 @@ OcSecureResource.DoOwnershipTransferListener, OcSecureResource.ProvisionPairwise
     /**
      * Copy svr db CBOR dat file from assets folder to app data files dir
      */
-    private void copyCborFromAsset() {
+    private void copyCborFromAsset(String filep) {
         InputStream inputStream = null;
         OutputStream outputStream = null;
         int length;
         byte[] buffer = new byte[BUFFER_SIZE];
         try {
-            inputStream = getAssets().open(StringConstants.OIC_CLIENT_CBOR_DB_FILE);
+            inputStream = getAssets().open(filep);
             File file = new File(filePath);
             //check files directory exists
             if (!(file.exists() && file.isDirectory())) {
                 file.mkdirs();
             }
-            outputStream = new FileOutputStream(filePath + StringConstants.OIC_CLIENT_CBOR_DB_FILE);
+            outputStream = new FileOutputStream(filePath + filep);
             while ((length = inputStream.read(buffer)) != -1) {
                 outputStream.write(buffer, 0, length);
             }
@@ -435,7 +533,7 @@ OcSecureResource.DoOwnershipTransferListener, OcSecureResource.ProvisionPairwise
             logMessage(TAG + "CBOR svr db file not found " + e.getMessage());
             Log.e(TAG, e.getMessage());
         } catch (IOException e) {
-            logMessage(TAG + StringConstants.OIC_CLIENT_CBOR_DB_FILE + " file copy failed");
+            logMessage(TAG + filep + " file copy failed");
             Log.e(TAG, e.getMessage());
         } finally {
             if (inputStream != null) {
@@ -796,6 +894,45 @@ OcSecureResource.DoOwnershipTransferListener, OcSecureResource.ProvisionPairwise
             }
     }
 
+    @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_secure_provision_client, menu);
+            return true;
+        }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        int id = item.getItemId();
+
+
+        if (id == R.id.export_dat) {
+            try {
+                File sd = Environment.getExternalStorageDirectory();
+                File data = Environment.getDataDirectory();
+                if (sd.canWrite()) {
+                    String currentDBPath = "/data/data/" + getPackageName() + "/files/" + StringConstants.OIC_CLIENT_CBOR_DB_FILE_ENC;
+
+                    File currentDB = new File(currentDBPath);
+                    File backupDB = new File(sd, StringConstants.OIC_CLIENT_CBOR_DB_FILE_ENC);
+                    if (currentDB.exists()) {
+                        FileChannel src = new FileInputStream(currentDB).getChannel();
+                        FileChannel dst = new FileOutputStream(backupDB).getChannel();
+                        dst.transferFrom(src, 0, src.size());
+                        src.close();
+                        dst.close();
+                    }
+                }
+            } catch (Exception e) {
+                Toast.makeText(ProvisioningClient.this, e.getMessage(), Toast.LENGTH_SHORT).show();
+            }
+
+            Toast.makeText(ProvisioningClient.this, StringConstants.OIC_CLIENT_CBOR_DB_FILE_ENC + " File export to sdcard", Toast.LENGTH_SHORT).show();
+            return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
     /**
      * to display on Server Message on Client screen
      */
index 2ae1017..defe108 100644 (file)
@@ -29,8 +29,10 @@ public interface StringConstants {
     public static final String DEFAULT_RECURRENCES_2 =  "Weekly";
     public static final String DEFAULT_PERIOD =  "12-12-16";
     public static final int DEFAULT_PERMISSION = 31;
-    public static final String OIC_CLIENT_CBOR_DB_FILE =  "oic_svr_db_client.dat";
-       public static final String CRT_FILE =  "rootca.crt";
+    public static final String OIC_CLIENT_CBOR_DB_FILE_PLAIN =  "oic_svr_db_client_plain.dat";
+    public static final String OIC_CLIENT_CBOR_DB_FILE_ENC =  "oic_svr_db_client_enc.dat";
+    public static final String OIC_CLIENT_CBOR_DB_FILE_RESCUE =  "oic_svr_db_client_rescue.dat";
+    public static final String CRT_FILE =  "rootca.crt";
     public static final String MESSAGE = "message";
     public static final String OIC_SQL_DB_FILE =  "Pdm.db";
     public static final int  CREDENTIAL_TYPE=1;
index dd57e4d..1a6a274 100644 (file)
@@ -1,5 +1,7 @@
 <menu xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:tools="http://schemas.android.com/tools" tools:context=".SecureProvisionClientActivity">
-    <item android:id="@+id/action_settings" android:title="@string/action_settings"
-        android:orderInCategory="100" android:showAsAction="never" />
+    xmlns:tools="http://schemas.android.com/tools" tools:context=".ProvisioningClient">
+    <item android:id="@+id/export_dat"
+        android:orderInCategory="100"
+        android:showAsAction="never"
+        android:title="Export dat"/>
 </menu>
old mode 100755 (executable)
new mode 100644 (file)
index 200aca6..54e157b 100644 (file)
@@ -6,6 +6,7 @@
         android:name="android.hardware.bluetooth_le"
         android:required="true" />
 
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
     <uses-permission android:name="android.permission.BLUETOOTH" />
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
     <uses-permission android:name="android.permission.INTERNET" />
index 1d21865..21e727e 100644 (file)
@@ -266,6 +266,7 @@ public class BluetoothFragment extends Fragment implements
                 sb.append("Set Connect with : ");
                 try {
                     final String address = mBluetoothDevices.get(pos).getAddress();
+                    Common.setLeAddress(address);
                     CaInterface.setAutoConnectionDevice(address);
                     OcPlatform.OnResourceFoundListener resourceFoundListener =
                             new OcPlatform.OnResourceFoundListener() {
index 4eef8a1..8382e4b 100644 (file)
@@ -24,6 +24,7 @@ package org.iotivity.base.examples;
 
 import android.content.Context;
 import android.widget.Toast;
+import android.util.Log;
 
 import org.iotivity.base.OcPlatform;
 import org.iotivity.base.ResourceProperty;
@@ -39,6 +40,7 @@ import java.util.Locale;
  */
 public class Common {
 
+    private static final String TAG               = "OIC_SIMPLE_COMMON";
     public static final int    DATA_SIZE          = 3000;
     public static String       HOST               = "coap+tcp://192.168.0.1:5683";
     public static final String COAP_TCP           = "coap+tcp://";
@@ -63,6 +65,8 @@ public class Common {
     public final static String MQ_DEFAULT_TOPIC_URI = "/oic/ps/cleanroom";
     public final static String MQ_BROKER_URI = "/oic/ps";
 
+    private static String mLeAddress = null;
+
     public static String getDateCurrentTimeZone() {
         StringBuilder sb = new StringBuilder();
         try {
@@ -82,5 +86,17 @@ public class Common {
     public static void showToast(Context context, String msg) {
         Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
     }
+
+    public static void setLeAddress(String address)
+    {
+        Log.i(TAG, "setLeAddress : " + address.toString());
+        mLeAddress = address;
+    }
+
+    public static String getLeAddress()
+    {
+        Log.i(TAG, "getLeAddress : " + mLeAddress);
+        return mLeAddress;
+    }
 }
 
index 6778978..403a9f1 100644 (file)
@@ -91,6 +91,7 @@ public class DrawerFragment extends Fragment {
                         getString(R.string.title_message),
                         getString(R.string.title_bluetooth),
                         getString(R.string.title_cloud),
+                        getString(R.string.title_keepalive),
                         getString(R.string.title_template), }));
         mDrawerListView.setItemChecked(mCurrentSelectedPosition, true);
 
diff --git a/android/examples/simplebase/src/main/java/org/iotivity/base/examples/KeepAliveFragment.java b/android/examples/simplebase/src/main/java/org/iotivity/base/examples/KeepAliveFragment.java
new file mode 100644 (file)
index 0000000..f26a8b9
--- /dev/null
@@ -0,0 +1,480 @@
+/*
+ * ******************************************************************
+ *
+ * Copyright 2017 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.
+ *
+ * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.base.examples;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.PowerManager;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.TextView;
+
+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 org.iotivity.ca.CaInterface;
+
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This class is for Keep Alive between the client and server (or Cloud).
+ * It can handle Keep Alive mechanism manually.
+ */
+public class KeepAliveFragment extends Fragment implements
+        OcResource.OnGetListener, CaInterface.OnConnectionManagerStateListener {
+
+    private static final String TAG = "OIC_SIMPLE_KEEPALIVE";
+    private final String EOL = System.getProperties().getProperty("line.separator");
+    private final long MILLI_PER_SEC = 1000;
+    private final long ONE_MINUTE = 60 * MILLI_PER_SEC;
+    private final long MARGIN_SEC = 10;
+    private final int KEEPALIVE_MSG = 1;
+    private final int TIMER_MSG = 2;
+    private final int OC_STACK_OK = 0;
+    private final int OC_STACK_RESOURCE_CHANGED = 4;
+
+    private Activity mActivity;
+    private Context mContext;
+    private PowerManager.WakeLock mWakeLock;
+
+    private TextView mIntervalView;
+    private TextView mRemainView;
+    private TextView mStatusView;
+
+    private TextView mActionLog;
+    private TextView mResultLog;
+
+    private Button mDiscoveryButton;
+    private Button mFindButton;
+    private Button mSendButton;
+
+    private boolean isShowTimer = true;
+
+    private long mStartTime = 0;
+    private long mEndTime = 0;
+    private long mRemainTime = -1;
+
+    private int mInterval[] = {2, 4, 8};
+    private int mIndex = 0;
+
+    private String mHost = null;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mActivity = getActivity();
+        mContext = mActivity.getBaseContext();
+
+        initOcPlatform(ModeType.CLIENT);
+        CaInterface.startManagerService(mContext, this);
+
+        PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        CaInterface.stopManagerService();
+    }
+
+
+    // [[ Discovery
+    View.OnClickListener discoveryButtonListener() {
+        return new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                Log.i(TAG, "discoveryButtonListener");
+
+                try {
+                    OcPlatform.findResource("",
+                            OcPlatform.WELL_KNOWN_QUERY,
+                            EnumSet.of(OcConnectivityType.CT_ADAPTER_IP),
+                            resourceFoundListener, QualityOfService.LOW);
+                } catch (OcException e) {
+                    e.printStackTrace();
+                }
+
+                mActivity.runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        mActionLog.setText("[Action Log]" + EOL);
+                        mActionLog.append("Discovery Click" + EOL);
+
+                        mResultLog.setText("[Result Log]" + EOL);
+                        mResultLog.append("Start Time : ");
+                        mResultLog.append(Common.getDateCurrentTimeZone() + EOL);
+                        mStartTime = System.currentTimeMillis();
+
+                        resetInterval();
+                    }
+                });
+            }
+        };
+    }
+
+    OcPlatform.OnResourceFoundListener resourceFoundListener =
+            new OcPlatform.OnResourceFoundListener() {
+                @Override
+                public void onResourceFound(OcResource ocResource) {
+                    synchronized (mActivity) {
+                        final String resourceUri = ocResource.getUri();
+                        Log.i(TAG, "onResourceFound : " + resourceUri);
+
+                        if (resourceUri.contains(Common.RESOURCE_URI)
+                                && ocResource.getConnectivityTypeSet().contains(OcConnectivityType.CT_ADAPTER_TCP)) {
+
+                            mHost = ocResource.getHost();
+                            mActivity.runOnUiThread(new Runnable() {
+                                @Override
+                                public void run() {
+                                    mEndTime = System.currentTimeMillis();
+                                    double flightTime = (double) (mEndTime - mStartTime) / MILLI_PER_SEC;
+                                    mResultLog.append("Discovery Time : "
+                                            + String.format("%.3f", flightTime) + "sec" + EOL);
+                                }
+                            });
+
+                            sendGetToFoundResource(ocResource);
+                        }
+                    }
+                }
+
+                @Override
+                public void onFindResourceFailed(Throwable throwable, String uri) {
+                    synchronized (mActivity) {
+                        Log.i(TAG, "findResource request has failed");
+                        Log.e(TAG, throwable.toString());
+                    }
+                }
+            };
+    // ]] Discovery
+
+
+    // [[ Find KeepAlive Resource
+    View.OnClickListener findButtonListener() {
+        return new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                Log.i(TAG, "findButtonListener");
+
+                try {
+                    OcPlatform.findKeepAliveResource(mHost, pingResourceFoundListener);
+                } catch (OcException e) {
+                    e.printStackTrace();
+                }
+
+                mActivity.runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        mActionLog.setText("[Action Log]" + EOL);
+                        mActionLog.append("Find Ping" + EOL);
+
+                        resetInterval();
+                    }
+                });
+            }
+        };
+    }
+
+    OcPlatform.KeepAliveListener pingResourceFoundListener =
+            new OcPlatform.KeepAliveListener() {
+                @Override
+                public void onKeepAliveListener(OcRepresentation ocRepresentation,
+                                                final int result) {
+                    synchronized (mActivity) {
+                        Log.i(TAG, "onKeepAliveListener : " + result);
+
+                        mActivity.runOnUiThread(new Runnable() {
+                            @Override
+                            public void run() {
+                                if (OC_STACK_OK == result || OC_STACK_RESOURCE_CHANGED == result) {
+                                    mSendButton.setEnabled(true);
+                                }
+
+                                mResultLog.append("Ping Resource Found Result : " + result + EOL);
+                            }
+                        });
+
+                    }
+                }
+            };
+    // ]] Find KeepAlive Resource
+
+
+    // [[ Send KeepAlive Request
+    View.OnLongClickListener sendButtonLongListener() {
+        return new View.OnLongClickListener() {
+            @Override
+            public boolean onLongClick(View v) {
+                Log.i(TAG, "sendButtonLongListener");
+
+                mActivity.runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        mActionLog.setText("[Action Log]" + EOL);
+                        mActionLog.append("Send Interval" + EOL);
+                    }
+                });
+
+                sendPing(true);
+
+                return true;
+            }
+        };
+    }
+
+    View.OnClickListener sendButtonListener() {
+        return new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                Log.i(TAG, "sendButtonListener");
+
+                mActivity.runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        mActionLog.setText("[Action Log]" + EOL);
+                        mActionLog.append("Send Ping" + EOL);
+                    }
+                });
+
+                mSendButton.setEnabled(false);
+                sendPing(false);
+            }
+        };
+    }
+
+    private void sendPing(boolean updateInterval) {
+        if (updateInterval) {
+            mResultLog.append("Send Keep Alive Interval with {2, 4, 8}" + EOL);
+        } else {
+            mResultLog.append("Send Keep Alive Request with " + mInterval[mIndex] + "min" + EOL);
+        }
+
+        try {
+            OcRepresentation rep = new OcRepresentation();
+            rep.setValue("in", mInterval[mIndex]);
+            if (updateInterval) {
+                rep.setValue("inarray", mInterval);
+            }
+            OcPlatform.sendKeepAliveRequest(mHost, rep, keepAliveListener);
+        } catch (OcException e) {
+            e.printStackTrace();
+        }
+        mWakeLock.acquire(ONE_MINUTE);
+
+        if (!updateInterval) {
+            if (isShowTimer) {
+                mRemainTime = mInterval[mIndex] * ONE_MINUTE / MILLI_PER_SEC - MARGIN_SEC;
+                showTimer();
+            } else {
+                Message msg = new Message();
+                msg.what = KEEPALIVE_MSG;
+                mHandler.sendMessageDelayed(msg, mInterval[mIndex] * ONE_MINUTE);
+            }
+
+            if (mInterval.length - 1 > mIndex) {
+                mIndex++;
+            }
+        }
+    }
+
+    OcPlatform.KeepAliveListener keepAliveListener =
+            new OcPlatform.KeepAliveListener() {
+                @Override
+                public void onKeepAliveListener(OcRepresentation ocRepresentation,
+                                                final int result) {
+                    synchronized (mActivity) {
+                        Log.i(TAG, "onKeepAliveListener : " + result);
+
+                        mActivity.runOnUiThread(new Runnable() {
+                            @Override
+                            public void run() {
+                                if (OC_STACK_OK != result && OC_STACK_RESOURCE_CHANGED != result) {
+                                    resetInterval();
+                                }
+
+                                mResultLog.append("Keep Alive Request Result : " + result + EOL);
+                            }
+                        });
+                    }
+                }
+            };
+
+    private void showTimer() {
+        mRemainView.setText("Remain Time : " + mRemainTime + "sec");
+
+        if (mRemainTime > 0) {
+            Message msg = new Message();
+            msg.what = TIMER_MSG;
+            mHandler.sendMessageDelayed(msg, MILLI_PER_SEC);
+        } else if (mRemainTime == 0) {
+            sendPing(false);
+            return;
+        }
+
+        mRemainTime--;
+    }
+
+    private Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case KEEPALIVE_MSG:
+                    sendPing(false);
+                    break;
+                case TIMER_MSG:
+                    showTimer();
+                    break;
+                default:
+                    return;
+            }
+        }
+    };
+    // ]] Send KeepAlive Request
+
+
+    // [[ State Changed
+    @Override
+    public void onAdapterStateChanged(OcConnectivityType ocConnectivityType, boolean b) {
+        Log.i(TAG, "onAdapterStateChanged");
+    }
+
+    @Override
+    public void onConnectionStateChanged(OcConnectivityType type,
+                                         String address, final boolean connected) {
+        Log.i(TAG, "onConnectionStateChanged address: " + address);
+
+        if (OcConnectivityType.CT_ADAPTER_TCP == type) {
+            final String msg = getString(R.string.action_onconnectionstatechanged) + connected;
+
+            mActivity.runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    mStatusView.setText("TCP Connected : " + connected);
+                    mFindButton.setEnabled(connected);
+                    mResultLog.append(msg + EOL);
+
+                    if (!connected) {
+                        resetInterval();
+                    }
+                }
+            });
+        }
+    }
+    // ]] State Changed
+
+
+    // [[ Get
+    void sendGetToFoundResource(final OcResource ocResource) {
+        try {
+            Log.i(TAG, "sendGetToFoundResource");
+            mActivity.runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    mResultLog.append("Send get to : " + ocResource.getHost() + EOL);
+                }
+            });
+
+            Map<String, String> queryParameters = new HashMap<String, String>();
+            queryParameters.put(Common.GET_COMMAND, Common.STATE_GET);
+            ocResource.get(queryParameters, this, QualityOfService.LOW);
+
+        } catch (OcException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void onGetCompleted(List<OcHeaderOption> list, OcRepresentation ocRepresentation) {
+        Log.i(TAG, "onGetCompleted");
+    }
+
+    @Override
+    public void onGetFailed(Throwable throwable) {
+        Log.i(TAG, "onGetFailed");
+    }
+    // ]] Get
+
+    private void resetInterval() {
+        mHandler.removeMessages(TIMER_MSG);
+        mRemainView.setText("Remain Time : -");
+        mSendButton.setEnabled(false);
+        mIndex = 0;
+        mRemainTime = -1;
+    }
+
+    private void initOcPlatform(ModeType type) {
+        PlatformConfig cfg = new PlatformConfig(mActivity, mContext,
+                ServiceType.IN_PROC,
+                type,
+                Common.IP_ADDRESS,
+                Common.IP_PORT,
+                QualityOfService.LOW);
+        OcPlatform.Configure(cfg);
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                             Bundle savedInstanceState) {
+        View rootView = inflater.inflate(R.layout.fragment_keepalive, container, false);
+
+        mIntervalView = (TextView) rootView.findViewById(R.id.interval_view);
+        mIntervalView.setText("Interval : {2, 4, 8}");
+        mRemainView = (TextView) rootView.findViewById(R.id.remain_view);
+        mStatusView = (TextView) rootView.findViewById(R.id.status_view);
+
+        mActionLog = (TextView) rootView.findViewById(R.id.action_log_view);
+        mResultLog = (TextView) rootView.findViewById(R.id.result_log_view);
+
+        mDiscoveryButton = (Button) rootView.findViewById(R.id.discovery_button);
+        mFindButton = (Button) rootView.findViewById(R.id.find_button);
+        mSendButton = (Button) rootView.findViewById(R.id.send_button);
+
+        mDiscoveryButton.setOnClickListener(discoveryButtonListener());
+        mFindButton.setOnClickListener(findButtonListener());
+        mSendButton.setOnClickListener(sendButtonListener());
+        mSendButton.setOnLongClickListener(sendButtonLongListener());
+
+
+        return rootView;
+    }
+}
index 6c11b2e..cc6ed71 100644 (file)
@@ -169,6 +169,17 @@ public class MessageFragment extends Fragment implements OcResource.OnGetListene
                                 OcPlatform.WELL_KNOWN_QUERY,
                                 EnumSet.of(OcConnectivityType.CT_ADAPTER_IP),
                                 resourceFoundListener, mQos);
+                    } else if (OcConnectivityType.CT_ADAPTER_GATT_BTLE == connectivityType) {
+                        if (null != Common.getLeAddress())
+                        {
+                            OcPlatform.findResource("",
+                                    Common.getLeAddress() + OcPlatform.WELL_KNOWN_QUERY,
+                                    EnumSet.of(OcConnectivityType.CT_ADAPTER_GATT_BTLE),
+                                    resourceFoundListener, QualityOfService.LOW);
+                        } else {
+                            Common.showToast(mContext, "Please scan ble device");
+                            Log.e(TAG, "invalid ble device");
+                        }
                     } else {
                         OcPlatform.findResource("",
                                 OcPlatform.WELL_KNOWN_QUERY,
index 91360a6..00d1c69 100644 (file)
@@ -71,6 +71,10 @@ public class SimpleBase extends Activity implements DrawerFragment.DrawerCallbac
                 fragment = new CloudFragment();
                 break;
             case 3:
+                mTitle = getString(R.string.title_keepalive);
+                fragment = new KeepAliveFragment();
+                break;
+            case 4:
                 mTitle = getString(R.string.title_template);
                 fragment = new TemplateFragment();
                 break;
diff --git a/android/examples/simplebase/src/main/res/layout/fragment_keepalive.xml b/android/examples/simplebase/src/main/res/layout/fragment_keepalive.xml
new file mode 100644 (file)
index 0000000..92b2a2b
--- /dev/null
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:paddingBottom="@dimen/activity_vertical_margin"
+    android:paddingLeft="0dp"
+    android:paddingRight="0dp"
+    android:paddingTop="@dimen/activity_vertical_margin"
+    tools:context=".KeepAliveFragment">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+
+        <LinearLayout
+            android:id="@+id/server_layout"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:focusable="true"
+            android:focusableInTouchMode="true"
+            android:orientation="vertical">
+
+            <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:background="#AAAAAA"
+                android:gravity="center_vertical"
+                android:paddingLeft="10dp"
+                android:text="Keep Alive Information"
+                android:textColor="#FFFFFF"
+                android:textSize="14sp" />
+
+            <TextView
+                android:id="@+id/interval_view"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:paddingBottom="5dp"
+                android:paddingLeft="20dp"
+                android:paddingTop="5dp"
+                android:text="Interval : -" />
+
+            <TextView
+                android:id="@+id/remain_view"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:paddingBottom="5dp"
+                android:paddingLeft="20dp"
+                android:paddingTop="5dp"
+                android:text="Remain Time : -" />
+
+            <TextView
+                android:id="@+id/status_view"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:paddingBottom="5dp"
+                android:paddingLeft="20dp"
+                android:paddingTop="5dp"
+                android:text="TCP Connected : false" />
+
+        </LinearLayout>
+
+        <LinearLayout
+            android:id="@+id/client_layout"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:focusable="true"
+            android:focusableInTouchMode="true"
+            android:gravity="center_horizontal"
+            android:orientation="vertical">
+
+            <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:background="#AAAAAA"
+                android:gravity="center_vertical"
+                android:paddingLeft="10dp"
+                android:text="Keep Alive Buttons"
+                android:textColor="#FFFFFF"
+                android:textSize="14sp" />
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_horizontal"
+                android:layout_marginTop="10dp"
+                android:gravity="center_horizontal"
+                android:orientation="horizontal">
+
+                <Button
+                    android:id="@+id/discovery_button"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center_horizontal"
+                    android:layout_weight="1"
+                    android:text="Discovery" />
+
+                <Button
+                    android:id="@+id/find_button"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center_horizontal"
+                    android:layout_weight="1"
+                    android:enabled="false"
+                    android:text="Find Ping" />
+
+                <Button
+                    android:id="@+id/send_button"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center_horizontal"
+                    android:layout_weight="1"
+                    android:enabled="false"
+                    android:text="Send Ping" />
+
+            </LinearLayout>
+        </LinearLayout>
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:background="#AAAAAA"
+            android:gravity="center_vertical"
+            android:paddingLeft="10dp"
+            android:text="Log"
+            android:textColor="#FFFFFF"
+            android:textSize="14sp" />
+
+        <TextView
+            android:id="@+id/action_log_view"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:paddingBottom="5dp"
+            android:paddingLeft="20dp"
+            android:paddingTop="5dp"
+            android:text="@string/action_log_view" />
+
+        <ScrollView
+            android:layout_width="fill_parent"
+            android:layout_height="fill_parent">
+
+            <TextView
+                android:id="@+id/result_log_view"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:paddingLeft="20dp"
+                android:paddingTop="5dp"
+                android:text="@string/result_log_view" />
+        </ScrollView>
+    </LinearLayout>
+
+</RelativeLayout>
\ No newline at end of file
index 2765bcf..92c29c9 100644 (file)
@@ -4,6 +4,7 @@
     <string name="title_message">Message</string>
     <string name="title_bluetooth">Bluetooth</string>
     <string name="title_cloud">Cloud</string>
+    <string name="title_keepalive">Keep Alive</string>
     <string name="title_template">Template</string>
 
     <string name="resource_view">[Resource View]</string>
diff --git a/build-da-checkout.sh b/build-da-checkout.sh
new file mode 100755 (executable)
index 0000000..f914518
--- /dev/null
@@ -0,0 +1,58 @@
+#!/bin/bash
+
+# For Git
+FETCH_CMD="git fetch -p"
+CHECKOUT_CMD="git checkout -f "
+
+msg_hello()
+{
+    echo "***********************************************************************"
+    echo "*                                                                     *"
+    echo "*                         IoTivity Checkout Start.                    *"
+    echo "*                                                                     *"
+    echo "***********************************************************************"
+}
+
+msg_error()
+{
+    echo ---------------------------------------------------------------------
+    echo "Fail to Build, Check Last Step. [$_STEP]"
+    echo ---------------------------------------------------------------------
+    exit 2
+}
+
+error_check()
+{
+    if [ $? != 0 ]
+    then
+       msg_error
+    fi
+}
+
+_STEP=INIT
+if [ ! -d resource/csdk ];then
+    echo "Please check the pwd."
+    msg_error
+fi
+
+# Check commit_info
+_STEP=COMMIT
+if [ "" = "$1" ];then
+    msg_error
+fi
+COMMIT_ID=$(awk '/^commit_id:/{print $2}' "$1")
+echo COMMIT ID is $COMMIT_ID
+error_check
+if [ 0 == ${#COMMIT_ID} ];then
+    msg_error
+fi
+
+_STEP=FETCH
+echo $FETCH_CMD
+$FETCH_CMD
+error_check
+
+_STEP=CHECKOUT
+echo $CHECKOUT_CMD $COMMIT_ID
+$CHECKOUT_CMD $COMMIT_ID
+error_check
diff --git a/build-im-sc-android.sh b/build-im-sc-android.sh
new file mode 100755 (executable)
index 0000000..bc166b9
--- /dev/null
@@ -0,0 +1,95 @@
+#!/bin/bash
+
+###### Please specify below ######
+CLEAN_CMD="scons -c"
+BUILD_CMD="scons TARGET_OS=android TARGET_ARCH=armeabi TARGET_TRANSPORT=IP,BLE WITH_TCP=1 WITH_CLOUD=1 SECURED=1 LOGGING=1 RELEASE=1 ANDROID_HOME=$ANDROID_HOME"
+CONF_CMD=""
+SPEC_CMD=""
+
+# For Git
+CLONE_CMD="git clone http://suprem.sec.samsung.net/gerrit/IoTivity samsung_iotivity"
+FETCH_CMD="git fetch -p"
+CHECKOUT_CMD="git checkout -f "
+
+msg_hello()
+{
+    echo "***********************************************************************"
+    echo "*                                                                     *"
+    echo "*                         IoTivity Build Start.                       *"
+    echo "*                                                                     *"
+    echo "***********************************************************************"
+}
+
+msg_error()
+{
+    echo ---------------------------------------------------------------------
+    echo "Fail to Build, Check Last Step. [$_STEP]"
+    echo ---------------------------------------------------------------------
+    exit 2
+}
+
+error_check()
+{
+    if [ $? != 0 ]
+    then
+       msg_error
+    fi
+}
+
+# Check commit_info
+_STEP=COMMIT
+if [ "" = "$1" ];then
+    msg_error
+fi
+COMMIT_ID=$(awk '/^commit_id:/{print $2}' "$1")
+echo COMMIT ID is $COMMIT_ID
+error_check
+if [ 0 == ${#COMMIT_ID} ];then
+    msg_error
+fi
+
+# Check Source Code
+_STEP=INIT
+msg_hello
+if [ ! -d resource/csdk ];then
+    if [ ! -d samsung_iotivity ];then
+        echo $CLONE_CMD
+        $CLONE_CMD
+        error_check
+    fi
+    cd ./samsung_iotivity
+fi
+error_check
+
+_STEP=FETCH
+echo $FETCH_CMD
+$FETCH_CMD
+error_check
+
+_STEP=CHECKOUT
+echo $CHECKOUT_CMD $COMMIT_ID
+$CHECKOUT_CMD $COMMIT_ID
+error_check
+
+_STEP=CONF
+echo $CONF_CMD
+$CONF_CMD
+echo $SPEC_CMD
+$SPEC_CMD
+error_check
+
+_STEP=CLEAN
+rm -rf out
+echo $CLEAN_CMD
+$CLEAN_CMD
+error_check
+
+_STEP=BUILD
+echo $BUILD_CMD
+if [ $ANDROID_HOME ];then
+    $BUILD_CMD
+    error_check
+else
+    echo "Please add ANDROID_HOME in .bashrc file."
+    msg_error
+fi
diff --git a/build-im-sc-android64.sh b/build-im-sc-android64.sh
new file mode 100755 (executable)
index 0000000..c8b41b4
--- /dev/null
@@ -0,0 +1,125 @@
+#!/bin/bash
+
+###### Please specify below ######
+CLEAN_CMD="scons -c"
+BUILD_CMD="scons TARGET_OS=android TARGET_ARCH=arm64-v8a TARGET_TRANSPORT=IP,BLE WITH_TCP=1 WITH_CLOUD=1 MULTIPLE_OWNER=1 SECURED=1 LOGGING=1 RELEASE=1 ANDROID_HOME=$ANDROID_HOME ANDROID_NDK=$ANDROID_NDK ANDROID_GRADLE=$ANDROID_GRADLE"
+REMOVE_CMD="rm -rf out"
+REMOVE_THIRDPARTY_CMD="rm service/third_party_libs.scons"
+CONF_CMD=""
+SPEC_CMD=""
+
+# For Git
+CLONE_CMD="git clone http://suprem.sec.samsung.net/gerrit/IoTivity samsung_iotivity"
+FETCH_CMD="git fetch -p"
+CHECKOUT_CMD="git checkout -f"
+CHERRYPICK_PREFIX="git fetch http://suprem.sec.samsung.net/gerrit/IoTivity"
+CHERRYPICK_CMD="git cherry-pick FETCH_HEAD"
+
+msg_hello()
+{
+    echo "***********************************************************************"
+    echo "*                                                                     *"
+    echo "*                         IoTivity Build Start.                       *"
+    echo "*                                                                     *"
+    echo "***********************************************************************"
+}
+
+msg_error()
+{
+    echo ---------------------------------------------------------------------
+    echo "Fail to Build, Check Last Step. [$_STEP]"
+    echo ---------------------------------------------------------------------
+    exit 2
+}
+
+error_check()
+{
+    if [ $? != 0 ]
+    then
+       msg_error
+    fi
+}
+
+# Check commit_info
+_STEP=COMMIT
+if [ "" = "$1" ];then
+    msg_error
+fi
+COMMIT_ID=$(awk '/^commit_id:/{print $2}' "$1")
+echo COMMIT ID is $COMMIT_ID
+error_check
+if [ 0 == ${#COMMIT_ID} ];then
+    msg_error
+fi
+
+# Cherry pick_info
+_STEP=CHERRYPICK
+CHERRYPICK_ID=$(awk '/^cherrypick_cmd_id:/{print $5}' "$1")
+for cherry_pic_arr in $CHERRYPICK_ID
+do
+    echo CHERRY_PICK_ID is $cherry_pic_arr
+    error_check
+done
+
+# Check Source Code
+_STEP=INIT
+msg_hello
+if [ ! -d resource/csdk ];then
+    if [ ! -d samsung_iotivity ];then
+        echo $CLONE_CMD
+        $CLONE_CMD
+        error_check
+    fi
+    cd ./samsung_iotivity
+fi
+error_check
+
+_STEP=FETCH
+echo $FETCH_CMD
+$FETCH_CMD
+error_check
+
+_STEP=CLEAN
+if [ -d out ]; then
+    echo $REMOVE_THIRDPARTY_CMD
+    $REMOVE_THIRDPARTY_CMD
+    echo $CLEAN_CMD
+    $CLEAN_CMD
+    error_check
+    echo $REMOVE_CMD
+    $REMOVE_CMD
+    error_check
+fi
+
+_STEP=CHECKOUT
+echo $CHECKOUT_CMD $COMMIT_ID
+$CHECKOUT_CMD $COMMIT_ID
+error_check
+
+_STEP=CHERRYPICK
+if $isCherrypickFile ; then
+    for arr_cherry_pick_cmd in $CHERRYPICK_ID; do
+        echo $CHERRYPICK_PREFIX $arr_cherry_pick_cmd 
+        $CHERRYPICK_PREFIX $arr_cherry_pick_cmd
+        echo $CHERRYPICK_CMD
+        $CHERRYPICK_CMD
+        error_check
+    done
+fi
+
+_STEP=CONF
+echo $CONF_CMD
+$CONF_CMD
+echo $SPEC_CMD
+$SPEC_CMD
+error_check
+
+_STEP=BUILD
+echo $BUILD_CMD
+if [ $ANDROID_HOME ];then
+    $BUILD_CMD
+    error_check
+else
+    echo "Please add ANDROID_HOME in .bashrc file."
+    msg_error
+fi
diff --git a/build-im-sc-ios.sh b/build-im-sc-ios.sh
new file mode 100644 (file)
index 0000000..0e6616f
--- /dev/null
@@ -0,0 +1,126 @@
+#!/bin/bash
+
+###### Please specify below ######
+CLEAN_CMD="scons -c"
+BUILD_CMD="scons TARGET_OS=ios TARGET_ARCH=arm64 TARGET_TRANSPORT=IP WITH_TCP=yes WITH_CLOUD=yes MULTIPLE_OWNER=0 SECURED=1 LOGGING=1 RELEASE=1"
+REMOVE_CMD="rm -rf out"
+REMOVE_THIRDPARTY_CMD="rm service/third_party_libs.scons"
+CONF_CMD=""
+SPEC_CMD=""
+BOOST_BUILD_CMD="chmod 755 extlibs/boost/boost_ios.sh; extlibs/boost/boost_ios.sh"
+
+# For Git
+CLONE_CMD="git clone http://suprem.sec.samsung.net/gerrit/IoTivity samsung_iotivity"
+FETCH_CMD="git fetch -p"
+CHECKOUT_CMD="git checkout -f "
+CHERRYPICK_PREFIX="git fetch http://suprem.sec.samsung.net/gerrit/IoTivity"
+CHERRYPICK_CMD="git cherry-pick FETCH_HEAD"
+
+msg_hello()
+{
+    echo "***********************************************************************"
+    echo "*                                                                     *"
+    echo "*                         IoTivity Build Start.                       *"
+    echo "*                                                                     *"
+    echo "***********************************************************************"
+}
+
+msg_error()
+{
+    echo ---------------------------------------------------------------------
+    echo "Fail to Build, Check Last Step. [$_STEP]"
+    echo ---------------------------------------------------------------------
+    exit 2
+}
+
+error_check()
+{
+    if [ $? != 0 ]
+    then
+       msg_error
+    fi
+}
+
+# Check commit_info
+_STEP=COMMIT
+if [ "" = "$1" ];then
+    msg_error
+fi
+COMMIT_ID=$(awk '/^commit_id:/{print $2}' "$1")
+echo COMMIT ID is $COMMIT_ID
+error_check
+if [ 0 == ${#COMMIT_ID} ];then
+    msg_error
+fi
+
+# Cherry pick_info
+_STEP=CHERRYPICK
+CHERRYPICK_ID=$(awk '/^cherrypick_cmd_id:/{print $5}' "$1")
+for cherry_pic_arr in $CHERRYPICK_ID
+do
+    echo CHERRY_PICK_ID is $cherry_pic_arr
+    error_check
+done
+
+# Check Source Code
+_STEP=INIT
+msg_hello
+if [ ! -d resource/csdk ];then
+    if [ ! -d samsung_iotivity ];then
+        echo $CLONE_CMD
+        $CLONE_CMD
+        error_check
+    fi
+    cd ./samsung_iotivity
+fi
+error_check
+
+_STEP=FETCH
+echo $FETCH_CMD
+$FETCH_CMD
+error_check
+
+_STEP=CLEAN
+if [ -d out ]; then
+    echo $REMOVE_THIRDPARTY_CMD
+    $REMOVE_THIRDPARTY_CMD
+    echo $CLEAN_CMD
+    $CLEAN_CMD
+    error_check
+    echo $REMOVE_CMD
+    $REMOVE_CMD
+    error_check
+fi
+
+_STEP=CHECKOUT
+echo $CHECKOUT_CMD $COMMIT_ID
+$CHECKOUT_CMD $COMMIT_ID
+error_check
+
+_STEP=CHERRYPICK
+for arr_cherry_pick_cmd in $CHERRYPICK_ID; do
+    echo $CHERRYPICK_PREFIX $arr_cherry_pick_cmd
+    $CHERRYPICK_PREFIX $arr_cherry_pick_cmd
+    error_check
+    echo $CHERRYPICK_CMD
+    $CHERRYPICK_CMD
+    error_check
+done
+
+
+_STEP=CONF
+echo $CONF_CMD
+$CONF_CMD
+echo $SPEC_CMD
+$SPEC_CMD
+error_check
+
+_STEP=BOOST_BUILD
+echo $BOOST_BUILD_CMD
+eval $BOOST_BUILD_CMD
+error_check
+
+_STEP=BUILD
+echo $BUILD_CMD
+$BUILD_CMD
+error_check
diff --git a/build-im-virtual_device-android.sh b/build-im-virtual_device-android.sh
new file mode 100755 (executable)
index 0000000..1dd54c4
--- /dev/null
@@ -0,0 +1,95 @@
+#!/bin/bash
+
+###### Please specify below ######
+CLEAN_CMD="scons -c"
+BUILD_CMD="scons TARGET_OS=android TARGET_ARCH=armeabi TARGET_TRANSPORT=IP WITH_TCP=1 WITH_CLOUD=1 SECURED=1 LOGGING=1 RELEASE=1 ANDROID_HOME=$ANDROID_HOME"
+CONF_CMD=""
+SPEC_CMD=""
+
+# For Git
+CLONE_CMD="git clone http://suprem.sec.samsung.net/gerrit/IoTivity samsung_iotivity"
+FETCH_CMD="git fetch -p"
+CHECKOUT_CMD="git checkout -f "
+
+msg_hello()
+{
+    echo "***********************************************************************"
+    echo "*                                                                     *"
+    echo "*                         IoTivity Build Start.                       *"
+    echo "*                                                                     *"
+    echo "***********************************************************************"
+}
+
+msg_error()
+{
+    echo ---------------------------------------------------------------------
+    echo "Fail to Build, Check Last Step. [$_STEP]"
+    echo ---------------------------------------------------------------------
+    exit 2
+}
+
+error_check()
+{
+    if [ $? != 0 ]
+    then
+       msg_error
+    fi
+}
+
+# Check commit_info
+_STEP=COMMIT
+if [ "" = "$1" ];then
+    msg_error
+fi
+COMMIT_ID=$(awk '/^commit_id:/{print $2}' "$1")
+echo COMMIT ID is $COMMIT_ID
+error_check
+if [ 0 == ${#COMMIT_ID} ];then
+    msg_error
+fi
+
+# Check Source Code
+_STEP=INIT
+msg_hello
+if [ ! -d resource/csdk ];then
+    if [ ! -d samsung_iotivity ];then
+        echo $CLONE_CMD
+        $CLONE_CMD
+        error_check
+    fi
+    cd ./samsung_iotivity
+fi
+error_check
+
+_STEP=FETCH
+echo $FETCH_CMD
+$FETCH_CMD
+error_check
+
+_STEP=CHECKOUT
+echo $CHECKOUT_CMD $COMMIT_ID
+$CHECKOUT_CMD $COMMIT_ID
+error_check
+
+_STEP=CONF
+echo $CONF_CMD
+$CONF_CMD
+echo $SPEC_CMD
+$SPEC_CMD
+error_check
+
+_STEP=CLEAN
+rm -rf out
+echo $CLEAN_CMD
+$CLEAN_CMD
+error_check
+
+_STEP=BUILD
+echo $BUILD_CMD
+if [ $ANDROID_HOME ];then
+    $BUILD_CMD
+    error_check
+else
+    echo "Please add ANDROID_HOME in .bashrc file."
+    msg_error
+fi
diff --git a/build-vd-tv-es-tizen30.sh b/build-vd-tv-es-tizen30.sh
new file mode 100644 (file)
index 0000000..0ed304a
--- /dev/null
@@ -0,0 +1,107 @@
+#!/bin/bash
+
+###### Please specify below ######
+BUILD_CMD="bash gbsbuild.sh WITH_TCP SECURED"
+CONF_CMD="cp ./tools/tizen/.gbs.vd.tv.tizen30.conf ./tools/tizen/.gbs.conf"
+SPEC_CMD="cp ./tools/tizen/iotivity-vd-tv-es-tizen30.spec ./tools/tizen/iotivity.spec"
+
+# For Git
+CLONE_CMD="git clone http://suprem.sec.samsung.net/gerrit/IoTivity samsung_iotivity"
+FETCH_CMD="git fetch -p"
+CHECKOUT_CMD="git checkout -f "
+CHERRYPICK_PREFIX="git fetch http://suprem.sec.samsung.net/gerrit/IoTivity"
+CHERRYPICK_CMD="git cherry-pick FETCH_HEAD"
+
+msg_hello()
+{
+    echo "***********************************************************************"
+    echo "*                                                                     *"
+    echo "*                         IoTivity Build Start.                       *"
+    echo "*                                                                     *"
+    echo "***********************************************************************"
+}
+
+msg_error()
+{
+    echo ---------------------------------------------------------------------
+    echo "Fail to Build, Check Last Step. [$_STEP]"
+    echo ---------------------------------------------------------------------
+    exit 2
+}
+
+error_check()
+{
+    if [ $? != 0 ]
+    then
+       msg_error
+    fi
+}
+
+# Check commit_info
+_STEP=COMMIT
+if [ "" = "$1" ];then
+    msg_error
+fi
+COMMIT_ID=$(awk '/^commit_id:/{print $2}' "$1")
+echo COMMIT ID is $COMMIT_ID
+error_check
+if [ 0 == ${#COMMIT_ID} ];then
+    msg_error
+fi
+
+# Cherry pick_info
+_STEP=CHERRYPICK
+CHERRYPICK_ID=$(awk '/^cherrypick_cmd_id:/{print $5}' "$1")
+for cherry_pic_arr in $CHERRYPICK_ID
+do
+    echo CHERRY_PICK_ID is $cherry_pic_arr
+    error_check
+done
+
+# Check Source Code
+_STEP=INIT
+msg_hello
+if [ ! -d resource/csdk ];then
+    if [ ! -d samsung_iotivity ];then
+        echo $CLONE_CMD
+        $CLONE_CMD
+        error_check
+    fi
+    cd ./samsung_iotivity
+fi
+error_check
+
+_STEP=FETCH
+echo $FETCH_CMD
+$FETCH_CMD
+error_check
+
+_STEP=CHECKOUT
+echo $CHECKOUT_CMD $COMMIT_ID
+$CHECKOUT_CMD $COMMIT_ID
+error_check
+
+_STEP=CHERRYPICK
+for arr_cherry_pick_cmd in $CHERRYPICK_ID; do
+    echo $CHERRYPICK_PREFIX $arr_cherry_pick_cmd
+    $CHERRYPICK_PREFIX $arr_cherry_pick_cmd
+    error_check
+    echo $CHERRYPICK_CMD
+    $CHERRYPICK_CMD
+    error_check
+done
+
+_STEP=CONF
+echo $CONF_CMD
+$CONF_CMD
+echo $SPEC_CMD
+$SPEC_CMD
+error_check
+
+_STEP=CLEAN
+rm -rf out
+
+_STEP=BUILD
+echo $BUILD_CMD
+$BUILD_CMD
+error_check
diff --git a/build-vd-tv-tizen30.sh b/build-vd-tv-tizen30.sh
new file mode 100755 (executable)
index 0000000..53702e0
--- /dev/null
@@ -0,0 +1,107 @@
+#!/bin/bash
+
+###### Please specify below ######
+BUILD_CMD="bash ./gbsbuild.sh"
+CONF_CMD="cp ./tools/tizen/.gbs.vd.tv.tizen30.conf ./tools/tizen/.gbs.conf"
+SPEC_CMD="cp ./tools/tizen/iotivity-vd-tv-tizen30.spec ./tools/tizen/iotivity.spec"
+
+# For Git
+CLONE_CMD="git clone http://suprem.sec.samsung.net/gerrit/IoTivity samsung_iotivity"
+FETCH_CMD="git fetch -p"
+CHECKOUT_CMD="git checkout -f "
+CHERRYPICK_PREFIX="git fetch http://suprem.sec.samsung.net/gerrit/IoTivity"
+CHERRYPICK_CMD="git cherry-pick FETCH_HEAD"
+
+msg_hello()
+{
+    echo "***********************************************************************"
+    echo "*                                                                     *"
+    echo "*                         IoTivity Build Start.                       *"
+    echo "*                                                                     *"
+    echo "***********************************************************************"
+}
+
+msg_error()
+{
+    echo ---------------------------------------------------------------------
+    echo "Fail to Build, Check Last Step. [$_STEP]"
+    echo ---------------------------------------------------------------------
+    exit 2
+}
+
+error_check()
+{
+    if [ $? != 0 ]
+    then
+       msg_error
+    fi
+}
+
+# Check commit_info
+_STEP=COMMIT
+if [ "" = "$1" ];then
+    msg_error
+fi
+COMMIT_ID=$(awk '/^commit_id:/{print $2}' "$1")
+echo COMMIT ID is $COMMIT_ID
+error_check
+if [ 0 == ${#COMMIT_ID} ];then
+    msg_error
+fi
+
+# Cherry pick_info
+_STEP=CHERRYPICK
+CHERRYPICK_ID=$(awk '/^cherrypick_cmd_id:/{print $5}' "$1")
+for cherry_pic_arr in $CHERRYPICK_ID
+do
+    echo CHERRY_PICK_ID is $cherry_pic_arr
+    error_check
+done
+
+# Check Source Code
+_STEP=INIT
+msg_hello
+if [ ! -d resource/csdk ];then
+    if [ ! -d samsung_iotivity ];then
+        echo $CLONE_CMD
+        $CLONE_CMD
+        error_check
+    fi
+    cd ./samsung_iotivity
+fi
+error_check
+
+_STEP=FETCH
+echo $FETCH_CMD
+$FETCH_CMD
+error_check
+
+_STEP=CHECKOUT
+echo $CHECKOUT_CMD $COMMIT_ID
+$CHECKOUT_CMD $COMMIT_ID
+error_check
+
+_STEP=CHERRYPICK
+for arr_cherry_pick_cmd in $CHERRYPICK_ID; do
+    echo $CHERRYPICK_PREFIX $arr_cherry_pick_cmd
+    $CHERRYPICK_PREFIX $arr_cherry_pick_cmd
+    error_check
+    echo $CHERRYPICK_CMD
+    $CHERRYPICK_CMD
+    error_check
+done
+
+_STEP=CONF
+echo $CONF_CMD
+$CONF_CMD
+echo $SPEC_CMD
+$SPEC_CMD
+error_check
+
+_STEP=CLEAN
+rm -rf out
+
+_STEP=BUILD
+echo $BUILD_CMD
+$BUILD_CMD
+error_check
index e00a628..b373665 100644 (file)
@@ -10,7 +10,7 @@ project_version = '1.2.1'
 
 # Map of host os and allowed target os (host: allowed target os)
 host_target_map = {
-               'linux': ['linux', 'android', 'arduino', 'yocto', 'tizen'],
+               'linux': ['linux', 'android', 'arduino', 'yocto', 'tizen', 'tizenrt'],
                'windows': ['windows', 'android', 'arduino'],
                'darwin': ['darwin', 'ios', 'android', 'arduino'],
                'msys_nt' :['msys_nt'],
@@ -27,6 +27,7 @@ os_arch_map = {
                'ios': ['i386', 'x86_64', 'armv7', 'armv7s', 'arm64'],
                'arduino': ['avr', 'arm'],
                'yocto': ['i586', 'i686', 'x86_64', 'arm', 'aarch64', 'powerpc', 'powerpc64', 'mips', 'mipsel'],
+               'tizenrt': ['armv7-r', 'armv7-m'],
                }
 
 host = platform.system().lower()
@@ -112,9 +113,12 @@ else:
 
 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('WITH_MBEDTLS_STATIC_LIB', 'Build mbedTLS library as static library', '0', allowed_values=('0', '1')))
 help_vars.Add(EnumVariable('MULTIPLE_OWNER', 'Enable multiple owner', '0', allowed_values=('0', '1')))
+help_vars.Add(EnumVariable('EXC_PROV_SUPPORT', 'Except OCPMAPI library(libocpmapi.so)', '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(EnumVariable('LOG_LEVEL', 'Enable stack logging level', 'DEBUG', allowed_values=('DEBUG', 'INFO', 'ERROR', 'WARNING', 'FATAL')))
 help_vars.Add(BoolVariable('UPLOAD', 'Upload binary ? (For Arduino)', require_upload))
 help_vars.Add(EnumVariable('ROUTING', 'Enable routing', 'EP', allowed_values=('GW', 'EP')))
 help_vars.Add(EnumVariable('BUILD_SAMPLE', 'Build with sample', 'ON', allowed_values=('ON', 'OFF')))
@@ -123,7 +127,12 @@ help_vars.Add(PathVariable('ANDROID_NDK', 'Android NDK path', None, PathVariable
 help_vars.Add(PathVariable('ANDROID_HOME', 'Android SDK path', None, PathVariable.PathAccept))
 help_vars.Add(PathVariable('ANDROID_GRADLE', 'Gradle binary file', None, PathVariable.PathIsFile))
 help_vars.Add(EnumVariable('WITH_UPSTREAM_LIBCOAP', 'Use latest stable version of LibCoAP downloaded from github', default_with_upstream_libcoap, allowed_values=('0','1')))
-
+help_vars.Add(EnumVariable('BLE_CUSTOM_ADV', 'Build with CUSTOM Advertisement', 'False', allowed_values=('True', 'False')))
+help_vars.Add(EnumVariable('BLE_DIVISION', 'BLE Build with division code', 'OFF', allowed_values=('OFF', 'MCD', 'VD')))
+help_vars.Add(EnumVariable('BLE_TIZEN_30', 'Build with tizen 3.0 BLE api', 'False', allowed_values=('True', 'False')))
+help_vars.Add(PathVariable('TIZENRT_OS_DIR', 'Absolute Path to TizenRT OS directory', None, PathVariable.PathAccept))
+help_vars.Add(EnumVariable('PLATFORM_TLS', 'Use platform tls instead of local mbedtls', '0', allowed_values=('0', '1')))
+help_vars.Add(EnumVariable('OIC_SUPPORT_TIZEN_TRACE', 'Tizen Trace(T-trace) api availability', 'False', allowed_values=('True', 'False')))
 AddOption('--prefix',
                   dest='prefix',
                   type='string',
@@ -135,7 +144,7 @@ AddOption('--prefix',
 ######################################################################
 # Platform(build target) specific options: SDK/NDK & toolchain
 ######################################################################
-targets_support_cc = ['linux', 'arduino', 'tizen']
+targets_support_cc = ['linux', 'arduino', 'tizen', 'tizenrt']
 
 if target_os in targets_support_cc:
        # Set cross compile toolchain
@@ -189,6 +198,9 @@ if target_os in targets_support_cc:
                env.AppendUnique(CCFLAGS = ['--sysroot=' + sys_root])
                env.AppendUnique(LINKFLAGS = ['--sysroot=' + sys_root])
 
+        if target_os == 'tizenrt':
+                env.PrependENVPath('PATH', os.environ['PATH'])
+
        if prefix or tc_path:
                print tc_set_msg
 
@@ -335,15 +347,17 @@ if env.get('ROUTING') == 'GW':
 elif env.get('ROUTING') == 'EP':
     defines.append('-DROUTING_EP=1')
 
-libs = []
 if env.get('WITH_TCP'):
     defines.append('-DTCP_ADAPTER=1')
     if env.get('SECURED') == '1':
         defines.append('-D__WITH_TLS__=1')
 
+libs = []
 if env.get('SECURED') == '1':
-    libs.append('-locpmapi')
-    defines.append('-D_WITH_DTLS_=1')
+    defines.append('-D__WITH_DTLS__=1')
+    if env.get('EXC_PROV_SUPPORT') == '0':
+        libs.append('-locpmapi')       # CAPI
+        libs.append('-locprovision')   # C++API
 
 pc_vars = {
     '\@VERSION\@': project_version,
index f24c038..2de28b1 100644 (file)
@@ -153,6 +153,21 @@ for flags in p.stdout.readlines():
                env.AppendUnique(CXXFLAGS = Split(flags[9:]))
 
        elif cmp(flags[0:8], 'CPPPATH=') == 0:
+               ndk_arch = 'arch-'
+               if cmp(target_arch, 'x86') == 0:
+                       ndk_arch += 'x86'
+               elif cmp(target_arch, 'x86_64') == 0:
+                       ndk_arch += 'x86_64'
+               elif cmp(target_arch, 'armeabi') == 0:
+                       ndk_arch += 'arm'
+               elif cmp(target_arch, 'armeabi-v7a') == 0:
+                       ndk_arch += 'arm'
+               elif cmp(target_arch, 'armeabi-v7a-hard') == 0:
+                       ndk_arch += 'arm'
+               elif cmp(target_arch, 'arm64-v8a') == 0:
+                       ndk_arch += 'arm64'
+
+               env.AppendUnique(CPPPATH = android_ndk+'/platforms/android-21/'+ndk_arch+'/usr/include')
                env.AppendUnique(CPPPATH = Split(flags[8:]))
 
        elif cmp(flags[0:8], 'SYSROOT=') == 0:
@@ -165,9 +180,8 @@ for flags in p.stdout.readlines():
        elif cmp(flags[0:7], 'TC_VER=') == 0:  # set gnustl library path
                ver = flags[7:].strip()
                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/'
-
+#              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')
 
@@ -221,7 +235,6 @@ env.AppendUnique(LIBPATH = [src_dir + '/resource/csdk/connectivity/lib/android']
 env.AppendUnique(LIBS = ['log', 'coap'])
 
 if env.get('SECURED') == '1':
-       env.AppendUnique(LIBS = ['tinydtls'])
        env.SConscript('#extlibs/mbedtls/SConscript')
        env.AppendUnique(LIBS = ['mbedtls','mbedx509','mbedcrypto'])
 
index fc01aef..2b07db5 100644 (file)
@@ -10,7 +10,7 @@ target_os = thread_env.get('TARGET_OS')
 compiler = thread_env.get('CC')
 if 'gcc' in compiler:
     thread_env.AppendUnique(CFLAGS = ['-Wall'])
-    if target_os not in ['android']:
+    if target_os not in ['android','tizenrt']:
         thread_env.AppendUnique(CFLAGS = ['-pthread'])
         thread_env.AppendUnique(LIBS = ['pthread'])
 
index 88e95dd..aa2c212 100644 (file)
@@ -24,5 +24,6 @@ env.AppendUnique(LIBS = ['dl', 'pthread'])
 
 env.AppendUnique(CCFLAGS = ['-D__TIZEN__', '-D_GNU_SOURCE', '-DTIZEN_DEBUG_ENABLE'])
 env.ParseConfig("pkg-config dlog --cflags --libs")
-
+if env.get('OIC_SUPPORT_TIZEN_TRACE') == 'True':
+    env.ParseConfig("pkg-config ttrace --cflags --libs")
 # Set arch flags : It will be handled by Tizen build system.
diff --git a/build_common/tizenrt/SConscript b/build_common/tizenrt/SConscript
new file mode 100644 (file)
index 0000000..6325807
--- /dev/null
@@ -0,0 +1,77 @@
+###########################################################################
+#
+# Copyright 2016 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.
+#
+###########################################################################
+
+##
+# This script includes tizenrt specific config
+##
+import os
+import platform
+
+Import('env')
+
+print "Reading tizenrt configuration script"
+
+host = platform.system().lower()
+
+default_os_dir = env.GetLaunchDir() + '/../../../os'
+
+# TIZENRT_OS_DIR build option
+if env.get('TIZENRT_OS_DIR'):
+        tizenrt_os_dir = ARGUMENTS.get('TIZENRT_OS_DIR',default_os_dir)
+       print 'TIZENRT_OS_DIR = ' + tizenrt_os_dir
+else:
+        print '''
+*************************************** Info **********************************
+*   Environment variable TIZENRT_OS_DIR must be set to absolute path of       *
+*   tizenrt os directory. To set, please specify TIZENRT_OS_DIR as follows:   *
+*       scons TIZENRT_OS_DIR= <path to tizenrt os directory>                  *
+*******************************************************************************
+'''
+
+target_arch = env.get('TARGET_ARCH')
+
+env.AppendUnique(CCFLAGS = ['-fno-builtin'])
+# Set release/debug flags
+if env.get('RELEASE') == 1:
+       env.AppendUnique(CCFLAGS = ['-Os'])
+       env.AppendUnique(CPPDEFINES = ['NDEBUG'])
+else:
+       env.AppendUnique(CCFLAGS = ['-g'])
+
+# we have variety of macros for tizenrt!!
+#env.AppendUnique(CPPDEFINES = ['CONFIG_CLOCK_MONOTONIC'])
+env.AppendUnique(CPPDEFINES = ['WITH_POSIX', '__TIZENRT__'])
+# Set device name to __OIC_DEVICE_NAME__
+env.AppendUnique(CPPDEFINES = ['-D__OIC_DEVICE_NAME__=' + "\'\"" + env.get('DEVICE_NAME') + "\"\'"])
+if env.get('LOGGING'):
+       print 'LOGGING is enabled'
+       env.AppendUnique(CPPDEFINES = ['TB_LOG'])
+
+
+# Determine dependency for tizenrt_os_dir
+
+dep_src_dir1 =  os.path.join(tizenrt_os_dir, 'include')
+dep_src_dir2 =  os.path.join(tizenrt_os_dir, 'include/tinyara')
+dep_lib_dir =  '/usr/lib/arm-none-eabi/include'
+
+
+# Add directories to search for header files and external libraries
+env.AppendUnique(CPPPATH = [ dep_src_dir1, dep_src_dir2 ])
+env.AppendUnique(LIBPATH = [ dep_lib_dir ])
+
+print env.get('CPPPATH')
index 514b54c..85e1689 100644 (file)
@@ -1,11 +1,12 @@
 # -*- coding: utf-8 -*-
 
+# -- Dual Licence ----------------------------------------------------------
+
 ############################################################################
 # GPL License                                                              #
 #                                                                          #
 # This file is a SCons (http://www.scons.org/) builder                     #
 # Copyright (c) 2012-14, Philipp Kraus, <philipp.kraus@flashpixx.de>       #
-# 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       #
 # along with this program. If not, see <http://www.gnu.org/licenses/>.     #
 ############################################################################
 
-# 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.
+# --------------------------------------------------------------------------
+
+############################################################################
+# BSD 3-Clause License                                                     #
+#                                                                          #
+# This file is a SCons (http://www.scons.org/) builder                     #
+# Copyright (c) 2012-14, Philipp Kraus, <philipp.kraus@flashpixx.de>       #
+# 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 its         #
+# contributors may be used to endorse or promote products derived from     #
+# this software without specific prior written permission.                 #
+#                                                                          #
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS      #
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT        #
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A  #
+# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT       #
+# 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.             #
+############################################################################
+
+
 
 # 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"):
+# 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
 
 
 import subprocess, os
-import SCons.Errors, SCons.Warnings, SCons.Util
+
+import SCons.Errors, SCons.Warnings
+import SCons.Util
+
 
 # enables Scons warning for this builder
 class UnpackWarning(SCons.Warnings.Warning) :
@@ -67,6 +104,8 @@ class UnpackWarning(SCons.Warnings.Warning) :
 
 SCons.Warnings.enableWarningClass(UnpackWarning)
 
+
+
 # extractor function for Tar output
 # @param env environment object
 # @param count number of returning lines
@@ -115,10 +154,11 @@ def __fileextractor_win_7zip( env, count, no, i ) :
 # @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
+    # we check each unpacker and get the correc  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 the run command not set, we continue the extractor search, otherwise we check the extractor parameters
         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"]) :
@@ -159,64 +199,97 @@ def __message( s, target, source, env ) :
 # action function for extracting of the data
 # @param target target packed file
 # @param source extracted files
-# @param env environment object
+# @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) )
+        raise SCons.Errors.StopError( "can not find any extractor value for the source file [%s]" % (source[0]) )
 
-    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) )
+    if len(extractor["EXTRACTCMD"]) == 0 :
+        raise SCons.Errors.StopError( "the extractor command for the source file [%s] is empty" % (source[0]) )
 
     # build it now (we need the shell, because some programs need it)
     handle = None
-
-    cmd = env.subst(extractor_cmd, source=source, target=target)
+    cmd    = env.subst(extractor["EXTRACTCMD"], 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)
+        handle  = subprocess.Popen( cmd, shell=True, stdout=devnull )
 
     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) )
+        raise SCons.Errors.BuildError( "error running extractor [%s] on the source [%s]" % (cmd, source[0])  )
+
 
 # emitter function for getting the files
 # within the archive
 # @param target target packed file
 # @param source extracted files
-# @param env environment object
+# @env environment object
 def __emitter( target, source, env ) :
+    extractor = __getExtractor(source, env)
+    if not extractor :
+        raise SCons.Errors.StopError( "can not find any extractor value for the source file [%s]" % (source[0]) )
+
+    # we do a little trick, because in some cases we do not have got a physical
+    # file (eg we download a packed archive), so we don't get a list or knows
+    # the targets. On physical files we can do this with the LISTCMD, but on
+    # non-physical files we hope the user knows the target files, so we inject
+    # this knowledge into the return target.
+    if env.has_key("UNPACKLIST") :
+        if not SCons.Util.is_List(env["UNPACKLIST"]) and not SCons.Util.is_String(env["UNPACKLIST"]) :
+            raise SCons.Errors.StopError( "manual target list of [%s] must be a string or list" % (source[0]) )
+        if not env["UNPACKLIST"] :
+            raise SCons.Errors.StopError( "manual target list of [%s] need not be empty" % (source[0]) )
+        return env["UNPACKLIST"], source
+
+
+    # we check if the source file exists, because we would like to read the data
+    if not source[0].exists() :
+        raise SCons.Errors.StopError( "source file [%s] must be exist" % (source[0]) )
+
+    # create the list command and run it in a subprocess and pipes the output to a variable,
+    # we need the shell for reading data from the stdout
+    cmd    = env.subst(extractor["LISTCMD"], source=source, target=target)
+    handle = subprocess.Popen( cmd, shell=True, stdout=subprocess.PIPE )
+    target = handle.stdout.readlines()
+    handle.communicate()
+    if handle.returncode <> 0 :
+        raise SCons.Errors.StopError("error on running list command [%s] of the source file [%s]" % (cmd, source[0]) )
+
+    # if the returning output exists and the listseperator is a callable structure
+    # we run it for each line of the output and if the return of the callable is
+    # a string we push it back to the target list
+    try :
+        if callable(extractor["LISTEXTRACTOR"]) :
+            target = filter( lambda s : SCons.Util.is_String(s), [ extractor["LISTEXTRACTOR"]( env, len(target), no, i) for no, i in enumerate(target) ] )
+    except Exception, e :
+        raise SCons.Errors.StopError( "%s" % (e) )
+
+    # the line removes duplicated names - we need this line, otherwise an cyclic dependency error will occured,
+    # because the list process can create redundant data (an archive file can not store redundant content in a filepath)
+    target = [i.strip() for i in list(set(target))]
+    if not target :
+        SCons.Warnings.warn(UnpackWarning, "emitter file list on target [%s] is empty, please check your extractor list function [%s]" % (source[0], cmd) )
+
+    # we append the extractdir to each target if is not absolut
+    if env["UNPACK"]["EXTRACTDIR"] <> "." :
+        target = [i if os.path.isabs(i) else os.path.join(env["UNPACK"]["EXTRACTDIR"], i) for i in target]
+
     return target, source
 
 def __unpack_all(env, target, source) :
-       if os.path.exists(target):
-               return
+    if os.path.exists(target):
+        return
 
-       print "Unpacking %s ..." % source
-       __action(target, source, env)
+    print "Unpacking %s ..." % source
+    __action(target, source, env)
 
 # generate function, that adds the builder to the environment
-# @param env environment object
+# @env environment object
 def generate( env ) :
     # setup environment variable
     toolset = {
index 1881f90..68b03f3 100644 (file)
@@ -36,6 +36,8 @@ import org.iotivity.cloud.base.protocols.MessageBuilder;
 import org.iotivity.cloud.base.protocols.coap.CoapResponse;
 import org.iotivity.cloud.base.protocols.enums.RequestMethod;
 import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
+import org.iotivity.cloud.rdserver.Constants;
+import org.iotivity.cloud.rdserver.db.DBManager;
 import org.iotivity.cloud.rdserver.resources.directory.rd.ResourceDirectoryResource;
 import org.iotivity.cloud.rdserver.resources.directory.res.DiscoveryResource;
 import org.iotivity.cloud.util.Cbor;
@@ -92,6 +94,13 @@ public class DiscoveryResourceTest {
 
     @Test
     public void testHandleGetRequest_existValue() throws Exception {
+        // add presence state on
+        HashMap<String, Object> presenceinfo = new HashMap<>();
+        presenceinfo.put(Constants.DEVICE_ID, RDServerTestUtils.DI);
+        presenceinfo.put(Constants.PRESENCE_STATE, Constants.PRESENCE_ON);
+        DBManager.getInstance().insertRecord(Constants.PRESENCE_TABLE,
+                presenceinfo);
+
         IRequest request = MessageBuilder.createRequest(RequestMethod.GET,
                 RDServerTestUtils.DISCOVERY_REQ_URI,
                 "rt=core.light;di=" + RDServerTestUtils.DI);
@@ -148,4 +157,4 @@ public class DiscoveryResourceTest {
                 .parsePayloadFromCbor(mResponse.getPayload(), ArrayList.class);
         return (payloadData.isEmpty());
     }
-}
\ No newline at end of file
+}
index 17cec71..d507b73 100644 (file)
@@ -482,7 +482,7 @@ void PublishResources(string host)
         cout << "Setting device info failed" << endl;
     }
 
-    res = OCRDPublish(host.c_str(), CT_ADAPTER_TCP, NULL, 0, &cbData, OC_LOW_QOS);
+    res = OCRDPublish(nullptr, host.c_str(), CT_ADAPTER_TCP, NULL, 0, &cbData, OC_LOW_QOS);
     if (res != OC_STACK_OK)
     {
         cout << "Unable to publish default resources to cloud" << endl;
@@ -490,7 +490,7 @@ void PublishResources(string host)
 
     cout << "Publish user resources" << endl;
 
-    res = OCRDPublish(host.c_str(), CT_ADAPTER_TCP, resourceHandles, 1, &cbData, OC_LOW_QOS);
+    res = OCRDPublish(nullptr, host.c_str(), CT_ADAPTER_TCP, resourceHandles, 1, &cbData, OC_LOW_QOS);
     if (res != OC_STACK_OK)
     {
         cout << "Unable to publish user resources to cloud" << endl;
index 76fb4ec..cae1be1 100644 (file)
@@ -17,7 +17,7 @@ if target_os in ['android']:
     boost_version   = '1.58.0'
 
 boost_base_name  = 'boost_'+string.replace(boost_version,'.','_')
-boost_arch_name  = boost_base_name+'.zip'
+boost_arch_name  = boost_base_name+'.tar.bz2'
 boost_b2_name    = boost_base_name+os.sep+'b2'
 boost_url       = 'http://downloads.sourceforge.net/project/boost/boost/'+boost_version+'/'+boost_arch_name+'?r=&ts=1421801329&use_mirror=iweb'
 
index 52a75ac..6441a5a 100644 (file)
@@ -115,11 +115,11 @@ if target_os == 'msys_nt':
     libcoap_env.AppendUnique(CPPDEFINES = ['_DEFAULT_SOURCE'])
     libcoap_env.AppendUnique(CFLAGS = ['-std=c99'])
 
-if target_os in ['linux', 'tizen', 'android', 'ios', 'arduino']:
+if target_os in ['linux', 'tizen', 'android', 'ios', 'arduino', 'tizenrt']:
     if with_tcp == True:
         libcoap_env.AppendUnique(CPPDEFINES = ['WITH_TCP'])
 
-if target_os in ['linux', 'tizen', 'android', 'arduino']:
+if target_os in ['linux', 'tizen', 'android', 'arduino', 'tizenrt']:
     libcoap_env.AppendUnique(LIBS = ['log'])
     if (('BLE' in ca_transport) or ('BT' in ca_transport) or ('ALL' in ca_transport)):
         libcoap_env.AppendUnique(CPPDEFINES = ['WITH_TCP'])
index 3301e2a..cfcec9d 100644 (file)
@@ -26,6 +26,7 @@ import subprocess
 
 target_os = env.get('TARGET_OS')
 root_dir = env.get('SRC_DIR')
+static_lib = env.get('WITH_MBEDTLS_STATIC_LIB');
 mbedtls_dir = os.path.join(root_dir, 'extlibs','mbedtls','mbedtls/')
 start_dir = os.getcwd()
 # Right now this script assumes the revision is a tag, and not a branch or an arbitrary
@@ -48,20 +49,19 @@ os.chdir(mbedtls_dir)
 # the mbedtls_revision tag selected is the same as in extlibs/mbedtls/prep.sh.
 # This code also assumes mbedtls_revision is a tag; if it changes to
 # a branch or an arbitrary commit, disable this check below.
-if target_os != 'tizen':
-    out = subprocess.check_output('git tag -l ' + mbedtls_revision, shell = True)
-    if mbedtls_revision not in out:
-        print out
-        print '''
-*********************************** Error: ****************************************
-* Your mbedTLS repo is not up to date with the latest version we require. Please  *
-* update with the following commands:                                             *
-*     $ cd extlibs/mbedtls/mbedtls                                                *
-*     $ git fetch                                                                 *
-***********************************************************************************
- '''
-        Exit(1)
-
+# if target_os != 'tizen':
+#     out = subprocess.check_output('git tag -l ' + mbedtls_revision, shell = True)
+#     if mbedtls_revision not in out:
+#         print out
+#         print '''
+# *********************************** Error: ****************************************
+# * Your mbedTLS repo is not up to date with the latest version we require. Please  *
+# * update with the following commands:                                             *
+# *     $ cd extlibs/mbedtls/mbedtls                                                *
+# *     $ git fetch                                                                 *
+# ***********************************************************************************
+#  '''
+#         Exit(1)
 
 # Apply ocf patch on git revision
 if os.path.exists('.git/HEAD'):
@@ -169,7 +169,21 @@ mbex509_env.AppendUnique(LIBS = ['mbedcrypto'])
 static_libmbedx509 = mbex509_env.StaticLibrary('mbedx509', mbeX509_src)
 mbex509_env.InstallTarget(static_libmbedx509, 'mbedx509')
 
-
-mbedtls_env.AppendUnique(LIBS = ['mbedx509', 'mbedcrypto'])
-static_libmbedtls = mbedtls_env.StaticLibrary('mbedtls', mbedtls_src)
-mbedtls_env.InstallTarget(static_libmbedtls, 'mbedtls')
+if static_lib == '1':
+       mbedtls_env.AppendUnique(LIBS = ['mbedx509', 'mbedcrypto'])
+       static_libmbedtls = mbedtls_env.StaticLibrary('mbedtls', mbedtls_src)
+       mbedtls_env.InstallTarget(static_libmbedtls, 'mbedtls')
+else:
+       if target_os in ['windows', 'msys_nt', 'ios']:
+               mbedtls_env.AppendUnique(LIBS = ['mbedx509', 'mbedcrypto'])
+               static_libmbedtls = mbedtls_env.StaticLibrary('mbedtls', mbedtls_src)
+               mbedtls_env.InstallTarget(static_libmbedtls, 'mbedtls')
+       else:
+               mbedtls_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+               mbedtls_env.AppendUnique(LIBS = ['mbedx509', 'mbedcrypto'])
+               static_libmbedtls = mbedtls_env.StaticLibrary('mbedtls', mbedtls_src)
+               shared_libmbedtls = mbedtls_env.SharedLibrary('mbedtls', mbedtls_src)
+               mbedtls_env.InstallTarget([static_libmbedtls, shared_libmbedtls], 'mbedtls')
+               mbedtls_env.UserInstallTargetLib([static_libmbedtls, shared_libmbedtls], 'mbedtls')
+       if target_os in ['android']:
+               mbedtls_env.AppendUnique(LINKFLAGS = ['-Wl,-soname,libmbedtls.so'])
diff --git a/extlibs/mbedtls/mbedtls/library/net.c b/extlibs/mbedtls/mbedtls/library/net.c
new file mode 100644 (file)
index 0000000..4142bc0
--- /dev/null
@@ -0,0 +1,586 @@
+/*
+ *  TCP/IP or UDP/IP networking functions
+ *
+ *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
+ *  SPDX-License-Identifier: Apache-2.0
+ *
+ *  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 is part of mbed TLS (https://tls.mbed.org)
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_NET_C)
+
+#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
+    !defined(__APPLE__) && !defined(_WIN32)
+#error "This module only works on Unix and Windows, see MBEDTLS_NET_C in config.h"
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#define mbedtls_time_t    time_t
+#endif
+
+#include "mbedtls/net.h"
+
+#include <string.h>
+
+#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \
+    !defined(EFI32)
+
+#ifdef _WIN32_WINNT
+#undef _WIN32_WINNT
+#endif
+/* Enables getaddrinfo() & Co */
+#define _WIN32_WINNT 0x0501
+#include <ws2tcpip.h>
+
+#include <winsock2.h>
+#include <windows.h>
+
+#if defined(_MSC_VER)
+#if defined(_WIN32_WCE)
+#pragma comment( lib, "ws2.lib" )
+#else
+#pragma comment( lib, "ws2_32.lib" )
+#endif
+#endif /* _MSC_VER */
+
+#define read(fd,buf,len)        recv(fd,(char*)buf,(int) len,0)
+#define write(fd,buf,len)       send(fd,(char*)buf,(int) len,0)
+#define close(fd)               closesocket(fd)
+
+static int wsa_init_done = 0;
+
+#else /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <errno.h>
+
+#endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
+
+/* Some MS functions want int and MSVC warns if we pass size_t,
+ * but the standard fucntions use socklen_t, so cast only for MSVC */
+#if defined(_MSC_VER)
+#define MSVC_INT_CAST   (int)
+#else
+#define MSVC_INT_CAST
+#endif
+
+#include <stdio.h>
+
+#include <time.h>
+
+#include <stdint.h>
+
+/*
+ * Prepare for using the sockets interface
+ */
+static int net_prepare( void )
+{
+#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
+    !defined(EFI32)
+    WSADATA wsaData;
+
+    if( wsa_init_done == 0 )
+    {
+        if( WSAStartup( MAKEWORD(2,0), &wsaData ) != 0 )
+            return( MBEDTLS_ERR_NET_SOCKET_FAILED );
+
+        wsa_init_done = 1;
+    }
+#else
+#if !defined(EFIX64) && !defined(EFI32)
+    signal( SIGPIPE, SIG_IGN );
+#endif
+#endif
+    return( 0 );
+}
+
+/*
+ * Initialize a context
+ */
+void mbedtls_net_init( mbedtls_net_context *ctx )
+{
+    ctx->fd = -1;
+}
+
+/*
+ * Initiate a TCP connection with host:port and the given protocol
+ */
+int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char *port, int proto )
+{
+    int ret;
+    struct addrinfo hints, *addr_list, *cur;
+
+    if( ( ret = net_prepare() ) != 0 )
+        return( ret );
+
+    /* Do name resolution with both IPv6 and IPv4 */
+    memset( &hints, 0, sizeof( hints ) );
+    hints.ai_family = AF_UNSPEC;
+    hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
+    hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
+
+    if( getaddrinfo( host, port, &hints, &addr_list ) != 0 )
+        return( MBEDTLS_ERR_NET_UNKNOWN_HOST );
+
+    /* Try the sockaddrs until a connection succeeds */
+    ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
+    for( cur = addr_list; cur != NULL; cur = cur->ai_next )
+    {
+        ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype,
+                            cur->ai_protocol );
+        if( ctx->fd < 0 )
+        {
+            ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
+            continue;
+        }
+
+        if( connect( ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen ) == 0 )
+        {
+            ret = 0;
+            break;
+        }
+
+        close( ctx->fd );
+        ret = MBEDTLS_ERR_NET_CONNECT_FAILED;
+    }
+
+    freeaddrinfo( addr_list );
+
+    return( ret );
+}
+
+/*
+ * Create a listening socket on bind_ip:port
+ */
+int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto )
+{
+    int n, ret;
+    struct addrinfo hints, *addr_list, *cur;
+
+    if( ( ret = net_prepare() ) != 0 )
+        return( ret );
+
+    /* Bind to IPv6 and/or IPv4, but only in the desired protocol */
+    memset( &hints, 0, sizeof( hints ) );
+    hints.ai_family = AF_UNSPEC;
+    hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
+    hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
+    if( bind_ip == NULL )
+        hints.ai_flags = AI_PASSIVE;
+
+    if( getaddrinfo( bind_ip, port, &hints, &addr_list ) != 0 )
+        return( MBEDTLS_ERR_NET_UNKNOWN_HOST );
+
+    /* Try the sockaddrs until a binding succeeds */
+    ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
+    for( cur = addr_list; cur != NULL; cur = cur->ai_next )
+    {
+        ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype,
+                            cur->ai_protocol );
+        if( ctx->fd < 0 )
+        {
+            ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
+            continue;
+        }
+
+        n = 1;
+        if( setsockopt( ctx->fd, SOL_SOCKET, SO_REUSEADDR,
+                        (const char *) &n, sizeof( n ) ) != 0 )
+        {
+            close( ctx->fd );
+            ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
+            continue;
+        }
+
+        if( bind( ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen ) != 0 )
+        {
+            close( ctx->fd );
+            ret = MBEDTLS_ERR_NET_BIND_FAILED;
+            continue;
+        }
+
+        /* Listen only makes sense for TCP */
+        if( proto == MBEDTLS_NET_PROTO_TCP )
+        {
+            if( listen( ctx->fd, MBEDTLS_NET_LISTEN_BACKLOG ) != 0 )
+            {
+                close( ctx->fd );
+                ret = MBEDTLS_ERR_NET_LISTEN_FAILED;
+                continue;
+            }
+        }
+
+        /* I we ever get there, it's a success */
+        ret = 0;
+        break;
+    }
+
+    freeaddrinfo( addr_list );
+
+    return( ret );
+
+}
+
+#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
+    !defined(EFI32)
+/*
+ * Check if the requested operation would be blocking on a non-blocking socket
+ * and thus 'failed' with a negative return value.
+ */
+static int net_would_block( const mbedtls_net_context *ctx )
+{
+    ((void) ctx);
+    return( WSAGetLastError() == WSAEWOULDBLOCK );
+}
+#else
+/*
+ * Check if the requested operation would be blocking on a non-blocking socket
+ * and thus 'failed' with a negative return value.
+ *
+ * Note: on a blocking socket this function always returns 0!
+ */
+static int net_would_block( const mbedtls_net_context *ctx )
+{
+    /*
+     * Never return 'WOULD BLOCK' on a non-blocking socket
+     */
+    if( ( fcntl( ctx->fd, F_GETFL ) & O_NONBLOCK ) != O_NONBLOCK )
+        return( 0 );
+
+    switch( errno )
+    {
+#if defined EAGAIN
+        case EAGAIN:
+#endif
+#if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN
+        case EWOULDBLOCK:
+#endif
+            return( 1 );
+    }
+    return( 0 );
+}
+#endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
+
+/*
+ * Accept a connection from a remote client
+ */
+int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
+                        mbedtls_net_context *client_ctx,
+                        void *client_ip, size_t buf_size, size_t *ip_len )
+{
+    int ret;
+    int type;
+
+    struct sockaddr_storage client_addr;
+
+#if defined(__socklen_t_defined) || defined(_SOCKLEN_T) ||  \
+    defined(_SOCKLEN_T_DECLARED) || defined(__DEFINED_socklen_t)
+    socklen_t n = (socklen_t) sizeof( client_addr );
+    socklen_t type_len = (socklen_t) sizeof( type );
+#else
+    int n = (int) sizeof( client_addr );
+    int type_len = (int) sizeof( type );
+#endif
+
+    /* Is this a TCP or UDP socket? */
+    if( getsockopt( bind_ctx->fd, SOL_SOCKET, SO_TYPE,
+                    (void *) &type, &type_len ) != 0 ||
+        ( type != SOCK_STREAM && type != SOCK_DGRAM ) )
+    {
+        return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
+    }
+
+    if( type == SOCK_STREAM )
+    {
+        /* TCP: actual accept() */
+        ret = client_ctx->fd = (int) accept( bind_ctx->fd,
+                                         (struct sockaddr *) &client_addr, &n );
+    }
+    else
+    {
+        /* UDP: wait for a message, but keep it in the queue */
+        char buf[1] = { 0 };
+
+        ret = (int) recvfrom( bind_ctx->fd, buf, sizeof( buf ), MSG_PEEK,
+                        (struct sockaddr *) &client_addr, &n );
+
+#if defined(_WIN32)
+        if( ret == SOCKET_ERROR &&
+            WSAGetLastError() == WSAEMSGSIZE )
+        {
+            /* We know buf is too small, thanks, just peeking here */
+            ret = 0;
+        }
+#endif
+    }
+
+    if( ret < 0 )
+    {
+        if( net_would_block( bind_ctx ) != 0 )
+            return( MBEDTLS_ERR_SSL_WANT_READ );
+
+        return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
+    }
+
+    /* UDP: hijack the listening socket to communicate with the client,
+     * then bind a new socket to accept new connections */
+    if( type != SOCK_STREAM )
+    {
+        struct sockaddr_storage local_addr;
+        int one = 1;
+
+        if( connect( bind_ctx->fd, (struct sockaddr *) &client_addr, n ) != 0 )
+            return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
+
+        client_ctx->fd = bind_ctx->fd;
+        bind_ctx->fd   = -1; /* In case we exit early */
+
+        n = sizeof( struct sockaddr_storage );
+        if( getsockname( client_ctx->fd,
+                         (struct sockaddr *) &local_addr, &n ) != 0 ||
+            ( bind_ctx->fd = (int) socket( local_addr.ss_family,
+                                           SOCK_DGRAM, IPPROTO_UDP ) ) < 0 ||
+            setsockopt( bind_ctx->fd, SOL_SOCKET, SO_REUSEADDR,
+                        (const char *) &one, sizeof( one ) ) != 0 )
+        {
+            return( MBEDTLS_ERR_NET_SOCKET_FAILED );
+        }
+
+        if( bind( bind_ctx->fd, (struct sockaddr *) &local_addr, n ) != 0 )
+        {
+            return( MBEDTLS_ERR_NET_BIND_FAILED );
+        }
+    }
+
+    if( client_ip != NULL )
+    {
+        if( client_addr.ss_family == AF_INET )
+        {
+            struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr;
+            *ip_len = sizeof( addr4->sin_addr.s_addr );
+
+            if( buf_size < *ip_len )
+                return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL );
+
+            memcpy( client_ip, &addr4->sin_addr.s_addr, *ip_len );
+        }
+        else
+        {
+            struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &client_addr;
+            *ip_len = sizeof( addr6->sin6_addr.s6_addr );
+
+            if( buf_size < *ip_len )
+                return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL );
+
+            memcpy( client_ip, &addr6->sin6_addr.s6_addr, *ip_len);
+        }
+    }
+
+    return( 0 );
+}
+
+/*
+ * Set the socket blocking or non-blocking
+ */
+int mbedtls_net_set_block( mbedtls_net_context *ctx )
+{
+#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
+    !defined(EFI32)
+    u_long n = 0;
+    return( ioctlsocket( ctx->fd, FIONBIO, &n ) );
+#else
+    return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL ) & ~O_NONBLOCK ) );
+#endif
+}
+
+int mbedtls_net_set_nonblock( mbedtls_net_context *ctx )
+{
+#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
+    !defined(EFI32)
+    u_long n = 1;
+    return( ioctlsocket( ctx->fd, FIONBIO, &n ) );
+#else
+    return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL ) | O_NONBLOCK ) );
+#endif
+}
+
+/*
+ * Portable usleep helper
+ */
+void mbedtls_net_usleep( unsigned long usec )
+{
+#if defined(_WIN32)
+    Sleep( ( usec + 999 ) / 1000 );
+#else
+    struct timeval tv;
+    tv.tv_sec  = usec / 1000000;
+#if defined(__unix__) || defined(__unix) || \
+    ( defined(__APPLE__) && defined(__MACH__) )
+    tv.tv_usec = (suseconds_t) usec % 1000000;
+#else
+    tv.tv_usec = usec % 1000000;
+#endif
+    select( 0, NULL, NULL, NULL, &tv );
+#endif
+}
+
+/*
+ * Read at most 'len' characters
+ */
+int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len )
+{
+    int ret;
+    int fd = ((mbedtls_net_context *) ctx)->fd;
+
+    if( fd < 0 )
+        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
+
+    ret = (int) read( fd, buf, len );
+
+    if( ret < 0 )
+    {
+        if( net_would_block( ctx ) != 0 )
+            return( MBEDTLS_ERR_SSL_WANT_READ );
+
+#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
+    !defined(EFI32)
+        if( WSAGetLastError() == WSAECONNRESET )
+            return( MBEDTLS_ERR_NET_CONN_RESET );
+#else
+        if( errno == EPIPE || errno == ECONNRESET )
+            return( MBEDTLS_ERR_NET_CONN_RESET );
+
+        if( errno == EINTR )
+            return( MBEDTLS_ERR_SSL_WANT_READ );
+#endif
+
+        return( MBEDTLS_ERR_NET_RECV_FAILED );
+    }
+
+    return( ret );
+}
+
+/*
+ * Read at most 'len' characters, blocking for at most 'timeout' ms
+ */
+int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len,
+                      uint32_t timeout )
+{
+    int ret;
+    struct timeval tv;
+    fd_set read_fds;
+    int fd = ((mbedtls_net_context *) ctx)->fd;
+
+    if( fd < 0 )
+        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
+
+    FD_ZERO( &read_fds );
+    FD_SET( fd, &read_fds );
+
+    tv.tv_sec  = timeout / 1000;
+    tv.tv_usec = ( timeout % 1000 ) * 1000;
+
+    ret = select( fd + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv );
+
+    /* Zero fds ready means we timed out */
+    if( ret == 0 )
+        return( MBEDTLS_ERR_SSL_TIMEOUT );
+
+    if( ret < 0 )
+    {
+#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
+    !defined(EFI32)
+        if( WSAGetLastError() == WSAEINTR )
+            return( MBEDTLS_ERR_SSL_WANT_READ );
+#else
+        if( errno == EINTR )
+            return( MBEDTLS_ERR_SSL_WANT_READ );
+#endif
+
+        return( MBEDTLS_ERR_NET_RECV_FAILED );
+    }
+
+    /* This call will not block */
+    return( mbedtls_net_recv( ctx, buf, len ) );
+}
+
+/*
+ * Write at most 'len' characters
+ */
+int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len )
+{
+    int ret;
+    int fd = ((mbedtls_net_context *) ctx)->fd;
+
+    if( fd < 0 )
+        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
+
+    ret = (int) write( fd, buf, len );
+
+    if( ret < 0 )
+    {
+        if( net_would_block( ctx ) != 0 )
+            return( MBEDTLS_ERR_SSL_WANT_WRITE );
+
+#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
+    !defined(EFI32)
+        if( WSAGetLastError() == WSAECONNRESET )
+            return( MBEDTLS_ERR_NET_CONN_RESET );
+#else
+        if( errno == EPIPE || errno == ECONNRESET )
+            return( MBEDTLS_ERR_NET_CONN_RESET );
+
+        if( errno == EINTR )
+            return( MBEDTLS_ERR_SSL_WANT_WRITE );
+#endif
+
+        return( MBEDTLS_ERR_NET_SEND_FAILED );
+    }
+
+    return( ret );
+}
+
+/*
+ * Gracefully close the connection
+ */
+void mbedtls_net_free( mbedtls_net_context *ctx )
+{
+    if( ctx->fd == -1 )
+        return;
+
+    shutdown( ctx->fd, 2 );
+    close( ctx->fd );
+
+    ctx->fd = -1;
+}
+
+#endif /* MBEDTLS_NET_C */
index 945c973..c52ee17 100644 (file)
@@ -1981,7 +1981,7 @@ static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl,
                                       unsigned char **p,
                                       unsigned char *end )
 {
-    int ret = 0;
+        int ret = 0;
     size_t n;
 
     if( ssl->conf->f_psk == NULL &&
@@ -2004,11 +2004,6 @@ static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl,
     n = ( (*p)[0] << 8 ) | (*p)[1];
     *p += 2;
 
-    if (n == 0)
-    {
-        return ( 0 );
-    }
-
     if( n < 1 || n > 65535 || *p + n > end )
     {
         MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
@@ -2432,7 +2427,10 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
 
 // Anonim cipher suite without sign, ecdh param only
 #if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ANON_ENABLED)
-        goto exit;
+        if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ANON )
+        {
+            goto exit;
+        }
 #endif
         /*
          * Read signature
index 2b11ab6..139787a 100644 (file)
@@ -1,8 +1,8 @@
 diff --git a/include/mbedtls/check_config.h b/include/mbedtls/check_config.h
-index fe86c1e..e4583d6 100644
+index a95af6c..a3852b2 100644
 --- a/include/mbedtls/check_config.h
 +++ b/include/mbedtls/check_config.h
-@@ -189,6 +189,11 @@
+@@ -184,6 +184,11 @@
  #error "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED defined, but not all prerequisites"
  #endif
  
@@ -45,10 +45,10 @@ index 27abbd9..fa4db26 100644
  #define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
  #define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
 diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h
-index 6fc9c77..9798b39 100644
+index 3b7c85b..5bef190 100644
 --- a/include/mbedtls/config.h
 +++ b/include/mbedtls/config.h
-@@ -648,6 +648,21 @@
+@@ -642,6 +642,21 @@
  #define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
  
  /**
@@ -70,7 +70,7 @@ index 6fc9c77..9798b39 100644
   * \def MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
   *
   * Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS.
-@@ -1233,7 +1248,7 @@
+@@ -1239,7 +1254,7 @@
   *
   * Comment this macro to disable support for SSL session tickets
   */
@@ -79,7 +79,7 @@ index 6fc9c77..9798b39 100644
  
  /**
   * \def MBEDTLS_SSL_EXPORT_KEYS
-@@ -1473,6 +1488,7 @@
+@@ -1479,6 +1494,7 @@
   *      MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256
   *      MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256
   *      MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA
@@ -88,10 +88,10 @@ index 6fc9c77..9798b39 100644
   * PEM_PARSE uses AES for decrypting encrypted keys.
   */
 diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h
-index ba499d2..8046e6e 100644
+index 82c0760..88103ad 100644
 --- a/include/mbedtls/ssl.h
 +++ b/include/mbedtls/ssl.h
-@@ -358,7 +358,8 @@ union mbedtls_ssl_premaster_secret
+@@ -356,7 +356,8 @@ union mbedtls_ssl_premaster_secret
  #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)    || \
      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED)  || \
      defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED)     || \
@@ -174,10 +174,10 @@ index a116e60..c022caf 100644
  
      return( 0 );
 diff --git a/library/ssl_ciphersuites.c b/library/ssl_ciphersuites.c
-index a762bf7..021ab50 100644
+index 3546331..74cef29 100644
 --- a/library/ssl_ciphersuites.c
 +++ b/library/ssl_ciphersuites.c
-@@ -95,6 +95,7 @@ static const int ciphersuite_preference[] =
+@@ -96,6 +96,7 @@ static const int ciphersuite_preference[] =
      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8,
@@ -185,7 +185,7 @@ index a762bf7..021ab50 100644
  
      /* All CAMELLIA-128 ephemeral suites */
      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256,
-@@ -407,6 +408,22 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
+@@ -408,6 +409,22 @@ static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] =
  #endif /* MBEDTLS_CIPHER_NULL_CIPHER */
  #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
  
@@ -208,7 +208,7 @@ index a762bf7..021ab50 100644
  #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED)
  #if defined(MBEDTLS_AES_C)
  #if defined(MBEDTLS_SHA1_C)
-@@ -1829,6 +1846,7 @@ int mbedtls_ssl_ciphersuite_uses_ec( const mbedtls_ssl_ciphersuite_t *info )
+@@ -1830,6 +1847,7 @@ int mbedtls_ssl_ciphersuite_uses_ec( const mbedtls_ssl_ciphersuite_t *info )
          case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
          case MBEDTLS_KEY_EXCHANGE_ECDH_RSA:
          case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA:
@@ -217,10 +217,10 @@ index a762bf7..021ab50 100644
  
          default:
 diff --git a/library/ssl_cli.c b/library/ssl_cli.c
-index 223823b..945c973 100644
+index cd39db0..1347167 100644
 --- a/library/ssl_cli.c
 +++ b/library/ssl_cli.c
-@@ -1904,7 +1904,8 @@ static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl, unsigned char *
+@@ -1897,7 +1897,8 @@ static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl, unsigned char *
      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) ||                     \
      defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||                      \
@@ -230,7 +230,7 @@ index 223823b..945c973 100644
  static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl )
  {
      const mbedtls_ecp_curve_info *curve_info;
-@@ -1934,11 +1935,13 @@ static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl )
+@@ -1927,11 +1928,13 @@ static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl )
            MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
            MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
            MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
@@ -246,7 +246,7 @@ index 223823b..945c973 100644
  static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl,
                                           unsigned char **p,
                                           unsigned char *end )
-@@ -1970,40 +1973,80 @@ static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl,
+@@ -1963,40 +1966,75 @@ static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl,
  }
  #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
            MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
@@ -262,7 +262,7 @@ index 223823b..945c973 100644
 -    int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
 -    size_t  len;
 -    ((void) ssl);
-+    int ret = 0;
++        int ret = 0;
 +    size_t n;
 +
 +    if( ssl->conf->f_psk == NULL &&
@@ -290,11 +290,12 @@ index 223823b..945c973 100644
      *p += 2;
  
 -    if( (*p) + len > end )
-+    if (n == 0)
++    if( n < 1 || n > 65535 || *p + n > end )
      {
 -        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message (psk_identity_hint length)" ) );
 -        return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
-+        return ( 0 );
++        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
++        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
      }
  
 -    /*
@@ -304,13 +305,6 @@ index 223823b..945c973 100644
 -     */
 -    *p += len;
 -    ret = 0;
-+    if( n < 1 || n > 65535 || *p + n > end )
-+    {
-+        MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
-+        return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
-+    }
--    return( ret );
 +    if( ssl->conf->f_psk != NULL )
 +    {
 +        if( ssl->conf->f_psk( ssl->conf->p_psk, ssl, *p, n ) != 0 )
@@ -326,7 +320,8 @@ index 223823b..945c973 100644
 +            ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY;
 +        }
 +    }
-+
+-    return( ret );
 +    if( ret == MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY )
 +    {
 +        MBEDTLS_SSL_DEBUG_BUF( 3, "Unknown PSK identity", *p, n );
@@ -346,7 +341,7 @@ index 223823b..945c973 100644
  }
  #endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */
  
-@@ -2299,10 +2342,12 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
+@@ -2292,10 +2330,12 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
            MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */
  #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) ||                     \
@@ -361,7 +356,7 @@ index 223823b..945c973 100644
      {
          if( ssl_parse_server_ecdh_params( ssl, &p, end ) != 0 )
          {
-@@ -2313,7 +2358,8 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
+@@ -2306,7 +2346,8 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
      else
  #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
            MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED ||
@@ -371,18 +366,21 @@ index 223823b..945c973 100644
  #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
      if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE )
      {
-@@ -2384,6 +2430,10 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
+@@ -2377,6 +2418,13 @@ static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl )
              return( MBEDTLS_ERR_SSL_INTERNAL_ERROR );
          }
  
 +// Anonim cipher suite without sign, ecdh param only
 +#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ANON_ENABLED)
-+        goto exit;
++        if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ANON )
++        {
++            goto exit;
++        }
 +#endif
          /*
           * Read signature
           */
-@@ -2534,7 +2584,8 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
+@@ -2525,7 +2573,8 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
@@ -392,7 +390,7 @@ index 223823b..945c973 100644
      {
          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
          ssl->state++;
-@@ -2559,7 +2610,8 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
+@@ -2550,7 +2599,8 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
@@ -402,7 +400,7 @@ index 223823b..945c973 100644
      {
          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) );
          ssl->state++;
-@@ -2773,11 +2825,13 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
+@@ -2753,11 +2803,13 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
  #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
      defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||                      \
@@ -418,7 +416,7 @@ index 223823b..945c973 100644
      {
          /*
           * ECDH key exchange -- send client public value
-@@ -2812,7 +2866,8 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
+@@ -2792,7 +2844,8 @@ static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl )
  #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED ||
            MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED ||
            MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED ||
@@ -428,7 +426,7 @@ index 223823b..945c973 100644
  #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
      if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
-@@ -3002,7 +3057,8 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
+@@ -2980,7 +3033,8 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
@@ -438,7 +436,7 @@ index 223823b..945c973 100644
      {
          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
          ssl->state++;
-@@ -3035,7 +3091,8 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
+@@ -3013,7 +3067,8 @@ static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl )
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
@@ -449,10 +447,10 @@ index 223823b..945c973 100644
          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
          ssl->state++;
 diff --git a/library/ssl_srv.c b/library/ssl_srv.c
-index fc0d2d7..6965f1f 100644
+index 7271045..2964015 100644
 --- a/library/ssl_srv.c
 +++ b/library/ssl_srv.c
-@@ -2498,6 +2498,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
+@@ -2500,6 +2500,7 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ||
@@ -460,7 +458,7 @@ index fc0d2d7..6965f1f 100644
          authmode == MBEDTLS_SSL_VERIFY_NONE )
      {
          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) );
-@@ -2675,7 +2676,8 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
+@@ -2677,7 +2678,8 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) ||                     \
      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
@@ -470,7 +468,7 @@ index fc0d2d7..6965f1f 100644
      unsigned char *p = ssl->out_msg + 4;
      unsigned char *dig_signed = p;
      size_t dig_signed_len = 0, len;
-@@ -2736,12 +2738,11 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
+@@ -2738,12 +2740,11 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
      if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK )
      {
@@ -488,7 +486,7 @@ index fc0d2d7..6965f1f 100644
      }
  #endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED ||
            MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */
-@@ -2798,7 +2799,8 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
+@@ -2800,7 +2801,8 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl )
  #if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED)
      if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ||
@@ -498,7 +496,7 @@ index fc0d2d7..6965f1f 100644
      {
          /*
           * Ephemeral ECDH parameters:
-@@ -3336,11 +3338,13 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
+@@ -3338,11 +3340,13 @@ static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl )
  #if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) ||                     \
      defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) ||                   \
      defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) ||                      \
@@ -533,10 +531,10 @@ index fc0d2d7..6965f1f 100644
      {
          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) );
 diff --git a/library/ssl_tls.c b/library/ssl_tls.c
-index 84a04ae..938b840 100644
+index 80a908d..94c8fd7 100644
 --- a/library/ssl_tls.c
 +++ b/library/ssl_tls.c
-@@ -4066,7 +4066,8 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
+@@ -4037,7 +4037,8 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
      if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
@@ -546,7 +544,7 @@ index 84a04ae..938b840 100644
      {
          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
          ssl->state++;
-@@ -4086,7 +4087,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
+@@ -4057,7 +4058,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
      if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
@@ -556,7 +554,7 @@ index 84a04ae..938b840 100644
      {
          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
          ssl->state++;
-@@ -4109,7 +4111,8 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
+@@ -4080,7 +4082,8 @@ int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl )
      if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
@@ -566,7 +564,7 @@ index 84a04ae..938b840 100644
      {
          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
          ssl->state++;
-@@ -4225,7 +4228,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
+@@ -4196,7 +4199,8 @@ int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl )
      if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ||
          ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ||
@@ -576,7 +574,7 @@ index 84a04ae..938b840 100644
      {
          MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
          ssl->state++;
-@@ -7539,6 +7543,7 @@ int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert,
+@@ -7510,6 +7514,7 @@ int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert,
              case MBEDTLS_KEY_EXCHANGE_DHE_PSK:
              case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK:
              case MBEDTLS_KEY_EXCHANGE_ECJPAKE:
@@ -585,7 +583,7 @@ index 84a04ae..938b840 100644
          }
      }
 diff --git a/library/version_features.c b/library/version_features.c
-index e866e67..3184bc2 100644
+index 5d20ba0..6404a0c 100644
 --- a/library/version_features.c
 +++ b/library/version_features.c
 @@ -264,6 +264,9 @@ static const char *features[] = {
@@ -599,7 +597,7 @@ index e866e67..3184bc2 100644
      "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED",
  #endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */
 diff --git a/library/x509_crt.c b/library/x509_crt.c
-index 60e14f9..67cedde 100644
+index af6c2a4..6dcb6aa 100644
 --- a/library/x509_crt.c
 +++ b/library/x509_crt.c
 @@ -62,6 +62,7 @@
index 6fa46b5..e718fa5 100755 (executable)
@@ -11,9 +11,9 @@ sqlite_env = env.Clone()
 target_os = sqlite_env.get('TARGET_OS')
 src_dir = sqlite_env.get('SRC_DIR')
 
-targets_need_sqlite = ['android', 'msys_nt', 'windows', 'ios']
-sqlite_dir = src_dir + '/extlibs/sqlite3/'
-sqlite_build_dir = src_dir + '/extlibs/sqlite3/sqlite-amalgamation-3081101/'
+targets_need_sqlite = ['linux', 'android', 'msys_nt', 'windows', 'ios']
+sqlite_dir      = src_dir + '/extlibs/sqlite3/'
+sqlite_build_dir      = src_dir + '/extlibs/sqlite3/sqlite-amalgamation-3081101/'
 sqlite_zip_file = src_dir + '/extlibs/sqlite3/sqlite-amalgamation-3081101.zip'
 sqlite_url = 'https://www.sqlite.org/2015/sqlite-amalgamation-3081101.zip'
 sqlite_package= 'sqlite-amalgamation-3081101'
@@ -36,5 +36,5 @@ if target_os in targets_need_sqlite:
         sqlite_env.UnpackAll(sqlite_tmp_dir, sqlite_zip_file)
         os.rename(sqlite_c_tmp, sqlite_c)
         os.rename(sqlite_h_tmp, sqlite_h)
-        os.remove(sqlite_zip_file)
+#        os.remove(sqlite_zip_file)
         shutil.rmtree(sqlite_tmp_dir)
index 2377e37..e21b550 100644 (file)
@@ -179,15 +179,9 @@ distcheck: .git
 
 release: .git
        $(MAKE) -f $(MAKEFILE) distcheck
-ifeq ($(VERSION),)
        git -C $(SRCDIR). show HEAD:VERSION | \
          perl -l -n -e '@_ = split /\./; print "$$_[0]." . ($$_[1] + 1)' > $(SRCDIR)VERSION
-else
-       echo "$(VERSION)" > VERSION
-endif
-       if test -n "`git diff VERSION`"; then \
-         git -C $(SRCDIR). commit -s -m "Update version number" VERSION; \
-       fi
+       git -C $(SRCDIR). commit -s -m "Update version number" VERSION
        { echo "TinyCBOR release `cat $(SRCDIR)VERSION`"; \
          echo; \
          echo '# Write something nice about this release here'; \
@@ -200,6 +194,7 @@ endif
        } > $(SRCDIR).git/TAG_EDITMSG
        @`git -C $(SRCDIR). var GIT_EDITOR` $(SRCDIR).git/TAG_EDITMSG
        git -C $(SRCDIR). tag -a -F $(SRCDIR).git/TAG_EDITMSG $(GITTAGFLAGS) v`cat $(SRCDIR)VERSION`
+       $(MAKE) -f $(MAKEFILE) dist
 
 .PHONY: all check silentcheck configure install uninstall
 .PHONY: mostlyclean clean distclean
diff --git a/extlibs/tinycbor/tinycbor/Makefile.configure b/extlibs/tinycbor/tinycbor/Makefile.configure
deleted file mode 100644 (file)
index 28f4c92..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-ALLTESTS = open_memstream funopen fopencookie gc_sections \
-          system-cjson cjson
-MAKEFILE := $(lastword $(MAKEFILE_LIST))
-OUT :=
-
-PROGRAM-open_memstream = extern int open_memstream(); int main() { return open_memstream(); }
-PROGRAM-funopen = extern int funopen(); int main() { return funopen(); }
-PROGRAM-fopencookie = extern int fopencookie(); int main() { return fopencookie(); }
-PROGRAM-gc_sections = int main() {}
-CCFLAGS-gc_sections = -Wl,--gc-sections
-
-PROGRAM-cjson  = \#include <stdlib.h>\n
-PROGRAM-cjson += \#include <cJSON.h>\n
-PROGRAM-cjson += int main() { return cJSON_False; }
-CCFLAGS-cjson = -I$(dir $(MAKEFILE))src/cjson
-PROGRAM-system-cjson = $(PROGRAM-cjson)
-CCFLAGS-system-cjson = -lcJSON
-
-sink:
-       @echo >&2 Please run from the top-level Makefile.
-
-configure: $(foreach it,$(ALLTESTS),check-$(it))
-
-check-%:
-       @echo $(subst check-,,$@)-tested := 1 $(OUT)
-       $(if $(V),,@)if printf "$($(subst check-,PROGRAM-,$@))" | \
-           $(CC) -xc $($(subst check-,CCFLAGS-,$@)) -o /dev/null - $(if $(V),,>/dev/null 2>&1); \
-       then \
-           echo $(subst check-,,$@)-pass := 1 $(OUT); \
-       fi
diff --git a/extlibs/tinycbor/tinycbor/Makefile.nmake b/extlibs/tinycbor/tinycbor/Makefile.nmake
deleted file mode 100644 (file)
index abf50da..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-CFLAGS = -W3
-
-TINYCBOR_HEADERS = src\cbor.h src\cborjson.h
-TINYCBOR_SOURCES = \
-       src\cborerrorstrings.c \
-       src\cborencoder.c \
-       src\cborencoder_close_container_checked.c \
-       src\cborparser.c \
-       src\cborparser_dup_string.c \
-       src\cborpretty.c
-TINYCBOR_OBJS = \
-       src\cborerrorstrings.obj \
-       src\cborencoder.obj \
-       src\cborencoder_close_container_checked.obj \
-       src\cborparser_dup_string.obj \
-       src\cborpretty.obj
-
-all: lib\tinycbor.lib
-check: tests\Makefile lib\tinycbor.lib
-       cd tests & $(MAKE) check
-silentcheck:
-       cd tests & set TESTARGS=-silent & $(MAKE) -s check
-tests\Makefile: tests\tests.pro
-       qmake -o $@ $**
-
-lib\tinycbor.lib: $(TINYCBOR_OBJS)
-       -if not exist lib\NUL md lib
-       lib -nologo /out:$@ $**
-
-mostlyclean:
-       -del $(TINYCBOR_OBJS)
-clean: mostlyclean
-       -del lib\tinycbor.lib
-       if exist tests\Makefile (cd tests & $(MAKE) clean)
-distclean: clean
-       if exist tests\Makefile (cd tests & $(MAKE) distclean)
-
-{src\}.c{src\}.obj:
-       $(CC) -nologo $(CFLAGS) -Isrc -DTINYCBOR_VERSION="" -c -Fo$@ $<
-
index ef3f5a9..afcfe8f 100644 (file)
@@ -163,7 +163,7 @@ struct CborEncoder
     union {
         uint8_t *ptr;
         ptrdiff_t bytes_needed;
-    } data;
+    };
     const uint8_t *end;
     size_t added;
     int flags;
@@ -205,12 +205,12 @@ CBOR_API CborError cbor_encoder_close_container_checked(CborEncoder *encoder, co
 
 CBOR_INLINE_API size_t cbor_encoder_get_buffer_size(const CborEncoder *encoder, const uint8_t *buffer)
 {
-    return (size_t)(encoder->data.ptr - buffer);
+    return (size_t)(encoder->ptr - buffer);
 }
 
 CBOR_INLINE_API size_t cbor_encoder_get_extra_bytes_needed(const CborEncoder *encoder)
 {
-    return encoder->end ? 0 : (size_t)encoder->data.bytes_needed;
+    return encoder->end ? 0 : (size_t)encoder->bytes_needed;
 }
 
 /* Parser API */
index cfe73de..1f69647 100644 (file)
  */
 void cbor_encoder_init(CborEncoder *encoder, uint8_t *buffer, size_t size, int flags)
 {
-    encoder->data.ptr = buffer;
+    encoder->ptr = buffer;
     encoder->end = buffer + size;
     encoder->added = 0;
     encoder->flags = flags;
@@ -239,7 +239,7 @@ static inline void put64(void *where, uint64_t v)
 static inline bool would_overflow(CborEncoder *encoder, size_t len)
 {
     ptrdiff_t remaining = (ptrdiff_t)encoder->end;
-    remaining -= remaining ? (ptrdiff_t)encoder->data.ptr : encoder->data.bytes_needed;
+    remaining -= remaining ? (ptrdiff_t)encoder->ptr : encoder->bytes_needed;
     remaining -= (ptrdiff_t)len;
     return unlikely(remaining < 0);
 }
@@ -247,26 +247,26 @@ static inline bool would_overflow(CborEncoder *encoder, size_t len)
 static inline void advance_ptr(CborEncoder *encoder, size_t n)
 {
     if (encoder->end)
-        encoder->data.ptr += n;
+        encoder->ptr += n;
     else
-        encoder->data.bytes_needed += n;
+        encoder->bytes_needed += n;
 }
 
 static inline CborError append_to_buffer(CborEncoder *encoder, const void *data, size_t len)
 {
     if (would_overflow(encoder, len)) {
         if (encoder->end != NULL) {
-            len -= encoder->end - encoder->data.ptr;
+            len -= encoder->end - encoder->ptr;
             encoder->end = NULL;
-            encoder->data.bytes_needed = 0;
+            encoder->bytes_needed = 0;
         }
 
         advance_ptr(encoder, len);
         return CborErrorOutOfMemory;
     }
 
-    memcpy(encoder->data.ptr, data, len);
-    encoder->data.ptr += len;
+    memcpy(encoder->ptr, data, len);
+    encoder->ptr += len;
     return CborNoError;
 }
 
@@ -451,7 +451,7 @@ __attribute__((noinline))
 static CborError create_container(CborEncoder *encoder, CborEncoder *container, size_t length, uint8_t shiftedMajorType)
 {
     CborError err;
-    container->data.ptr = encoder->data.ptr;
+    container->ptr = encoder->ptr;
     container->end = encoder->end;
     ++encoder->added;
     container->added = 0;
@@ -528,9 +528,9 @@ CborError cbor_encoder_create_map(CborEncoder *encoder, CborEncoder *mapEncoder,
 CborError cbor_encoder_close_container(CborEncoder *encoder, const CborEncoder *containerEncoder)
 {
     if (encoder->end)
-        encoder->data.ptr = containerEncoder->data.ptr;
+        encoder->ptr = containerEncoder->ptr;
     else
-        encoder->data.bytes_needed = containerEncoder->data.bytes_needed;
+        encoder->bytes_needed = containerEncoder->bytes_needed;
     encoder->end = containerEncoder->end;
     if (containerEncoder->flags & CborIteratorFlag_UnknownLength)
         return append_byte_to_buffer(encoder, BreakByte);
index 9a1f549..cad8335 100644 (file)
  */
 CborError cbor_encoder_close_container_checked(CborEncoder *encoder, const CborEncoder *containerEncoder)
 {
-    const uint8_t *ptr = encoder->data.ptr;
+    const uint8_t *ptr = encoder->ptr;
     CborError err = cbor_encoder_close_container(encoder, containerEncoder);
     if (containerEncoder->flags & CborIteratorFlag_UnknownLength || encoder->end == NULL)
         return err;
 
     /* check what the original length was */
     uint64_t actually_added;
-    err = extract_number(&ptr, encoder->data.ptr, &actually_added);
+    err = extract_number(&ptr, encoder->ptr, &actually_added);
     if (err)
         return err;
 
diff --git a/extlibs/tinycbor/tinycbor/tools/Makefile b/extlibs/tinycbor/tinycbor/tools/Makefile
deleted file mode 100644 (file)
index fed6108..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-CFLAGS = -O2 -g
-CPPFLAGS = -I../src
-VPATH = cbordump:../src
-
-all: ../bin ../bin/cbordump
-../bin:
-       @-mkdir ../bin
-
-../bin/cbordump: cbordump.o cborparser.o cborparser_dup_string.o cbortojson.o cborerrorstrings.o cborpretty.o
-       $(CC) -o $@ $^
-       $(RM) $^
-
index 96d3ed1..d2839f6 100644 (file)
 #include "cbor.h"
 #include "compilersupport_p.h"
 
+#if defined (__TIZENRT__)
+#include <apps/netutils/cJSON.h>
+#else
 #include <cJSON.h>
+#endif
 
 #include <errno.h>
 #include <math.h>
@@ -332,7 +336,7 @@ encode_double:
                 return err;
 
             *encoder = container;   // restore state
-            encoder->data.ptr = newbuffer + (container.data.ptr - buffer);
+            encoder->ptr = newbuffer + (container.ptr - buffer);
             encoder->end = newbuffer + buffersize;
             buffer = newbuffer;
             goto encode_double;
@@ -483,7 +487,7 @@ int main(int argc, char **argv)
         return EXIT_FAILURE;
     }
 
-    fwrite(buffer, 1, encoder.data.ptr - buffer, stdout);
+    fwrite(buffer, 1, encoder.ptr - buffer, stdout);
     free(buffer);
     return EXIT_SUCCESS;
 }
diff --git a/extlibs/tinydtls/0001-Add-TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256-cipher-su.patch b/extlibs/tinydtls/0001-Add-TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256-cipher-su.patch
deleted file mode 100644 (file)
index 5221174..0000000
+++ /dev/null
@@ -1,746 +0,0 @@
-From 947179cd0d3646359272cc0645e5049e2426f9e0 Mon Sep 17 00:00:00 2001
-From: Sachin Agrawal <sachin.agrawal@intel.com>
-Date: Thu, 6 Aug 2015 15:13:29 -0700
-Subject: [PATCH 1/1] Add TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256 cipher suite
- in tinydtls
-
-[Patch #1] Initial upload
-[Patch #2] Add function to calculate the pre-master key of ECDHE_PSK cipher suite.
-[Patch #3] Update codes according to review comments
-[Patch #4] Modify code alignment.
-
-Change-Id: I70be3a8e9469cc1913373d820b4a3d4f4a6d6d0d
-Signed-off-by: leechul <chuls.lee@samsung.com>
-Signed-off-by: Sachin Agrawal <sachin.agrawal@intel.com>
----
- extlibs/tinydtls/crypto.c            |   41 +++-
- extlibs/tinydtls/crypto.h            |    9 +
- extlibs/tinydtls/dtls.c              |  401 ++++++++++++++++++++++++++++++++--
- extlibs/tinydtls/global.h            |    1 +
- extlibs/tinydtls/tests/dtls-client.c |    8 +-
- 5 files changed, 444 insertions(+), 16 deletions(-)
-
-diff --git a/extlibs/tinydtls/crypto.c b/extlibs/tinydtls/crypto.c
-index 3fbb993..deaf581 100644
---- a/extlibs/tinydtls/crypto.c
-+++ b/extlibs/tinydtls/crypto.c
-@@ -641,6 +641,41 @@ dtls_ecdsa_verify_sig(const unsigned char *pub_key_x,
- }
- #endif /* DTLS_ECC */
-+#if defined(DTLS_PSK) && defined(DTLS_ECC)
-+int dtls_ecdhe_psk_pre_master_secret(unsigned char *psk, size_t psklen,
-+                                     unsigned char *ecc_priv_key,
-+                                     unsigned char *ecc_pub_key_x,
-+                                     unsigned char *ecc_pub_key_y,
-+                                     size_t ecc_key_size,
-+                                     unsigned char *result,
-+                                     size_t result_len)
-+{
-+  uint8_t eccPublicKey[64];
-+  uint8_t eccPrivateKey[32];
-+  unsigned char *p = result;
-+
-+  if (result_len < uECC_BYTES + psklen + (sizeof(uint16) * 2)) {
-+    return -1;
-+  }
-+
-+  dtls_int_to_uint16(p, uECC_BYTES);
-+  p += sizeof(uint16);
-+
-+  memcpy(eccPublicKey, ecc_pub_key_x, 32);
-+  memcpy(eccPublicKey + 32, ecc_pub_key_y, 32);
-+  memcpy(eccPrivateKey, ecc_priv_key, 32);
-+  uECC_shared_secret(eccPublicKey, eccPrivateKey, p);
-+  p += uECC_BYTES;
-+
-+  dtls_int_to_uint16(p, psklen);
-+  p += sizeof(uint16);
-+
-+  memcpy(p, psk, psklen);
-+
-+  return uECC_BYTES + psklen + (sizeof(uint16) * 2);
-+}
-+#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
-+
- int
- dtls_encrypt(const unsigned char *src, size_t length,
-            unsigned char *buf,
-@@ -665,7 +700,8 @@ dtls_encrypt(const unsigned char *src, size_t length,
-         memmove(buf, src, length);
-       ret = dtls_ccm_encrypt(&ctx->data, src, length, buf, nounce, aad, la);
-   }
--  if(cipher == TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256) {
-+  if(cipher == TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256 ||
-+     cipher == TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256) {
-       ret = rijndael_set_key(&ctx->data.ctx, key, 8 * keylen);
-       if (ret < 0) {
-         /* cleanup everything in case the key has the wrong size */
-@@ -708,7 +744,8 @@ dtls_decrypt(const unsigned char *src, size_t length,
-       ret = dtls_ccm_decrypt(&ctx->data, src, length, buf, nounce, aad, la);
-   }
--  if(cipher == TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256) {
-+  if(cipher == TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256 ||
-+     cipher == TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256) {
-       ret = rijndael_set_key(&ctx->data.ctx, key, 8 * keylen);
-       if (ret < 0) {
-         /* cleanup everything in case the key has the wrong size */
-diff --git a/extlibs/tinydtls/crypto.h b/extlibs/tinydtls/crypto.h
-index a81d306..f4cfc66 100644
---- a/extlibs/tinydtls/crypto.h
-+++ b/extlibs/tinydtls/crypto.h
-@@ -39,6 +39,7 @@
- #include "numeric.h"
- #include "hmac.h"
- #include "ccm.h"
-+#include "ecc/ecc.h"
- /* TLS_PSK_WITH_AES_128_CCM_8 */
- #define DTLS_MAC_KEY_LENGTH    0
-@@ -129,6 +130,13 @@ typedef struct {
-   dtls_compression_t compression;             /**< compression method */
-   dtls_cipher_t cipher;               /**< cipher type */
-   unsigned int do_client_auth:1;
-+
-+#ifdef DTLS_ECC && DTLS_PSK
-+  struct keyx_t {
-+    dtls_handshake_parameters_ecc_t ecc;
-+    dtls_handshake_parameters_psk_t psk;
-+  } keyx;
-+#else /* DTLS_ECC && DTLS_PSK */
-   union {
- #ifdef DTLS_ECC
-     dtls_handshake_parameters_ecc_t ecc;
-@@ -137,6 +145,7 @@ typedef struct {
-     dtls_handshake_parameters_psk_t psk;
- #endif /* DTLS_PSK */
-   } keyx;
-+#endif /* DTLS_ECC && DTLS_PSK */
- } dtls_handshake_parameters_t;
- /* The following macros provide access to the components of the
-diff --git a/extlibs/tinydtls/dtls.c b/extlibs/tinydtls/dtls.c
-index b5b8fd1..6104a08 100644
---- a/extlibs/tinydtls/dtls.c
-+++ b/extlibs/tinydtls/dtls.c
-@@ -506,6 +506,17 @@ static inline int is_tls_ecdh_anon_with_aes_128_cbc_sha_256(dtls_cipher_t cipher
- #endif
- }
-+/** returns true if the cipher matches TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256 */
-+static inline int is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(dtls_cipher_t cipher)
-+{
-+#if defined(DTLS_ECC) && defined(DTLS_PSK)
-+  return cipher == TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256;
-+#else
-+  return 0;
-+#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
-+}
-+
-+
- /** returns true if the application is configured for psk */
- static inline int is_psk_supported(dtls_context_t *ctx)
-@@ -549,6 +560,17 @@ static inline int is_ecdh_anon_supported(dtls_context_t *ctx)
- #endif
- }
-+/** returns true if ecdhe_psk_with_aes_128_cbc_sha_256 is supported */
-+static inline int is_ecdhe_psk_supported(dtls_context_t *ctx)
-+{
-+#if defined(DTLS_ECC) && defined(DTLS_PSK)
-+    return is_psk_supported(ctx);
-+#else
-+    return 0;
-+#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
-+}
-+
-+
- /**
-  * Returns @c 1 if @p code is a cipher suite other than @c
-  * TLS_NULL_WITH_NULL_NULL that we recognize.
-@@ -563,14 +585,17 @@ known_cipher(dtls_context_t *ctx, dtls_cipher_t code, int is_client) {
-   int psk;
-   int ecdsa;
-   int ecdh_anon;
-+  int ecdhe_psk;
-   psk = is_psk_supported(ctx);
-   ecdsa = is_ecdsa_supported(ctx, is_client);
-   ecdh_anon = is_ecdh_anon_supported(ctx);
-+  ecdhe_psk = is_ecdhe_psk_supported(ctx);
-   return (psk && is_tls_psk_with_aes_128_ccm_8(code)) ||
-        (ecdsa && is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(code)) ||
--       (ecdh_anon && is_tls_ecdh_anon_with_aes_128_cbc_sha_256(code));
-+       (ecdh_anon && is_tls_ecdh_anon_with_aes_128_cbc_sha_256(code)) ||
-+       (ecdhe_psk && is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(code));
- }
- /**
-@@ -676,7 +701,11 @@ calculate_key_block(dtls_context_t *ctx,
-                   dtls_peer_t *peer,
-                   session_t *session,
-                   dtls_peer_type role) {
--  unsigned char *pre_master_secret;
-+#if defined(DTLS_PSK) && defined(DTLS_ECC)
-+  unsigned char pre_master_secret[MAX_KEYBLOCK_LENGTH + uECC_BYTES];
-+#else
-+  unsigned char pre_master_secret[MAX_KEYBLOCK_LENGTH];
-+#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
-   int pre_master_len = 0;
-   dtls_security_parameters_t *security = dtls_security_params_next(peer);
-   uint8 master_secret[DTLS_MASTER_SECRET_LENGTH];
-@@ -685,8 +714,6 @@ calculate_key_block(dtls_context_t *ctx,
-     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: {
-@@ -733,6 +760,35 @@ calculate_key_block(dtls_context_t *ctx,
-     break;
-   }
- #endif /* DTLS_ECC */
-+#if defined(DTLS_PSK) && defined(DTLS_ECC)
-+    case TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256: {
-+      unsigned char psk[DTLS_PSK_MAX_KEY_LEN];
-+      int psklen;
-+
-+      psklen = 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 (psklen < 0) {
-+        dtls_crit("no psk key for session available\n");
-+        return psklen;
-+      }
-+
-+      pre_master_len = dtls_ecdhe_psk_pre_master_secret(psk, psklen,
-+                           handshake->keyx.ecc.own_eph_priv,
-+                           handshake->keyx.ecc.other_eph_pub_x,
-+                           handshake->keyx.ecc.other_eph_pub_y,
-+                           sizeof(handshake->keyx.ecc.own_eph_priv),
-+                           pre_master_secret,
-+                           MAX_KEYBLOCK_LENGTH + uECC_BYTES);
-+
-+      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 /* defined(DTLS_PSK) && defined(DTLS_ECC)  */
-   default:
-     dtls_crit("calculate_key_block: unknown cipher\n");
-     return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
-@@ -1113,6 +1169,56 @@ check_client_keyexchange(dtls_context_t *ctx,
-     data += sizeof(handshake->keyx.ecc.other_eph_pub_y);
-   }
- #endif /* DTLS_ECC */
-+#if defined(DTLS_PSK) && defined(DTLS_ECC)
-+  if (is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(handshake->cipher)) {
-+    int id_length;
-+
-+    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;
-+
-+    //PSK hint
-+    id_length = dtls_uint16_to_int(data);
-+    data += sizeof(uint16);
-+
-+    if (DTLS_HS_LENGTH + DTLS_CKXPSK_LENGTH_MIN + DTLS_CKXEC_LENGTH + 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);
-+    data += id_length;
-+
-+    //ECDH public
-+    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.ecc.other_eph_pub_x, data,
-+       sizeof(handshake->keyx.ecc.other_eph_pub_x));
-+    data += sizeof(handshake->keyx.ecc.other_eph_pub_x);
-+
-+    memcpy(handshake->keyx.ecc.other_eph_pub_y, data,
-+       sizeof(handshake->keyx.ecc.other_eph_pub_y));
-+    data += sizeof(handshake->keyx.ecc.other_eph_pub_y);
-+  }
-+#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
- #ifdef DTLS_PSK
-   if (is_tls_psk_with_aes_128_ccm_8(handshake->cipher)) {
-     int id_length;
-@@ -1286,7 +1392,8 @@ dtls_prepare_record(dtls_peer_t *peer, dtls_security_parameters_t *security,
-       p += data_len_array[i];
-       res += data_len_array[i];
-     }
--  } else if (is_tls_ecdh_anon_with_aes_128_cbc_sha_256(security->cipher)) {
-+  } else if (is_tls_ecdh_anon_with_aes_128_cbc_sha_256(security->cipher) ||
-+             is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(security->cipher)) {
-     unsigned char nonce[DTLS_CBC_IV_LENGTH];
-@@ -2116,6 +2223,80 @@ dtls_send_server_key_exchange_ecdh(dtls_context_t *ctx, dtls_peer_t *peer,
- }
- #endif /* DTLS_ECC */
-+#if defined(DTLS_PSK) && defined(DTLS_ECC)
-+static int dtls_send_server_key_exchange_ecdhe_psk(dtls_context_t *ctx, dtls_peer_t *peer,
-+                                const unsigned char *psk_hint, size_t psk_hint_len)
-+{
-+  /* 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 + DTLS_SKEXECPSK_LENGTH_MAX + 2];
-+  uint8 *p;
-+  uint8 *ephemeral_pub_x;
-+  uint8 *ephemeral_pub_y;
-+  dtls_handshake_parameters_t *config = peer->handshake_params;
-+
-+  /* ServerKeyExchange
-+    * Please see Session 2, RFC 5489.
-+
-+         struct {
-+          select (KeyExchangeAlgorithm) {
-+              //other cases for rsa, diffie_hellman, etc.
-+              case ec_diffie_hellman_psk:  // NEW
-+                  opaque psk_identity_hint<0..2^16-1>;
-+                  ServerECDHParams params;
-+          };
-+      } ServerKeyExchange; */
-+  p = buf;
-+
-+  assert(psk_hint_len <= DTLS_PSK_MAX_CLIENT_IDENTITY_LEN);
-+  if (psk_hint_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);
-+  }
-+
-+  // psk_identity_hint
-+  dtls_int_to_uint16(p, psk_hint_len);
-+  p += sizeof(uint16);
-+
-+  memcpy(p, psk_hint, psk_hint_len);
-+  p += psk_hint_len;
-+
-+  /* ServerECDHParams. */
-+  /* ECCurveType curve_type: named_curve */
-+  dtls_int_to_uint8(p, TLS_EC_CURVE_TYPE_NAMED_CURVE);
-+  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.ecc.own_eph_priv,
-+              ephemeral_pub_x, ephemeral_pub_y,
-+              DTLS_EC_KEY_SIZE);
-+
-+  assert(p - buf <= sizeof(buf));
-+
-+  return dtls_send_handshake_msg(ctx, peer, DTLS_HT_SERVER_KEY_EXCHANGE,
-+                               buf, p - buf);
-+}
-+#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
-+
- #ifdef DTLS_PSK
- static int
- dtls_send_server_key_exchange_psk(dtls_context_t *ctx, dtls_peer_t *peer,
-@@ -2207,6 +2388,7 @@ dtls_send_server_hello_msgs(dtls_context_t *ctx, dtls_peer_t *peer)
-   int res;
-   int ecdsa;
-   int ecdh_anon;
-+  int ecdhe_psk;
-   res = dtls_send_server_hello(ctx, peer);
-@@ -2217,6 +2399,7 @@ dtls_send_server_hello_msgs(dtls_context_t *ctx, dtls_peer_t *peer)
-   ecdsa = is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher);
-   ecdh_anon = is_tls_ecdh_anon_with_aes_128_cbc_sha_256(peer->handshake_params->cipher);
-+  ecdhe_psk = is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(peer->handshake_params->cipher);
- #ifdef DTLS_ECC
-   if(ecdh_anon) {
-@@ -2261,7 +2444,31 @@ dtls_send_server_hello_msgs(dtls_context_t *ctx, dtls_peer_t *peer)
-     }
-   }
- #endif /* DTLS_ECC */
-+#if defined(DTLS_PSK) && defined(DTLS_ECC)
-+  else if(ecdhe_psk) {
-+    unsigned char psk_hint[DTLS_PSK_MAX_CLIENT_IDENTITY_LEN];
-+    int psk_len;
-+
-+    /* The identity hint is optional, therefore we ignore the result
-+     * and check psk only. */
-+    psk_len = CALL(ctx, get_psk_info, &peer->session, DTLS_PSK_HINT,
-+             NULL, 0, psk_hint, DTLS_PSK_MAX_CLIENT_IDENTITY_LEN);
-+    if (psk_len < 0) {
-+      dtls_debug("dtls_server_hello: cannot create ServerKeyExchange\n");
-+      return psk_len;
-+    }
-+
-+    if (psk_len > 0) {
-+      res = dtls_send_server_key_exchange_ecdhe_psk(ctx, peer, psk_hint, (size_t)psk_len);
-+
-+      if (res < 0) {
-+        dtls_debug("dtls_server_hello(with ECDHE): cannot prepare Server Key Exchange record\n");
-+        return res;
-+      }
-+    }
-+  }
-+#endif /* defined(DTLS_PSK) && defined(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];
-@@ -2308,7 +2515,11 @@ dtls_send_ccs(dtls_context_t *ctx, dtls_peer_t *peer) {
- static int
- dtls_send_client_key_exchange(dtls_context_t *ctx, dtls_peer_t *peer)
- {
-+#if defined(DTLS_PSK) && defined(DTLS_ECC)
-+  uint8 buf[DTLS_CKXEC_LENGTH + 2 + DTLS_PSK_MAX_CLIENT_IDENTITY_LEN];
-+#else
-   uint8 buf[DTLS_CKXEC_LENGTH];
-+#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
-   uint8 client_id[DTLS_PSK_MAX_CLIENT_IDENTITY_LEN];
-   uint8 *p;
-   dtls_handshake_parameters_t *handshake = peer->handshake_params;
-@@ -2368,6 +2579,60 @@ dtls_send_client_key_exchange(dtls_context_t *ctx, dtls_peer_t *peer)
-     break;
-   }
- #endif /* DTLS_ECC */
-+#if defined(DTLS_PSK) && defined(DTLS_ECC)
-+  case TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256: {
-+      int psk_len;
-+      uint8 *ephemeral_pub_x;
-+      uint8 *ephemeral_pub_y;
-+
-+    /* Please see Session 2, RFC 5489.
-+         struct {
-+            select (KeyExchangeAlgorithm) {
-+                // other cases for rsa, diffie_hellman, etc.
-+                case ec_diffie_hellman_psk:
-+                    opaque psk_identity<0..2^16-1>;
-+                    ClientECDiffieHellmanPublic public;
-+            } exchange_keys;
-+        } ClientKeyExchange;
-+    */
-+
-+    psk_len = CALL(ctx, get_psk_info, &peer->session, DTLS_PSK_IDENTITY,
-+               NULL, 0,
-+               client_id,
-+               sizeof(client_id));
-+    if (psk_len < 0) {
-+      dtls_crit("no psk identity set in kx\n");
-+      return psk_len;
-+    }
-+
-+    if (psk_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, psk_len);
-+    p += sizeof(uint16);
-+
-+    memcpy(p, client_id, psk_len);
-+    p += psk_len;
-+
-+    dtls_int_to_uint8(p, 1 + 2 * DTLS_EC_KEY_SIZE);
-+    p += sizeof(uint8);
-+
-+    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.ecc.own_eph_priv,
-+                          ephemeral_pub_x, ephemeral_pub_y,
-+                          DTLS_EC_KEY_SIZE);
-+    break;
-+  }
-+#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
-   default:
-     dtls_crit("cipher not supported\n");
-     return dtls_alert_fatal_create(DTLS_ALERT_INTERNAL_ERROR);
-@@ -2457,6 +2722,7 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
-   int psk = 0;
-   int ecdsa = 0;
-   int ecdh_anon = 0;
-+  int ecdhe_psk = 0;
-   dtls_handshake_parameters_t *handshake = peer->handshake_params;
-   dtls_tick_t now;
-@@ -2471,14 +2737,18 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
-       case TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256:
-         ecdh_anon = is_ecdh_anon_supported(ctx);
-         break;
-+      case TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256:
-+        ecdhe_psk = is_ecdhe_psk_supported(ctx);
-+        break;
-       default:
-         psk = is_psk_supported(ctx);
-         ecdsa = is_ecdsa_supported(ctx, 1);
-         ecdh_anon = is_ecdh_anon_supported(ctx);
-+        ecdhe_psk = is_ecdhe_psk_supported(ctx);
-         break;
-    }
--  cipher_size = 2 + (ecdsa ? 2 : 0) + (psk ? 2 : 0) + (ecdh_anon ? 2 : 0);
-+  cipher_size = 2 + (ecdsa ? 2 : 0) + (psk ? 2 : 0) + (ecdh_anon ? 2 : 0) + (ecdhe_psk ? 2 : 0);
-   extension_size = (ecdsa) ? (2 + 6 + 6 + 8 + 6) : 0;
-   if (cipher_size == 0) {
-@@ -2533,6 +2803,10 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
-     dtls_int_to_uint16(p, TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8);
-     p += sizeof(uint16);
-   }
-+  if (ecdhe_psk) {
-+      dtls_int_to_uint16(p, TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256);
-+      p += sizeof(uint16);
-+  }
-   /* compression method */
-   dtls_int_to_uint8(p, 1);
-@@ -2900,8 +3174,97 @@ check_server_key_exchange_ecdh(dtls_context_t *ctx,
-   return 0;
- }
--
- #endif /* DTLS_ECC */
-+#if defined(DTLS_PSK) && defined(DTLS_ECC)
-+check_server_key_exchange_ecdhe_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 psk_len = 0;
-+
-+  /* ServerKeyExchange
-+    * Please see Session 2, RFC 5489.
-+
-+         struct {
-+          select (KeyExchangeAlgorithm) {
-+              //other cases for rsa, diffie_hellman, etc.
-+              case ec_diffie_hellman_psk:  // NEW
-+                  opaque psk_identity_hint<0..2^16-1>;
-+                  ServerECDHParams params;
-+          };
-+      } ServerKeyExchange; */
-+
-+  update_hs_hash(peer, data, data_length);
-+
-+  assert(is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(config->cipher));
-+
-+  data += DTLS_HS_LENGTH;
-+
-+  psk_len = dtls_uint16_to_int(data);
-+  data += sizeof(uint16);
-+
-+  if (psk_len != data_length - DTLS_HS_LENGTH - DTLS_SKEXEC_ECDH_ANON_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 (psk_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 = psk_len;
-+  memcpy(config->keyx.psk.identity, data, psk_len);
-+
-+  data += psk_len;
-+  data_length -= psk_len;
-+
-+  if (data_length < DTLS_HS_LENGTH + DTLS_SKEXEC_ECDH_ANON_LENGTH) {
-+    dtls_alert("the packet length does not match the expected\n");
-+    return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR);
-+  }
-+
-+  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.ecc.other_eph_pub_x, data, sizeof(config->keyx.ecc.other_eph_pub_x));
-+  data += sizeof(config->keyx.ecc.other_eph_pub_x);
-+  data_length -= sizeof(config->keyx.ecc.other_eph_pub_x);
-+
-+  memcpy(config->keyx.ecc.other_eph_pub_y, data, sizeof(config->keyx.ecc.other_eph_pub_y));
-+  data += sizeof(config->keyx.ecc.other_eph_pub_y);
-+  data_length -= sizeof(config->keyx.ecc.other_eph_pub_y);
-+
-+  return 0;
-+}
-+#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
- #ifdef DTLS_PSK
- static int
-@@ -3113,7 +3476,8 @@ decrypt_verify(dtls_peer_t *peer, uint8 *packet, size_t length,
-   if (security->cipher == TLS_NULL_WITH_NULL_NULL) {
-     /* no cipher suite selected */
-     return clen;
--  } else if (is_tls_ecdh_anon_with_aes_128_cbc_sha_256(security->cipher)) {
-+  } else if (is_tls_ecdh_anon_with_aes_128_cbc_sha_256(security->cipher) ||
-+             is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(security->cipher)) {
-     unsigned char nonce[DTLS_CBC_IV_LENGTH];
-@@ -3169,17 +3533,17 @@ decrypt_verify(dtls_peer_t *peer, uint8 *packet, size_t length,
-                      dtls_kb_remote_write_key(security, peer->role),
-                      dtls_kb_key_size(security, peer->role),
-                      A_DATA, A_DATA_LEN,
--                     security->cipher);
-+                     security->cipher);
-   }
-   if (clen < 0)
-     dtls_warn("decryption failed\n");
-   else {
- #ifndef NDEBUG
--      dtls_debug("decrypt_verify(): found %i bytes cleartext\n", clen);
-+    dtls_debug("decrypt_verify(): found %i bytes cleartext\n", clen);
- #endif
--      dtls_security_params_free_other(peer);
--      dtls_debug_dump("cleartext", *cleartext, clen);
-+    dtls_security_params_free_other(peer);
-+    dtls_debug_dump("cleartext", *cleartext, clen);
-   }
-   return clen;
-@@ -3282,7 +3646,8 @@ handle_handshake_msg(dtls_context_t *ctx, dtls_peer_t *peer, session_t *session,
-     }
-     if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher))
-       peer->state = DTLS_STATE_WAIT_SERVERCERTIFICATE; //ecdsa
--    else if (is_tls_ecdh_anon_with_aes_128_cbc_sha_256(peer->handshake_params->cipher))
-+    else if (is_tls_ecdh_anon_with_aes_128_cbc_sha_256(peer->handshake_params->cipher) ||
-+        is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(peer->handshake_params->cipher))
-         peer->state = DTLS_STATE_WAIT_SERVERKEYEXCHANGE; //ecdh
-     else
-       peer->state = DTLS_STATE_WAIT_SERVERHELLODONE; //psk
-@@ -3329,6 +3694,16 @@ handle_handshake_msg(dtls_context_t *ctx, dtls_peer_t *peer, session_t *session,
-       err = check_server_key_exchange_ecdh(ctx, peer, data, data_length);
-     }
- #endif /* DTLS_ECC */
-+
-+#if defined(DTLS_PSK) && defined(DTLS_ECC)
-+    if (is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(peer->handshake_params->cipher)) {
-+        if (state != DTLS_STATE_WAIT_SERVERKEYEXCHANGE) {
-+          return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE);
-+        }
-+      err = check_server_key_exchange_ecdhe_psk(ctx, peer, data, data_length);
-+    }
-+#endif defined(DTLS_PSK) && defined(DTLS_ECC)
-+
- #ifdef DTLS_PSK
-     if (is_tls_psk_with_aes_128_ccm_8(peer->handshake_params->cipher)) {
-       if (state != DTLS_STATE_WAIT_SERVERHELLODONE) {
-diff --git a/extlibs/tinydtls/global.h b/extlibs/tinydtls/global.h
-index 169c726..8b3c518 100644
---- a/extlibs/tinydtls/global.h
-+++ b/extlibs/tinydtls/global.h
-@@ -75,6 +75,7 @@ typedef enum {
-   TLS_NULL_WITH_NULL_NULL = 0x0000,   /**< NULL cipher  */
-   TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256 = 0xC018, /**< see RFC 4492 */
-   TLS_PSK_WITH_AES_128_CCM_8 = 0xC0A8, /**< see RFC 6655 */
-+  TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256 = 0xC037, /**< see RFC 5489 */
-   TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 = 0xC0AE /**< see RFC 7251 */
- } dtls_cipher_t;
-diff --git a/extlibs/tinydtls/tests/dtls-client.c b/extlibs/tinydtls/tests/dtls-client.c
-index dfc822a..dfd34c8 100644
---- a/extlibs/tinydtls/tests/dtls-client.c
-+++ b/extlibs/tinydtls/tests/dtls-client.c
-@@ -311,7 +311,8 @@ usage( const char *program, const char *version) {
-           "\t-c num\t\tcipher suite (default: 1)\n"
-           "\t\t\t1: TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256 \n"
-           "\t\t\t2: TLS_PSK_WITH_AES_128_CCM_8\n"
--          "\t\t\t3: TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8\n",
-+          "\t\t\t3: TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8\n"
-+          "\t\t\t4: TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256\n",
-          program, version, program, DEFAULT_PORT);
- }
-@@ -430,6 +431,11 @@ main(int argc, char **argv) {
-           selected_cipher = TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 ;
-           ecdh_anon_enalbe = DTLS_CIPHER_DISABLE;
-       }
-+      else if( strcmp(optarg, "4") == 0)
-+      {
-+          selected_cipher = TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256;
-+          ecdh_anon_enalbe = DTLS_CIPHER_DISABLE;
-+      }
-       break;
-     default:
-       usage(argv[0], dtls_package_version());
--- 
-1.7.9.5
-
diff --git a/extlibs/tinydtls/0001-Added-anonymous-ecdh-cipher-suite-into-tinydtls.patch b/extlibs/tinydtls/0001-Added-anonymous-ecdh-cipher-suite-into-tinydtls.patch
deleted file mode 100644 (file)
index ba75317..0000000
+++ /dev/null
@@ -1,1164 +0,0 @@
-From bdfe0e312f9c2cd34df7bfff070dfe8a9e82d147 Mon Sep 17 00:00:00 2001
-From: leechul <chuls.lee@samsung.com>
-Date: Thu, 9 Apr 2015 16:25:43 +0900
-Subject: [PATCH 1/1] Added anonymous ecdh cipher suite into tinydtls
-
-Change-Id: I80fa2985587618ebe7debdacba45996614c4cf1b
-Signed-off-by: leechul <chuls.lee@samsung.com>
-Signed-off-by: Sachin Agrawal <sachin.agrawal@intel.com>
----
- extlibs/tinydtls/aes/rijndael.h      |    1 +
- extlibs/tinydtls/crypto.c            |  173 ++++++++++++++++---
- extlibs/tinydtls/crypto.h            |   15 +-
- extlibs/tinydtls/dtls.c              |  301 +++++++++++++++++++++++++---------
- extlibs/tinydtls/dtls.h              |   28 +++-
- extlibs/tinydtls/global.h            |    6 +
- extlibs/tinydtls/tests/dtls-client.c |   42 ++++-
- extlibs/tinydtls/tests/dtls-server.c |   21 ++-
- 8 files changed, 468 insertions(+), 119 deletions(-)
- mode change 100755 => 100644 extlibs/tinydtls/crypto.c
-
-diff --git a/extlibs/tinydtls/aes/rijndael.h b/extlibs/tinydtls/aes/rijndael.h
-index 60e9bef..712798b 100755
---- a/extlibs/tinydtls/aes/rijndael.h
-+++ b/extlibs/tinydtls/aes/rijndael.h
-@@ -30,6 +30,7 @@
- #include <stdint.h>
-+#define WITH_AES_DECRYPT 1
- #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 */
-diff --git a/extlibs/tinydtls/crypto.c b/extlibs/tinydtls/crypto.c
-old mode 100755
-new mode 100644
-index 0113342..0ea1546
---- a/extlibs/tinydtls/crypto.c
-+++ b/extlibs/tinydtls/crypto.c
-@@ -54,6 +54,8 @@
- #include "crypto.h"
- #include "ccm.h"
- #include "ecc/ecc.h"
-+#include "aes/rijndael.h"
-+#include "sha2/sha2.h"
- #include "prng.h"
- #include "netq.h"
-@@ -292,7 +294,7 @@ dtls_mac(dtls_hmac_context_t *hmac_ctx,
- }
- static size_t
--dtls_ccm_encrypt(aes128_ccm_t *ccm_ctx, const unsigned char *src, size_t srclen,
-+dtls_ccm_encrypt(aes128_t *ccm_ctx, const unsigned char *src, size_t srclen,
-                unsigned char *buf,
-                unsigned char *nounce,
-                const unsigned char *aad, size_t la) {
-@@ -309,7 +311,7 @@ dtls_ccm_encrypt(aes128_ccm_t *ccm_ctx, const unsigned char *src, size_t srclen,
- }
- static size_t
--dtls_ccm_decrypt(aes128_ccm_t *ccm_ctx, const unsigned char *src,
-+dtls_ccm_decrypt(aes128_t *ccm_ctx, const unsigned char *src,
-                size_t srclen, unsigned char *buf,
-                unsigned char *nounce,
-                const unsigned char *aad, size_t la) {
-@@ -325,6 +327,95 @@ dtls_ccm_decrypt(aes128_ccm_t *ccm_ctx, const unsigned char *src,
-   return len;
- }
-+static size_t
-+dtls_cbc_encrypt(aes128_t *aes_ctx,
-+                 const unsigned char *iv,
-+                 const unsigned char *src, size_t srclen,
-+                 unsigned char *buf) {
-+
-+    unsigned char cbc[DTLS_BLK_LENGTH];
-+    unsigned char tmp[DTLS_BLK_LENGTH];
-+    unsigned char *pos;
-+    dtls_hash_ctx shactx;
-+    int i, j;
-+    int blocks;
-+
-+    pos = buf;
-+
-+    dtls_hash_init(&shactx);
-+    dtls_hash_update(&shactx, src, srclen);
-+    dtls_hash_finalize(pos + srclen, &shactx);
-+
-+    memcpy(cbc, iv, DTLS_BLK_LENGTH);
-+    blocks = (srclen + SHA256_DIGEST_LENGTH) / DTLS_BLK_LENGTH;
-+
-+    for (i = 0; i < blocks; i++) {
-+        for (j = 0; j < DTLS_BLK_LENGTH; j++) {
-+            cbc[j] ^= pos[j];
-+        }
-+
-+        rijndael_encrypt(&aes_ctx->ctx, cbc, tmp);
-+        memcpy(cbc, tmp, DTLS_BLK_LENGTH);
-+        memcpy(pos, cbc, DTLS_BLK_LENGTH);
-+        pos += DTLS_BLK_LENGTH;
-+    }
-+
-+    dtls_debug_dump("Encrypted Data:", buf, srclen + SHA256_DIGEST_LENGTH);
-+
-+    return srclen + SHA256_DIGEST_LENGTH;
-+}
-+
-+
-+static size_t
-+dtls_cbc_decrypt(aes128_t *aes_ctx,
-+                 const unsigned char *iv,
-+                 const unsigned char *src, size_t srclen,
-+                 unsigned char *buf) {
-+
-+    unsigned char cbc[DTLS_BLK_LENGTH];
-+    unsigned char tmp[DTLS_BLK_LENGTH];
-+    unsigned char tmp2[DTLS_BLK_LENGTH];
-+    unsigned char msg_hash[SHA256_DIGEST_LENGTH];
-+    unsigned char *pos;
-+    dtls_hash_ctx shactx;
-+    int i, j;
-+    int blocks;
-+
-+    pos = buf;
-+    memcpy(pos, src, srclen);
-+
-+    memcpy(cbc, iv, DTLS_BLK_LENGTH);
-+    blocks = srclen / DTLS_BLK_LENGTH;
-+
-+    for (i = 0; i < blocks; i++)
-+    {
-+        memcpy(tmp, pos, DTLS_BLK_LENGTH);
-+        rijndael_decrypt(&aes_ctx->ctx, pos, tmp2);
-+        memcpy(pos, tmp2, DTLS_BLK_LENGTH);
-+
-+        for (j = 0; j < DTLS_BLK_LENGTH; j++) {
-+            pos[j] ^= cbc[j];
-+        }
-+
-+        memcpy(cbc, tmp, DTLS_BLK_LENGTH);
-+        pos += DTLS_BLK_LENGTH;
-+    }
-+
-+    dtls_hash_init(&shactx);
-+    dtls_hash_update(&shactx, buf, srclen - SHA256_DIGEST_LENGTH);
-+    dtls_hash_finalize(msg_hash, &shactx);
-+
-+    dtls_debug_dump("decrypted data:", buf, srclen);
-+
-+    if(memcmp(msg_hash, buf + (srclen - SHA256_DIGEST_LENGTH), SHA256_DIGEST_LENGTH) != 0)
-+    {
-+        dtls_warn("message is broken\n");
-+        return -1;
-+    }
-+
-+    return srclen - SHA256_DIGEST_LENGTH;
-+}
-+
- #ifdef DTLS_PSK
- int
- dtls_psk_pre_master_secret(unsigned char *key, size_t keylen,
-@@ -432,13 +523,10 @@ 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);
-@@ -505,21 +593,37 @@ 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)
-+           const unsigned char *aad, size_t la,
-+           const dtls_cipher_t cipher)
- {
--  int ret;
-+  int ret = 0;
-   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(cipher == TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 ||
-+     cipher == TLS_PSK_WITH_AES_128_CCM_8) {
-+      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);
-+  }
-+  if(cipher == TLS_ECDH_anon_WITH_AES_128_CBC_SHA) {
-+      ret = rijndael_set_key(&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_cbc_encrypt(&ctx->data, nounce, src, length, buf);
-   }
--
--  if (src != buf)
--    memmove(buf, src, length);
--  ret = dtls_ccm_encrypt(&ctx->data, src, length, buf, nounce, aad, la);
- error:
-   dtls_cipher_context_release();
-@@ -531,21 +635,38 @@ 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)
-+           const unsigned char *aad, size_t la,
-+           const dtls_cipher_t cipher)
- {
--  int ret;
-+  int ret = 0;
-   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(cipher == TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 ||
-+     cipher == TLS_PSK_WITH_AES_128_CCM_8) {
-+      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);
-   }
--  if (src != buf)
--    memmove(buf, src, length);
--  ret = dtls_ccm_decrypt(&ctx->data, src, length, buf, nounce, aad, la);
-+  if(cipher == TLS_ECDH_anon_WITH_AES_128_CBC_SHA) {
-+      ret = rijndael_set_key(&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_cbc_decrypt(&ctx->data, nounce, src, length, buf);
-+    }
- error:
-   dtls_cipher_context_release();
-diff --git a/extlibs/tinydtls/crypto.h b/extlibs/tinydtls/crypto.h
-index 972a174..dd13ffa 100644
---- a/extlibs/tinydtls/crypto.h
-+++ b/extlibs/tinydtls/crypto.h
-@@ -69,11 +69,11 @@ typedef enum {
- /** Crypto context for TLS_PSK_WITH_AES_128_CCM_8 cipher suite. */
- typedef struct {
-   rijndael_ctx ctx;                  /**< AES-128 encryption context */
--} aes128_ccm_t;
-+} aes128_t;
- typedef struct dtls_cipher_context_t {
-   /** numeric identifier of this cipher suite in host byte order. */
--  aes128_ccm_t data;          /**< The crypto context */
-+  aes128_t data;              /**< The crypto context */
- } dtls_cipher_context_t;
- typedef struct {
-@@ -82,7 +82,8 @@ typedef struct {
-   uint8 other_eph_pub_y[32];
-   uint8 other_pub_x[32];
-   uint8 other_pub_y[32];
--} dtls_handshake_parameters_ecdsa_t;
-+} dtls_handshake_parameters_ecc_t;
-+
- /* This is the maximal supported length of the psk client identity and psk
-  * server identity hint */
-@@ -129,7 +130,7 @@ typedef struct {
-   unsigned int do_client_auth:1;
-   union {
- #ifdef DTLS_ECC
--    dtls_handshake_parameters_ecdsa_t ecdsa;
-+    dtls_handshake_parameters_ecc_t ecc;
- #endif /* DTLS_ECC */
- #ifdef DTLS_PSK
-     dtls_handshake_parameters_psk_t psk;
-@@ -265,7 +266,8 @@ 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);
-+               const unsigned char *aad, size_t aad_length,
-+               const dtls_cipher_t cipher);
- /** 
-  * Decrypts the given buffer \p src of given \p length, writing the
-@@ -289,7 +291,8 @@ 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);
-+               const unsigned char *a_data, size_t a_data_length,
-+               const dtls_cipher_t cipher);
- /* helper functions */
-diff --git a/extlibs/tinydtls/dtls.c b/extlibs/tinydtls/dtls.c
-index a87d7f1..f9a9a0b 100644
---- a/extlibs/tinydtls/dtls.c
-+++ b/extlibs/tinydtls/dtls.c
-@@ -79,6 +79,7 @@
- #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_SKEXEC_ECDH_ANON_LENGTH (1 + 2 + 1 + 1 + DTLS_EC_KEY_SIZE + DTLS_EC_KEY_SIZE)
- #define DTLS_SKEXECPSK_LENGTH_MIN 2
- #define DTLS_SKEXECPSK_LENGTH_MAX 2 + DTLS_PSK_MAX_CLIENT_IDENTITY_LEN
- #define DTLS_CKXPSK_LENGTH_MIN 2
-@@ -167,6 +168,24 @@ dtls_init() {
-   peer_init();
- }
-+ void
-+ dtls_enables_anon_ecdh(dtls_context_t* ctx, dtls_cipher_enable_t is_enable)
-+{
-+    if(ctx)
-+    {
-+        ctx->is_anon_ecdh_eabled = is_enable;
-+    }
-+}
-+
-+void
-+dtls_select_cipher(dtls_context_t* ctx, const dtls_cipher_t cipher)
-+{
-+    if(ctx)
-+    {
-+        ctx->selected_cipher = cipher;
-+    }
-+}
-+
- /* 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.
-@@ -477,6 +496,17 @@ static inline int is_tls_psk_with_aes_128_ccm_8(dtls_cipher_t cipher)
- #endif /* DTLS_PSK */
- }
-+/** returns true if the cipher matches TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
-+static inline int is_tls_ecdh_anon_with_aes_128_cbc_sha(dtls_cipher_t cipher)
-+{
-+#ifdef DTLS_ECC
-+    return cipher == TLS_ECDH_anon_WITH_AES_128_CBC_SHA;
-+#else
-+    return 0;
-+#endif
-+}
-+
-+
- /** returns true if the application is configured for psk */
- static inline int is_psk_supported(dtls_context_t *ctx)
- {
-@@ -509,6 +539,16 @@ static inline int is_ecdsa_client_auth_supported(dtls_context_t *ctx)
- #endif /* DTLS_ECC */
- }
-+/** returns true if ecdh_anon_with_aes_128_cbc_sha is supported */
-+static inline int is_ecdh_anon_supported(dtls_context_t *ctx)
-+{
-+#ifdef DTLS_ECC
-+    return ctx &&  (ctx->is_anon_ecdh_eabled == DTLS_CIPHER_ENABLE);
-+#else
-+    return 0;
-+#endif
-+}
-+
- /**
-  * Returns @c 1 if @p code is a cipher suite other than @c
-  * TLS_NULL_WITH_NULL_NULL that we recognize.
-@@ -522,11 +562,15 @@ static int
- known_cipher(dtls_context_t *ctx, dtls_cipher_t code, int is_client) {
-   int psk;
-   int ecdsa;
-+  int ecdh_anon;
-   psk = is_psk_supported(ctx);
-   ecdsa = is_ecdsa_supported(ctx, is_client);
-+  ecdh_anon = is_ecdh_anon_supported(ctx);
-+
-   return (psk && is_tls_psk_with_aes_128_ccm_8(code)) ||
--       (ecdsa && is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(code));
-+       (ecdsa && is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(code)) ||
-+       (ecdh_anon && is_tls_ecdh_anon_with_aes_128_cbc_sha(code));
- }
- /**
-@@ -674,11 +718,12 @@ calculate_key_block(dtls_context_t *ctx,
-   }
- #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),
-+  case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
-+  case TLS_ECDH_anon_WITH_AES_128_CBC_SHA: {
-+    pre_master_len = dtls_ecdh_pre_master_secret(handshake->keyx.ecc.own_eph_priv,
-+                                               handshake->keyx.ecc.other_eph_pub_x,
-+                                               handshake->keyx.ecc.other_eph_pub_y,
-+                                               sizeof(handshake->keyx.ecc.own_eph_priv),
-                                                pre_master_secret,
-                                                MAX_KEYBLOCK_LENGTH);
-     if (pre_master_len < 0) {
-@@ -1038,7 +1083,8 @@ check_client_keyexchange(dtls_context_t *ctx,
-                        uint8 *data, size_t length) {
- #ifdef DTLS_ECC
--  if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(handshake->cipher)) {
-+  if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(handshake->cipher) ||
-+       is_tls_ecdh_anon_with_aes_128_cbc_sha(handshake->cipher) ) {
-     if (length < DTLS_HS_LENGTH + DTLS_CKXEC_LENGTH) {
-       dtls_debug("The client key exchange is too short\n");
-@@ -1058,13 +1104,13 @@ check_client_keyexchange(dtls_context_t *ctx,
-     }
-     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.ecc.other_eph_pub_x, data,
-+         sizeof(handshake->keyx.ecc.other_eph_pub_x));
-+    data += sizeof(handshake->keyx.ecc.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);
-+    memcpy(handshake->keyx.ecc.other_eph_pub_y, data,
-+         sizeof(handshake->keyx.ecc.other_eph_pub_y));
-+    data += sizeof(handshake->keyx.ecc.other_eph_pub_y);
-   }
- #endif /* DTLS_ECC */
- #ifdef DTLS_PSK
-@@ -1253,6 +1299,8 @@ dtls_prepare_record(dtls_peer_t *peer, dtls_security_parameters_t *security,
-       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 if (is_tls_ecdh_anon_with_aes_128_cbc_sha(security->cipher)) {
-+        dtls_debug("dtls_prepare_record() : encrypt using TLS_ECDH_anon_WITH_AES_128_CBC_SHA\n");
-     } else {
-       dtls_debug("dtls_prepare_record(): encrypt using unknown cipher\n");
-     }
-@@ -1332,9 +1380,10 @@ dtls_prepare_record(dtls_peer_t *peer, dtls_security_parameters_t *security,
-     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);
-+               dtls_kb_local_write_key(security, peer->role),
-+               dtls_kb_key_size(security, peer->role),
-+               A_DATA, A_DATA_LEN,
-+               security->cipher);
-     if (res < 0)
-       return res;
-@@ -1753,8 +1802,8 @@ check_client_certificate_verify(dtls_context_t *ctx,
-   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),
-+  ret = dtls_ecdsa_verify_sig_hash(config->keyx.ecc.other_pub_x, config->keyx.ecc.other_pub_y,
-+                          sizeof(config->keyx.ecc.other_pub_x),
-                           sha256hash, sizeof(sha256hash),
-                           result_r, result_s);
-@@ -1866,7 +1915,7 @@ dtls_send_server_hello(dtls_context_t *ctx, dtls_peer_t *peer)
- #ifdef DTLS_ECC
- static int
- dtls_send_certificate_ecdsa(dtls_context_t *ctx, dtls_peer_t *peer,
--                          const dtls_ecdsa_key_t *key)
-+                          const dtls_ecc_key_t *key)
- {
-   uint8 buf[DTLS_CE_LENGTH];
-   uint8 *p;
-@@ -1956,7 +2005,7 @@ dtls_add_ecdsa_signature_elem(uint8 *p, uint32_t *point_r, uint32_t *point_s)
- static int
- dtls_send_server_key_exchange_ecdh(dtls_context_t *ctx, dtls_peer_t *peer,
--                                 const dtls_ecdsa_key_t *key)
-+                                 const dtls_ecc_key_t *key)
- {
-   /* The ASN.1 Integer representation of an 32 byte unsigned int could be
-    * 33 bytes long add space for that */
-@@ -1967,9 +2016,11 @@ dtls_send_server_key_exchange_ecdh(dtls_context_t *ctx, dtls_peer_t *peer,
-   uint8 *ephemeral_pub_y;
-   uint32_t point_r[9];
-   uint32_t point_s[9];
-+  int ecdsa;
-   dtls_handshake_parameters_t *config = peer->handshake_params;
--  /* ServerKeyExchange 
-+  ecdsa = is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher);
-+  /* ServerKeyExchange
-    *
-    * Start message construction at beginning of buffer. */
-   p = buf;
-@@ -1998,18 +2049,20 @@ dtls_send_server_key_exchange_ecdh(dtls_context_t *ctx, dtls_peer_t *peer,
-   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);
-+  dtls_ecdsa_generate_key(config->keyx.ecc.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);
-+  if(ecdsa) {
-+      /* 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);
-+      p = dtls_add_ecdsa_signature_elem(p, point_r, point_s);
-+  }
-   assert(p - buf <= sizeof(buf));
-@@ -2107,6 +2160,8 @@ static int
- dtls_send_server_hello_msgs(dtls_context_t *ctx, dtls_peer_t *peer)
- {
-   int res;
-+  int ecdsa;
-+  int ecdh_anon;
-   res = dtls_send_server_hello(ctx, peer);
-@@ -2115,9 +2170,20 @@ dtls_send_server_hello_msgs(dtls_context_t *ctx, dtls_peer_t *peer)
-     return res;
-   }
-+  ecdsa = is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher);
-+  ecdh_anon = is_tls_ecdh_anon_with_aes_128_cbc_sha(peer->handshake_params->cipher);
-+
- #ifdef DTLS_ECC
--  if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher)) {
--    const dtls_ecdsa_key_t *ecdsa_key;
-+  if(ecdh_anon) {
-+      res = dtls_send_server_key_exchange_ecdh(ctx, peer, NULL);
-+
-+      if (res < 0) {
-+        dtls_debug("dtls_server_hello(with ECDH): cannot prepare Server Key Exchange record\n");
-+        return res;
-+      }
-+  }
-+  else if (ecdsa) {
-+    const dtls_ecc_key_t *ecdsa_key;
-     res = CALL(ctx, get_ecdsa_key, &peer->session, &ecdsa_key);
-     if (res < 0) {
-@@ -2144,7 +2210,7 @@ dtls_send_server_hello_msgs(dtls_context_t *ctx, dtls_peer_t *peer)
-       res = dtls_send_server_certificate_request(ctx, peer);
-       if (res < 0) {
--        dtls_debug("dtls_server_hello: cannot prepare certificate Request record\n");
-+        dtls_debug("dtls_server_hello(with ECDSA): cannot prepare certificate Request record\n");
-         return res;
-       }
-     }
-@@ -2233,7 +2299,8 @@ dtls_send_client_key_exchange(dtls_context_t *ctx, dtls_peer_t *peer)
-   }
- #endif /* DTLS_PSK */
- #ifdef DTLS_ECC
--  case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: {
-+  case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
-+  case TLS_ECDH_anon_WITH_AES_128_CBC_SHA: {
-     uint8 *ephemeral_pub_x;
-     uint8 *ephemeral_pub_y;
-@@ -2249,7 +2316,7 @@ dtls_send_client_key_exchange(dtls_context_t *ctx, dtls_peer_t *peer)
-     ephemeral_pub_y = p;
-     p += DTLS_EC_KEY_SIZE;
--    dtls_ecdsa_generate_key(peer->handshake_params->keyx.ecdsa.own_eph_priv,
-+    dtls_ecdsa_generate_key(peer->handshake_params->keyx.ecc.own_eph_priv,
-                           ephemeral_pub_x, ephemeral_pub_y,
-                           DTLS_EC_KEY_SIZE);
-@@ -2270,7 +2337,7 @@ dtls_send_client_key_exchange(dtls_context_t *ctx, dtls_peer_t *peer)
- #ifdef DTLS_ECC
- static int
- dtls_send_certificate_verify_ecdh(dtls_context_t *ctx, dtls_peer_t *peer,
--                                 const dtls_ecdsa_key_t *key)
-+                                 const dtls_ecc_key_t *key)
- {
-   /* The ASN.1 Integer representation of an 32 byte unsigned int could be
-    * 33 bytes long add space for that */
-@@ -2342,16 +2409,32 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
-   uint8 *p = buf;
-   uint8_t cipher_size;
-   uint8_t extension_size;
--  int psk;
--  int ecdsa;
-+  int psk = 0;
-+  int ecdsa = 0;
-+  int ecdh_anon = 0;
-   dtls_handshake_parameters_t *handshake = peer->handshake_params;
-   dtls_tick_t now;
--  psk = is_psk_supported(ctx);
--  ecdsa = is_ecdsa_supported(ctx, 1);
-+  switch(ctx->selected_cipher)
-+  {
-+      case TLS_PSK_WITH_AES_128_CCM_8:
-+        psk = is_psk_supported(ctx);
-+        break;
-+      case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
-+        ecdsa = is_ecdsa_supported(ctx, 1);
-+        break;
-+      case TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
-+        ecdh_anon = is_ecdh_anon_supported(ctx);
-+        break;
-+      default:
-+        psk = is_psk_supported(ctx);
-+        ecdsa = is_ecdsa_supported(ctx, 1);
-+        ecdh_anon = is_ecdh_anon_supported(ctx);
-+        break;
-+   }
--  cipher_size = 2 + ((ecdsa) ? 2 : 0) + ((psk) ? 2 : 0);
--  extension_size = (ecdsa) ? 2 + 6 + 6 + 8 + 6: 0;
-+  cipher_size = 2 + (ecdsa ? 2 : 0) + (psk ? 2 : 0) + (ecdh_anon ? 2 : 0);
-+  extension_size = (ecdsa) ? (2 + 6 + 6 + 8 + 6) : 0;
-   if (cipher_size == 0) {
-     dtls_crit("no cipher callbacks implemented\n");
-@@ -2393,14 +2476,18 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
-   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);
-+  if (ecdh_anon) {
-+    dtls_int_to_uint16(p, TLS_ECDH_anon_WITH_AES_128_CBC_SHA);
-     p += sizeof(uint16);
-   }
-   if (psk) {
-     dtls_int_to_uint16(p, TLS_PSK_WITH_AES_128_CCM_8);
-     p += sizeof(uint16);
-   }
-+  if (ecdsa) {
-+    dtls_int_to_uint16(p, TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8);
-+    p += sizeof(uint16);
-+  }
-   /* compression method */
-   dtls_int_to_uint8(p, 1);
-@@ -2611,18 +2698,18 @@ check_server_certificate(dtls_context_t *ctx,
-   }
-   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.ecc.other_pub_x, data,
-+       sizeof(config->keyx.ecc.other_pub_x));
-+  data += sizeof(config->keyx.ecc.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);
-+  memcpy(config->keyx.ecc.other_pub_y, data,
-+       sizeof(config->keyx.ecc.other_pub_y));
-+  data += sizeof(config->keyx.ecc.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));
-+           config->keyx.ecc.other_pub_x,
-+           config->keyx.ecc.other_pub_y,
-+           sizeof(config->keyx.ecc.other_pub_x));
-   if (err < 0) {
-     dtls_warn("The certificate was not accepted\n");
-     return err;
-@@ -2682,13 +2769,13 @@ check_server_key_exchange_ecdsa(dtls_context_t *ctx,
-   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.ecc.other_eph_pub_x, data, sizeof(config->keyx.ecc.other_eph_pub_y));
-+  data += sizeof(config->keyx.ecc.other_eph_pub_y);
-+  data_length -= sizeof(config->keyx.ecc.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);
-+  memcpy(config->keyx.ecc.other_eph_pub_y, data, sizeof(config->keyx.ecc.other_eph_pub_y));
-+  data += sizeof(config->keyx.ecc.other_eph_pub_y);
-+  data_length -= sizeof(config->keyx.ecc.other_eph_pub_y);
-   ret = dtls_check_ecdsa_signature_elem(data, data_length, &result_r, &result_s);
-   if (ret < 0) {
-@@ -2697,8 +2784,8 @@ check_server_key_exchange_ecdsa(dtls_context_t *ctx,
-   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),
-+  ret = dtls_ecdsa_verify_sig(config->keyx.ecc.other_pub_x, config->keyx.ecc.other_pub_y,
-+                          sizeof(config->keyx.ecc.other_pub_x),
-                           config->tmp.random.client, DTLS_RANDOM_LENGTH,
-                           config->tmp.random.server, DTLS_RANDOM_LENGTH,
-                           key_params,
-@@ -2711,6 +2798,64 @@ check_server_key_exchange_ecdsa(dtls_context_t *ctx,
-   }
-   return 0;
- }
-+
-+static int
-+check_server_key_exchange_ecdh(dtls_context_t *ctx,
-+                              dtls_peer_t *peer,
-+                              uint8 *data, size_t data_length)
-+{
-+  dtls_handshake_parameters_t *config = peer->handshake_params;
-+
-+  update_hs_hash(peer, data, data_length);
-+
-+  assert(is_tls_ecdh_anon_with_aes_128_cbc_sha(config->cipher));
-+
-+  data += DTLS_HS_LENGTH;
-+
-+  if (data_length < DTLS_HS_LENGTH + DTLS_SKEXEC_ECDH_ANON_LENGTH) {
-+    dtls_alert("the packet length does not match the expected\n");
-+    return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR);
-+  }
-+
-+  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.ecc.other_eph_pub_x, data, sizeof(config->keyx.ecc.other_eph_pub_x));
-+  data += sizeof(config->keyx.ecc.other_eph_pub_x);
-+  data_length -= sizeof(config->keyx.ecc.other_eph_pub_x);
-+
-+  memcpy(config->keyx.ecc.other_eph_pub_y, data, sizeof(config->keyx.ecc.other_eph_pub_y));
-+  data += sizeof(config->keyx.ecc.other_eph_pub_y);
-+  data_length -= sizeof(config->keyx.ecc.other_eph_pub_y);
-+
-+  return 0;
-+}
-+
- #endif /* DTLS_ECC */
- #ifdef DTLS_PSK
-@@ -2838,7 +2983,7 @@ check_server_hellodone(dtls_context_t *ctx,
- {
-   int res;
- #ifdef DTLS_ECC
--  const dtls_ecdsa_key_t *ecdsa_key;
-+  const dtls_ecc_key_t *ecdsa_key;
- #endif /* DTLS_ECC */
-   dtls_handshake_parameters_t *handshake = peer->handshake_params;
-@@ -2848,7 +2993,7 @@ check_server_hellodone(dtls_context_t *ctx,
-   update_hs_hash(peer, data, data_length);
- #ifdef DTLS_ECC
--  if (handshake->do_client_auth) {
-+  if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(handshake->cipher) && handshake->do_client_auth) {
-     res = CALL(ctx, get_ecdsa_key, &peer->session, &ecdsa_key);
-     if (res < 0) {
-@@ -2874,7 +3019,7 @@ check_server_hellodone(dtls_context_t *ctx,
-   }
- #ifdef DTLS_ECC
--  if (handshake->do_client_auth) {
-+  if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(handshake->cipher) && handshake->do_client_auth) {
-     res = dtls_send_certificate_verify_ecdh(ctx, peer, ecdsa_key);
-@@ -2961,12 +3106,13 @@ decrypt_verify(dtls_peer_t *peer, uint8 *packet, size_t length,
-     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);
-+                     A_DATA, A_DATA_LEN,
-+               security->cipher);
-     if (clen < 0)
-       dtls_warn("decryption failed\n");
-     else {
- #ifndef NDEBUG
--      printf("decrypt_verify(): found %i bytes cleartext\n", clen);
-+      dtls_debug("decrypt_verify(): found %i bytes cleartext\n", clen);
- #endif
-       dtls_security_params_free_other(peer);
-       dtls_debug_dump("cleartext", *cleartext, clen);
-@@ -3071,9 +3217,11 @@ handle_handshake_msg(dtls_context_t *ctx, dtls_peer_t *peer, session_t *session,
-       return err;
-     }
-     if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher))
--      peer->state = DTLS_STATE_WAIT_SERVERCERTIFICATE;
-+      peer->state = DTLS_STATE_WAIT_SERVERCERTIFICATE; //ecdsa
-+    else if (is_tls_ecdh_anon_with_aes_128_cbc_sha(peer->handshake_params->cipher))
-+        peer->state = DTLS_STATE_WAIT_SERVERKEYEXCHANGE; //ecdh
-     else
--      peer->state = DTLS_STATE_WAIT_SERVERHELLODONE;
-+      peer->state = DTLS_STATE_WAIT_SERVERHELLODONE; //psk
-     /* update_hs_hash(peer, data, data_length); */
-     break;
-@@ -3109,6 +3257,13 @@ handle_handshake_msg(dtls_context_t *ctx, dtls_peer_t *peer, session_t *session,
-       }
-       err = check_server_key_exchange_ecdsa(ctx, peer, data, data_length);
-     }
-+
-+    if (is_tls_ecdh_anon_with_aes_128_cbc_sha(peer->handshake_params->cipher)) {
-+      if (state != DTLS_STATE_WAIT_SERVERKEYEXCHANGE) {
-+        return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE);
-+      }
-+      err = check_server_key_exchange_ecdh(ctx, peer, data, data_length);
-+    }
- #endif /* DTLS_ECC */
- #ifdef DTLS_PSK
-     if (is_tls_psk_with_aes_128_ccm_8(peer->handshake_params->cipher)) {
-@@ -3218,9 +3373,9 @@ handle_handshake_msg(dtls_context_t *ctx, dtls_peer_t *peer, session_t *session,
-     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;
-+      peer->state = DTLS_STATE_WAIT_CERTIFICATEVERIFY; //ecdsa
-     else
--      peer->state = DTLS_STATE_WAIT_CHANGECIPHERSPEC;
-+      peer->state = DTLS_STATE_WAIT_CHANGECIPHERSPEC; //psk || ecdh_anon
-     break;
- #ifdef DTLS_ECC
-@@ -3341,9 +3496,9 @@ handle_handshake_msg(dtls_context_t *ctx, dtls_peer_t *peer, session_t *session,
-     }
-     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;
-+      peer->state = DTLS_STATE_WAIT_CLIENTCERTIFICATE; //ecdhe
-     else
--      peer->state = DTLS_STATE_WAIT_CLIENTKEYEXCHANGE;
-+      peer->state = DTLS_STATE_WAIT_CLIENTKEYEXCHANGE; //psk, ecdh_anon
-     /* after sending the ServerHelloDone, we expect the
-      * ClientKeyExchange (possibly containing the PSK id),
-diff --git a/extlibs/tinydtls/dtls.h b/extlibs/tinydtls/dtls.h
-index 7ebde6b..4d82f72 100644
---- a/extlibs/tinydtls/dtls.h
-+++ b/extlibs/tinydtls/dtls.h
-@@ -60,12 +60,12 @@ 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 {
-+typedef struct dtls_ecc_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;
-+} dtls_ecc_key_t;
- /** Length of the secret that is used for generating Hello Verify cookies. */
- #define DTLS_COOKIE_SECRET_LENGTH 12
-@@ -183,7 +183,7 @@ typedef struct {
-    */
-   int (*get_ecdsa_key)(struct dtls_context_t *ctx, 
-                      const session_t *session,
--                     const dtls_ecdsa_key_t **result);
-+                     const dtls_ecc_key_t **result);
-   /**
-    * Called during handshake to check the peer's pubic key in this
-@@ -238,6 +238,10 @@ typedef struct dtls_context_t {
-   dtls_handler_t *h;          /**< callback handlers */
-+  dtls_cipher_enable_t is_anon_ecdh_eabled;    /**< enable/disable the TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
-+
-+  dtls_cipher_t selected_cipher; /**< selected ciper suite for handshake */
-+
-   unsigned char readbuf[DTLS_MAX_BUF];
- } dtls_context_t;
-@@ -263,6 +267,24 @@ static inline void dtls_set_handler(dtls_context_t *ctx, dtls_handler_t *h) {
-   ctx->h = h;
- }
-+ /**
-+  * @brief Enabling the TLS_ECDH_anon_WITH_AES_128_CBC_SHA
-+  *
-+  * @param ctx              The DTLS context to use.
-+  * @param is_enable    DTLS_CIPHER_ENABLE(1) or DTLS_CIPHER_DISABLE(0)
-+  */
-+void dtls_enables_anon_ecdh(dtls_context_t* ctx, dtls_cipher_enable_t is_enable);
-+
-+/**
-+ * @brief Select the cipher suite for handshake
-+ *
-+ * @param ctx              The DTLS context to use.
-+ * @param cipher         TLS_ECDH_anon_WITH_AES_128_CBC_SHA (0xC018)
-+ *                                  TLS_PSK_WITH_AES_128_CCM_8 (0xX0A8)
-+ *                                  TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 (0xC0AE)
-+ */
-+void dtls_select_cipher(dtls_context_t* ctx, const dtls_cipher_t cipher);
-+
- /**
-  * Establishes a DTLS channel with the specified remote peer @p dst.
-  * This function returns @c 0 if that channel already exists, a value
-diff --git a/extlibs/tinydtls/global.h b/extlibs/tinydtls/global.h
-index f0977c8..441710f 100644
---- a/extlibs/tinydtls/global.h
-+++ b/extlibs/tinydtls/global.h
-@@ -73,10 +73,16 @@ typedef unsigned char uint48[6];
- /** Known cipher suites.*/
- typedef enum { 
-   TLS_NULL_WITH_NULL_NULL = 0x0000,   /**< NULL cipher  */
-+  TLS_ECDH_anon_WITH_AES_128_CBC_SHA = 0xC018, /**< see RFC 4492 */
-   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;
-+typedef enum {
-+    DTLS_CIPHER_DISABLE = 0,
-+    DTLS_CIPHER_ENABLE = 1
-+} dtls_cipher_enable_t;
-+
- /** Known compression suites.*/
- typedef enum {
-   TLS_COMPRESSION_NULL = 0x0000               /* NULL compression */
-diff --git a/extlibs/tinydtls/tests/dtls-client.c b/extlibs/tinydtls/tests/dtls-client.c
-index 65b0275..3a3e4ca 100644
---- a/extlibs/tinydtls/tests/dtls-client.c
-+++ b/extlibs/tinydtls/tests/dtls-client.c
-@@ -147,8 +147,8 @@ get_psk_info(struct dtls_context_t *ctx UNUSED_PARAM,
- 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 = {
-+            const dtls_ecc_key_t **result) {
-+  static const dtls_ecc_key_t ecdsa_key = {
-     .curve = DTLS_ECDH_CURVE_SECP256R1,
-     .priv_key = ecdsa_priv_key,
-     .pub_key_x = ecdsa_pub_key_x,
-@@ -294,9 +294,9 @@ usage( const char *program, const char *version) {
-   fprintf(stderr, "%s v%s -- DTLS client implementation\n"
-         "(c) 2011-2014 Olaf Bergmann <bergmann@tzi.org>\n\n"
- #ifdef DTLS_PSK
--        "usage: %s [-i file] [-s 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] [-c num] addr [port]\n"
- #else /*  DTLS_PSK */
--        "usage: %s [-o file] [-p port] [-v num] addr [port]\n"
-+        "usage: %s [-o file] [-p port] [-v num] [-c num] addr [port]\n"
- #endif /* DTLS_PSK */
- #ifdef DTLS_PSK
-         "\t-i file\t\tread PSK Client identity from file\n"
-@@ -305,7 +305,11 @@ usage( const char *program, const char *version) {
- #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",
-+        "\t-v num\t\tverbosity level (default: 3)\n"
-+          "\t-c num\t\tcipher suite (default: 1)\n"
-+          "\t\t\t1: TLS_ECDH_anon_WITH_AES_128_CBC_SHA \n"
-+          "\t\t\t2: TLS_PSK_WITH_AES_128_CCM_8\n"
-+          "\t\t\t3: TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8\n",
-          program, version, program, DEFAULT_PORT);
- }
-@@ -334,6 +338,8 @@ main(int argc, char **argv) {
-   log_t log_level = DTLS_LOG_WARN;
-   int fd, result;
-   int on = 1;
-+  dtls_cipher_t selected_cipher = TLS_ECDH_anon_WITH_AES_128_CBC_SHA;
-+  dtls_cipher_enable_t ecdh_anon_enalbe = DTLS_CIPHER_ENABLE;
-   int opt, res;
-   session_t dst;
-@@ -349,7 +355,7 @@ main(int argc, char **argv) {
-   memcpy(psk_key, PSK_DEFAULT_KEY, psk_key_length);
- #endif /* DTLS_PSK */
--  while ((opt = getopt(argc, argv, "p:o:v:" PSK_OPTIONS)) != -1) {
-+  while ((opt = getopt(argc, argv, "p:o:v:c:" PSK_OPTIONS)) != -1) {
-     switch (opt) {
- #ifdef DTLS_PSK
-     case 'i' : {
-@@ -399,6 +405,23 @@ main(int argc, char **argv) {
-     case 'v' :
-       log_level = strtol(optarg, NULL, 10);
-       break;
-+    case 'c':
-+      if( strcmp(optarg, "1") == 0)
-+      {
-+          selected_cipher = TLS_ECDH_anon_WITH_AES_128_CBC_SHA;
-+          ecdh_anon_enalbe = DTLS_CIPHER_ENABLE;
-+      }
-+      else if( strcmp(optarg, "2") == 0)
-+      {
-+          selected_cipher = TLS_PSK_WITH_AES_128_CCM_8 ;
-+          ecdh_anon_enalbe = DTLS_CIPHER_DISABLE;
-+      }
-+      else if( strcmp(optarg, "3") == 0)
-+      {
-+          selected_cipher = TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 ;
-+          ecdh_anon_enalbe = DTLS_CIPHER_DISABLE;
-+      }
-+      break;
-     default:
-       usage(argv[0], dtls_package_version());
-       exit(1);
-@@ -464,6 +487,13 @@ main(int argc, char **argv) {
-     exit(-1);
-   }
-+
-+  /* select cipher suite */
-+  dtls_select_cipher(dtls_context, selected_cipher);
-+
-+  /* enable/disable tls_ecdh_anon_with_aes_128_cbc_sha */
-+  dtls_enables_anon_ecdh(dtls_context, ecdh_anon_enalbe);
-+
-   dtls_set_handler(dtls_context, &cb);
-   dtls_connect(dtls_context, &dst);
-diff --git a/extlibs/tinydtls/tests/dtls-server.c b/extlibs/tinydtls/tests/dtls-server.c
-index ae1283e..d3da1a7 100644
---- a/extlibs/tinydtls/tests/dtls-server.c
-+++ b/extlibs/tinydtls/tests/dtls-server.c
-@@ -113,8 +113,8 @@ get_psk_info(struct dtls_context_t *ctx, const session_t *session,
- 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 = {
-+            const dtls_ecc_key_t **result) {
-+  static const dtls_ecc_key_t ecdsa_key = {
-     .curve = DTLS_ECDH_CURVE_SECP256R1,
-     .priv_key = ecdsa_priv_key,
-     .pub_key_x = ecdsa_pub_key_x,
-@@ -249,10 +249,13 @@ usage(const char *program, const char *version) {
-   fprintf(stderr, "%s v%s -- DTLS server implementation\n"
-         "(c) 2011-2014 Olaf Bergmann <bergmann@tzi.org>\n\n"
--        "usage: %s [-A address] [-p port] [-v num]\n"
-+        "usage: %s [-A address] [-p port] [-v num] [-a enable|disable]\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",
-+        "\t-v num\t\tverbosity level (default: 3)\n"
-+        "\t-a enable|disable\t(default: disable)\n"
-+        "\t\t\t\tenable:enable TLS_ECDH_anon_with_AES_128_CBC_SHA\n"
-+        "\t\t\t\tdisable:disable TLS_ECDH_anon_with_AES_128_CBC_SHA\n",
-          program, version, program, DEFAULT_PORT);
- }
-@@ -277,6 +280,7 @@ main(int argc, char **argv) {
-   struct timeval timeout;
-   int fd, opt, result;
-   int on = 1;
-+  int ecdh_anon_enalbe = DTLS_CIPHER_DISABLE;
-   struct sockaddr_in6 listen_addr;
-   memset(&listen_addr, 0, sizeof(struct sockaddr_in6));
-@@ -290,7 +294,7 @@ main(int argc, char **argv) {
-   listen_addr.sin6_port = htons(DEFAULT_PORT);
-   listen_addr.sin6_addr = in6addr_any;
--  while ((opt = getopt(argc, argv, "A:p:v:")) != -1) {
-+  while ((opt = getopt(argc, argv, "A:p:v:a:")) != -1) {
-     switch (opt) {
-     case 'A' :
-       if (resolve_address(optarg, (struct sockaddr *)&listen_addr) < 0) {
-@@ -304,6 +308,10 @@ main(int argc, char **argv) {
-     case 'v' :
-       log_level = strtol(optarg, NULL, 10);
-       break;
-+    case 'a':
-+      if( strcmp(optarg, "enable") == 0)
-+          ecdh_anon_enalbe = DTLS_CIPHER_ENABLE;
-+      break;
-     default:
-       usage(argv[0], dtls_package_version());
-       exit(1);
-@@ -348,6 +356,9 @@ main(int argc, char **argv) {
-   the_context = dtls_new_context(&fd);
-+  /* enable/disable tls_ecdh_anon_with_aes_128_cbc_sha */
-+  dtls_enables_anon_ecdh(the_context, ecdh_anon_enalbe);
-+
-   dtls_set_handler(the_context, &cb);
-   while (1) {
--- 
-1.7.9.5
-
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
deleted file mode 100644 (file)
index fb9c71f..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-From c78aa91005b7b9542d595dc32d8c8fe020d2257d Mon Sep 17 00:00:00 2001
-From: Sachin Agrawal <sachin.agrawal@intel.com>
-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 <sachin.agrawal@intel.com>
----
- 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
deleted file mode 100644 (file)
index 263ed58..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-From b44aa20e0ff2763468bf82ff4e996dec03e872bd Mon Sep 17 00:00:00 2001
-From: Sachin Agrawal <sachin.agrawal@intel.com>
-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 <sachin.agrawal@intel.com>
----
- 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 <bergmann@tzi.org>
-+ * Copyright (C) 2013 Hauke Mehrtens <hauke@hauke-m.de>
-+ *
-+ * 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 <assert.h> 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 <memory.h> 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 <stddef.h> header file. */
-+#define HAVE_STDDEF_H 1
-+
-+/* Define to 1 if you have the <stdint.h> header file. */
-+#define HAVE_STDINT_H 1
-+
-+/* Define to 1 if you have the <stdlib.h> 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 <strings.h> header file. */
-+#define HAVE_STRINGS_H 1
-+
-+/* Define to 1 if you have the <string.h> 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 <time.h> 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 <sys/types.h> 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 <bergmann@tzi.org>
-+ * Copyright (C) 2013 Hauke Mehrtens <hauke@hauke-m.de>
-+ *
-+ * 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
deleted file mode 100644 (file)
index c52b679..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-From e25d93dec6d2907430f3680ad5fbdfedc1ee94d8 Mon Sep 17 00:00:00 2001
-From: Sachin Agrawal <sachin.agrawal@intel.com>
-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 <sachin.agrawal@intel.com>
----
- 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-Fix-the-wrong-implementation-about-the-anonymous-cip.patch b/extlibs/tinydtls/0001-Fix-the-wrong-implementation-about-the-anonymous-cip.patch
deleted file mode 100644 (file)
index e2b8e65..0000000
+++ /dev/null
@@ -1,690 +0,0 @@
-From 1ee27820ccad59423711c83fb01ff58939511f3b Mon Sep 17 00:00:00 2001
-From: Sachin Agrawal <sachin.agrawal@intel.com>
-Date: Mon, 29 Jun 2015 22:26:21 -0700
-Subject: [PATCH 1/1] Fix the wrong implementation about the anonymous cipher
- suite of tinydtls. (NOTE : This patch has been modified
- based on RFC 5246)
-
-1. IV for CBC block operation
-   - Apply the random IV for CBC block operations according to section 6.2.3.2 of RFC 5246.
-
-2. MAC calculation
-   - Apply HMAC for DTLS MAC calculation according to section 6.2.3.1 of RFC 5246.
-
-3. CBC padding
-   - Apply PKCS#5 padding for CBC block cipher accroding to section 6.2.3.2 of RFC 5246.
-
-4. Change the cipher suite name TLS_ECDH_anon_WITH_AES_128_CBC_SHA
-   to TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256.
-
-5. Fix the minor bug in dtls sample.
-
-Change-Id: I8783caa6ac04fe2d46e242efe56e3205646b1038
-Signed-off-by: leechul <chuls.lee@samsung.com>
-Signed-off-by: Sachin Agrawal <sachin.agrawal@intel.com>
----
- extlibs/tinydtls/crypto.c                          |  100 +++++++++++++-----
- extlibs/tinydtls/crypto.h                          |    1 +
- extlibs/tinydtls/dtls.c                            |  111 +++++++++++++++-----
- extlibs/tinydtls/dtls.h                            |    6 +-
- extlibs/tinydtls/global.h                          |    2 +-
- extlibs/tinydtls/tests/dtls-client.c               |    8 +-
- extlibs/tinydtls/tests/dtls-server.c               |    8 +-
- resource/csdk/connectivity/api/cainterface.h       |    4 +-
- resource/csdk/connectivity/inc/caadapternetdtls.h  |    2 +-
- .../src/adapter_util/caadapternetdtls.c            |    2 +-
- .../provisioning/src/provisioningmanager.c         |    2 +-
- 11 files changed, 180 insertions(+), 66 deletions(-)
-
-diff --git a/extlibs/tinydtls/crypto.c b/extlibs/tinydtls/crypto.c
-index 5082535..3fbb993 100644
---- a/extlibs/tinydtls/crypto.c
-+++ b/extlibs/tinydtls/crypto.c
-@@ -58,6 +58,7 @@
- #include "sha2/sha2.h"
- #include "prng.h"
- #include "netq.h"
-+#include "hmac.h"
- #ifndef WITH_CONTIKI
- #include <pthread.h>
-@@ -329,6 +330,7 @@ dtls_ccm_decrypt(aes128_t *ccm_ctx, const unsigned char *src,
- static size_t
- dtls_cbc_encrypt(aes128_t *aes_ctx,
-+                 unsigned char *key, size_t keylen,
-                  const unsigned char *iv,
-                  const unsigned char *src, size_t srclen,
-                  unsigned char *buf) {
-@@ -336,18 +338,35 @@ dtls_cbc_encrypt(aes128_t *aes_ctx,
-     unsigned char cbc[DTLS_BLK_LENGTH];
-     unsigned char tmp[DTLS_BLK_LENGTH];
-     unsigned char *pos;
--    dtls_hash_ctx shactx;
-+    const unsigned char *dtls_hdr = NULL;
-     int i, j;
-     int blocks;
-+    dtls_hmac_context_t* hmac_ctx = NULL;
-+    int paddinglen = 0;
-     pos = buf;
--    dtls_hash_init(&shactx);
--    dtls_hash_update(&shactx, src, srclen);
--    dtls_hash_finalize(pos + srclen, &shactx);
-+    dtls_hdr = src - DTLS_CBC_IV_LENGTH - sizeof(dtls_record_header_t);
-+
-+    //Calculate MAC : Append the MAC code to end of content
-+    hmac_ctx = dtls_hmac_new(key, keylen);
-+    dtls_mac(hmac_ctx,
-+             dtls_hdr,
-+             src, srclen,
-+             buf + srclen);
-+    dtls_hmac_free(hmac_ctx);
-+    
-+    dtls_debug_dump("[MAC]",
-+                    buf + srclen,
-+                    DTLS_HMAC_DIGEST_SIZE);
-+
-+    paddinglen = DTLS_BLK_LENGTH - ((srclen + DTLS_HMAC_DIGEST_SIZE) % DTLS_BLK_LENGTH);
-+    
-+    //TLS padding
-+    memset(buf + (srclen + DTLS_HMAC_DIGEST_SIZE), paddinglen - 1, paddinglen);
-     memcpy(cbc, iv, DTLS_BLK_LENGTH);
--    blocks = (srclen + SHA256_DIGEST_LENGTH) / DTLS_BLK_LENGTH;
-+    blocks = (srclen + DTLS_HMAC_DIGEST_SIZE + paddinglen) / DTLS_BLK_LENGTH;
-     for (i = 0; i < blocks; i++) {
-         for (j = 0; j < DTLS_BLK_LENGTH; j++) {
-@@ -360,14 +379,17 @@ dtls_cbc_encrypt(aes128_t *aes_ctx,
-         pos += DTLS_BLK_LENGTH;
-     }
--    dtls_debug_dump("Encrypted Data:", buf, srclen + SHA256_DIGEST_LENGTH);
--
--    return srclen + SHA256_DIGEST_LENGTH;
-+    dtls_debug_dump("[Encrypted Data]",
-+                    buf,
-+                    srclen + DTLS_HMAC_DIGEST_SIZE + paddinglen);
-+    
-+    return srclen + DTLS_HMAC_DIGEST_SIZE + paddinglen;
- }
- static size_t
- dtls_cbc_decrypt(aes128_t *aes_ctx,
-+                 unsigned char *key, size_t keylen,
-                  const unsigned char *iv,
-                  const unsigned char *src, size_t srclen,
-                  unsigned char *buf) {
-@@ -375,14 +397,17 @@ dtls_cbc_decrypt(aes128_t *aes_ctx,
-     unsigned char cbc[DTLS_BLK_LENGTH];
-     unsigned char tmp[DTLS_BLK_LENGTH];
-     unsigned char tmp2[DTLS_BLK_LENGTH];
--    unsigned char msg_hash[SHA256_DIGEST_LENGTH];
-+    unsigned char mac_buf[DTLS_HMAC_DIGEST_SIZE] = {0,};
-+    const unsigned char *dtls_hdr = NULL;
-     unsigned char *pos;
--    dtls_hash_ctx shactx;
-     int i, j;
-     int blocks;
-+    int depaddinglen = 0;
-+    dtls_hmac_context_t* hmac_ctx = NULL;
-     pos = buf;
--    memcpy(pos, src, srclen);
-+
-+    dtls_hdr = src - DTLS_CBC_IV_LENGTH - sizeof(dtls_record_header_t);
-     memcpy(cbc, iv, DTLS_BLK_LENGTH);
-     blocks = srclen / DTLS_BLK_LENGTH;
-@@ -401,19 +426,46 @@ dtls_cbc_decrypt(aes128_t *aes_ctx,
-         pos += DTLS_BLK_LENGTH;
-     }
--    dtls_hash_init(&shactx);
--    dtls_hash_update(&shactx, buf, srclen - SHA256_DIGEST_LENGTH);
--    dtls_hash_finalize(msg_hash, &shactx);
--
--    dtls_debug_dump("decrypted data:", buf, srclen);
-+    //de-padding
-+    depaddinglen = buf[srclen -1];
--    if(memcmp(msg_hash, buf + (srclen - SHA256_DIGEST_LENGTH), SHA256_DIGEST_LENGTH) != 0)
-+    //Calculate MAC
-+    hmac_ctx = dtls_hmac_new(key, keylen);
-+    if(!hmac_ctx) {
-+        return -1;
-+    }
-+    dtls_mac(hmac_ctx, dtls_hdr, buf,
-+             srclen - DTLS_HMAC_DIGEST_SIZE - depaddinglen - 1,
-+             mac_buf);
-+    dtls_hmac_free(hmac_ctx);
-+
-+    dtls_debug_dump("[MAC]",
-+                    mac_buf,
-+                    DTLS_HMAC_DIGEST_SIZE);
-+    dtls_debug_dump("[Decrypted data]",
-+                    buf,
-+                    srclen - DTLS_HMAC_DIGEST_SIZE - depaddinglen - 1);
-+
-+    //verify the MAC
-+    if(memcmp(mac_buf,
-+              buf + (srclen - DTLS_HMAC_DIGEST_SIZE - depaddinglen - 1),
-+              DTLS_HMAC_DIGEST_SIZE) != 0)
-     {
--        dtls_warn("message is broken\n");
-+        dtls_crit("Failed to verification of MAC\n");
-         return -1;
-     }
--    return srclen - SHA256_DIGEST_LENGTH;
-+    //verify the padding bytes
-+    for (i =0; i < depaddinglen; i++)
-+    {
-+        if (buf[srclen - depaddinglen - 1 + i] != depaddinglen)
-+        {
-+            dtls_crit("Failed to verify padding bytes\n");
-+            return -1;
-+        }
-+    }
-+
-+    return srclen - DTLS_HMAC_DIGEST_SIZE - depaddinglen - 1;
- }
- #ifdef DTLS_PSK
-@@ -523,8 +575,6 @@ 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];
-@@ -615,7 +665,7 @@ dtls_encrypt(const unsigned char *src, size_t length,
-         memmove(buf, src, length);
-       ret = dtls_ccm_encrypt(&ctx->data, src, length, buf, nounce, aad, la);
-   }
--  if(cipher == TLS_ECDH_anon_WITH_AES_128_CBC_SHA) {
-+  if(cipher == TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256) {
-       ret = rijndael_set_key(&ctx->data.ctx, key, 8 * keylen);
-       if (ret < 0) {
-         /* cleanup everything in case the key has the wrong size */
-@@ -625,7 +675,7 @@ dtls_encrypt(const unsigned char *src, size_t length,
-       if (src != buf)
-         memmove(buf, src, length);
--      ret = dtls_cbc_encrypt(&ctx->data, nounce, src, length, buf);
-+      ret = dtls_cbc_encrypt(&ctx->data, key, keylen, nounce, src, length, buf);
-   }
- error:
-@@ -658,7 +708,7 @@ dtls_decrypt(const unsigned char *src, size_t length,
-       ret = dtls_ccm_decrypt(&ctx->data, src, length, buf, nounce, aad, la);
-   }
--  if(cipher == TLS_ECDH_anon_WITH_AES_128_CBC_SHA) {
-+  if(cipher == TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256) {
-       ret = rijndael_set_key(&ctx->data.ctx, key, 8 * keylen);
-       if (ret < 0) {
-         /* cleanup everything in case the key has the wrong size */
-@@ -668,7 +718,7 @@ dtls_decrypt(const unsigned char *src, size_t length,
-       if (src != buf)
-         memmove(buf, src, length);
--      ret = dtls_cbc_decrypt(&ctx->data, nounce, src, length, buf);
-+      ret = dtls_cbc_decrypt(&ctx->data, key, keylen, nounce, src, length, buf);
-     }
- error:
-diff --git a/extlibs/tinydtls/crypto.h b/extlibs/tinydtls/crypto.h
-index dd13ffa..a81d306 100644
---- a/extlibs/tinydtls/crypto.h
-+++ b/extlibs/tinydtls/crypto.h
-@@ -46,6 +46,7 @@
- #define DTLS_BLK_LENGTH        16 /* AES-128 */
- #define DTLS_MAC_LENGTH        DTLS_HMAC_DIGEST_SIZE
- #define DTLS_IV_LENGTH         4  /* length of nonce_explicit */
-+#define DTLS_CBC_IV_LENGTH     16
- /** 
-  * Maximum size of the generated keyblock. Note that MAX_KEYBLOCK_LENGTH must 
-diff --git a/extlibs/tinydtls/dtls.c b/extlibs/tinydtls/dtls.c
-index 41e68a5..b5b8fd1 100644
---- a/extlibs/tinydtls/dtls.c
-+++ b/extlibs/tinydtls/dtls.c
-@@ -496,11 +496,11 @@ static inline int is_tls_psk_with_aes_128_ccm_8(dtls_cipher_t cipher)
- #endif /* DTLS_PSK */
- }
--/** returns true if the cipher matches TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
--static inline int is_tls_ecdh_anon_with_aes_128_cbc_sha(dtls_cipher_t cipher)
-+/** returns true if the cipher matches TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256 */
-+static inline int is_tls_ecdh_anon_with_aes_128_cbc_sha_256(dtls_cipher_t cipher)
- {
- #ifdef DTLS_ECC
--    return cipher == TLS_ECDH_anon_WITH_AES_128_CBC_SHA;
-+    return cipher == TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256;
- #else
-     return 0;
- #endif
-@@ -570,7 +570,7 @@ known_cipher(dtls_context_t *ctx, dtls_cipher_t code, int is_client) {
-   return (psk && is_tls_psk_with_aes_128_ccm_8(code)) ||
-        (ecdsa && is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(code)) ||
--       (ecdh_anon && is_tls_ecdh_anon_with_aes_128_cbc_sha(code));
-+       (ecdh_anon && is_tls_ecdh_anon_with_aes_128_cbc_sha_256(code));
- }
- /**
-@@ -719,7 +719,7 @@ calculate_key_block(dtls_context_t *ctx,
- #endif /* DTLS_PSK */
- #ifdef DTLS_ECC
-   case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
--  case TLS_ECDH_anon_WITH_AES_128_CBC_SHA: {
-+  case TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256: {
-     pre_master_len = dtls_ecdh_pre_master_secret(handshake->keyx.ecc.own_eph_priv,
-                                                handshake->keyx.ecc.other_eph_pub_x,
-                                                handshake->keyx.ecc.other_eph_pub_y,
-@@ -1084,7 +1084,7 @@ check_client_keyexchange(dtls_context_t *ctx,
- #ifdef DTLS_ECC
-   if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(handshake->cipher) ||
--       is_tls_ecdh_anon_with_aes_128_cbc_sha(handshake->cipher) ) {
-+       is_tls_ecdh_anon_with_aes_128_cbc_sha_256(handshake->cipher) ) {
-     if (length < DTLS_HS_LENGTH + DTLS_CKXEC_LENGTH) {
-       dtls_debug("The client key exchange is too short\n");
-@@ -1286,6 +1286,51 @@ dtls_prepare_record(dtls_peer_t *peer, dtls_security_parameters_t *security,
-       p += data_len_array[i];
-       res += data_len_array[i];
-     }
-+  } else if (is_tls_ecdh_anon_with_aes_128_cbc_sha_256(security->cipher)) {
-+
-+    unsigned char nonce[DTLS_CBC_IV_LENGTH];
-+
-+    /** Add IV into body of packet in case of AES CBC mode according to RFC 5246, Section 6.2.3.2
-+     *
-+     *    opaque IV[SecurityParameters.record_iv_length];
-+     *    block-ciphered struct {
-+     *        opaque content[TLSCompressed.length];
-+     *        opaque MAC[SecurityParameters.mac_length];
-+     *        uint8 padding[GenericBlockCipher.padding_length];
-+     *        uint8 padding_length;
-+     * };
-+     *
-+     */
-+
-+    res = 0;
-+    dtls_prng(nonce, DTLS_CBC_IV_LENGTH);
-+    memcpy(p , nonce, DTLS_CBC_IV_LENGTH);
-+    p += DTLS_CBC_IV_LENGTH;
-+    res += DTLS_CBC_IV_LENGTH;
-+
-+    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];
-+     }
-+
-+     res = dtls_encrypt(start + DTLS_CBC_IV_LENGTH, res - DTLS_CBC_IV_LENGTH,
-+               start + DTLS_CBC_IV_LENGTH, nonce,
-+               dtls_kb_local_write_key(security, peer->role),
-+               dtls_kb_key_size(security, peer->role),
-+               NULL, 0,
-+               security->cipher);
-+     if (res < 0)
-+       return res;
-+
-+     res += DTLS_CBC_IV_LENGTH;
-+
-   } 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
-@@ -1299,8 +1344,6 @@ dtls_prepare_record(dtls_peer_t *peer, dtls_security_parameters_t *security,
-       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 if (is_tls_ecdh_anon_with_aes_128_cbc_sha(security->cipher)) {
--        dtls_debug("dtls_prepare_record() : encrypt using TLS_ECDH_anon_WITH_AES_128_CBC_SHA\n");
-     } else {
-       dtls_debug("dtls_prepare_record(): encrypt using unknown cipher\n");
-     }
-@@ -1363,7 +1406,7 @@ dtls_prepare_record(dtls_peer_t *peer, dtls_security_parameters_t *security,
-     memset(nonce, 0, DTLS_CCM_BLOCKSIZE);
-     memcpy(nonce, dtls_kb_local_iv(security, peer->role),
--         dtls_kb_iv_size(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);
-@@ -1378,7 +1421,8 @@ dtls_prepare_record(dtls_peer_t *peer, dtls_security_parameters_t *security,
-     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),
-@@ -1388,7 +1432,7 @@ dtls_prepare_record(dtls_peer_t *peer, dtls_security_parameters_t *security,
-     if (res < 0)
-       return res;
--    res += 8;                 /* increment res by size of nonce_explicit */
-+    res += 8; /* increment res by size of nonce_explicit */
-     dtls_debug_dump("message:", start, res);
-   }
-@@ -2172,7 +2216,7 @@ dtls_send_server_hello_msgs(dtls_context_t *ctx, dtls_peer_t *peer)
-   }
-   ecdsa = is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher);
--  ecdh_anon = is_tls_ecdh_anon_with_aes_128_cbc_sha(peer->handshake_params->cipher);
-+  ecdh_anon = is_tls_ecdh_anon_with_aes_128_cbc_sha_256(peer->handshake_params->cipher);
- #ifdef DTLS_ECC
-   if(ecdh_anon) {
-@@ -2301,7 +2345,7 @@ dtls_send_client_key_exchange(dtls_context_t *ctx, dtls_peer_t *peer)
- #endif /* DTLS_PSK */
- #ifdef DTLS_ECC
-   case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
--  case TLS_ECDH_anon_WITH_AES_128_CBC_SHA: {
-+  case TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256: {
-     uint8 *ephemeral_pub_x;
-     uint8 *ephemeral_pub_y;
-@@ -2424,7 +2468,7 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
-       case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
-         ecdsa = is_ecdsa_supported(ctx, 1);
-         break;
--      case TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
-+      case TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256:
-         ecdh_anon = is_ecdh_anon_supported(ctx);
-         break;
-       default:
-@@ -2478,7 +2522,7 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
-   p += sizeof(uint16);
-   if (ecdh_anon) {
--    dtls_int_to_uint16(p, TLS_ECDH_anon_WITH_AES_128_CBC_SHA);
-+    dtls_int_to_uint16(p, TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256);
-     p += sizeof(uint16);
-   }
-   if (psk) {
-@@ -2809,7 +2853,7 @@ check_server_key_exchange_ecdh(dtls_context_t *ctx,
-   update_hs_hash(peer, data, data_length);
--  assert(is_tls_ecdh_anon_with_aes_128_cbc_sha(config->cipher));
-+  assert(is_tls_ecdh_anon_with_aes_128_cbc_sha_256(config->cipher));
-   data += DTLS_HS_LENGTH;
-@@ -3069,6 +3113,23 @@ decrypt_verify(dtls_peer_t *peer, uint8 *packet, size_t length,
-   if (security->cipher == TLS_NULL_WITH_NULL_NULL) {
-     /* no cipher suite selected */
-     return clen;
-+  } else if (is_tls_ecdh_anon_with_aes_128_cbc_sha_256(security->cipher)) {
-+
-+    unsigned char nonce[DTLS_CBC_IV_LENGTH];
-+
-+    if (clen < (DTLS_CBC_IV_LENGTH + DTLS_HMAC_DIGEST_SIZE))          /* need at least IV and MAC */
-+      return -1;
-+
-+    memcpy(nonce, *cleartext , DTLS_CBC_IV_LENGTH);
-+    clen -= DTLS_CBC_IV_LENGTH;
-+    *cleartext += DTLS_CBC_IV_LENGTH ;
-+
-+    clen = dtls_decrypt(*cleartext, clen, *cleartext, nonce,
-+                     dtls_kb_remote_write_key(security, peer->role),
-+                     dtls_kb_key_size(security, peer->role),
-+                     NULL, 0,
-+                     security->cipher);
-+
-   } 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
-@@ -3083,7 +3144,7 @@ decrypt_verify(dtls_peer_t *peer, uint8 *packet, size_t length,
-     memset(nonce, 0, DTLS_CCM_BLOCKSIZE);
-     memcpy(nonce, dtls_kb_remote_iv(security, peer->role),
--         dtls_kb_iv_size(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);
-@@ -3108,17 +3169,19 @@ decrypt_verify(dtls_peer_t *peer, uint8 *packet, size_t length,
-                      dtls_kb_remote_write_key(security, peer->role),
-                      dtls_kb_key_size(security, peer->role),
-                      A_DATA, A_DATA_LEN,
--               security->cipher);
--    if (clen < 0)
--      dtls_warn("decryption failed\n");
--    else {
-+                     security->cipher);
-+  }
-+
-+  if (clen < 0)
-+    dtls_warn("decryption failed\n");
-+  else {
- #ifndef NDEBUG
-       dtls_debug("decrypt_verify(): found %i bytes cleartext\n", clen);
- #endif
-       dtls_security_params_free_other(peer);
-       dtls_debug_dump("cleartext", *cleartext, clen);
--    }
-   }
-+
-   return clen;
- }
-@@ -3219,7 +3282,7 @@ handle_handshake_msg(dtls_context_t *ctx, dtls_peer_t *peer, session_t *session,
-     }
-     if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher))
-       peer->state = DTLS_STATE_WAIT_SERVERCERTIFICATE; //ecdsa
--    else if (is_tls_ecdh_anon_with_aes_128_cbc_sha(peer->handshake_params->cipher))
-+    else if (is_tls_ecdh_anon_with_aes_128_cbc_sha_256(peer->handshake_params->cipher))
-         peer->state = DTLS_STATE_WAIT_SERVERKEYEXCHANGE; //ecdh
-     else
-       peer->state = DTLS_STATE_WAIT_SERVERHELLODONE; //psk
-@@ -3259,7 +3322,7 @@ handle_handshake_msg(dtls_context_t *ctx, dtls_peer_t *peer, session_t *session,
-       err = check_server_key_exchange_ecdsa(ctx, peer, data, data_length);
-     }
--    if (is_tls_ecdh_anon_with_aes_128_cbc_sha(peer->handshake_params->cipher)) {
-+    if (is_tls_ecdh_anon_with_aes_128_cbc_sha_256(peer->handshake_params->cipher)) {
-       if (state != DTLS_STATE_WAIT_SERVERKEYEXCHANGE) {
-         return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE);
-       }
-diff --git a/extlibs/tinydtls/dtls.h b/extlibs/tinydtls/dtls.h
-index a2ab86e..7d2bc19 100644
---- a/extlibs/tinydtls/dtls.h
-+++ b/extlibs/tinydtls/dtls.h
-@@ -238,7 +238,7 @@ typedef struct dtls_context_t {
-   dtls_handler_t *h;          /**< callback handlers */
--  dtls_cipher_enable_t is_anon_ecdh_eabled;    /**< enable/disable the TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
-+  dtls_cipher_enable_t is_anon_ecdh_eabled;    /**< enable/disable the TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256 */
-   dtls_cipher_t selected_cipher; /**< selected ciper suite for handshake */
-@@ -268,7 +268,7 @@ static inline void dtls_set_handler(dtls_context_t *ctx, dtls_handler_t *h) {
- }
-  /**
--  * @brief Enabling the TLS_ECDH_anon_WITH_AES_128_CBC_SHA
-+  * @brief Enabling the TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256
-   *
-   * @param ctx              The DTLS context to use.
-   * @param is_enable    DTLS_CIPHER_ENABLE(1) or DTLS_CIPHER_DISABLE(0)
-@@ -279,7 +279,7 @@ void dtls_enables_anon_ecdh(dtls_context_t* ctx, dtls_cipher_enable_t is_enable)
-  * @brief Select the cipher suite for handshake
-  *
-  * @param ctx              The DTLS context to use.
-- * @param cipher         TLS_ECDH_anon_WITH_AES_128_CBC_SHA (0xC018)
-+ * @param cipher         TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256 (0xC018)
-  *                                  TLS_PSK_WITH_AES_128_CCM_8 (0xX0A8)
-  *                                  TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 (0xC0AE)
-  */
-diff --git a/extlibs/tinydtls/global.h b/extlibs/tinydtls/global.h
-index 441710f..169c726 100644
---- a/extlibs/tinydtls/global.h
-+++ b/extlibs/tinydtls/global.h
-@@ -73,7 +73,7 @@ typedef unsigned char uint48[6];
- /** Known cipher suites.*/
- typedef enum { 
-   TLS_NULL_WITH_NULL_NULL = 0x0000,   /**< NULL cipher  */
--  TLS_ECDH_anon_WITH_AES_128_CBC_SHA = 0xC018, /**< see RFC 4492 */
-+  TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256 = 0xC018, /**< see RFC 4492 */
-   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;
-diff --git a/extlibs/tinydtls/tests/dtls-client.c b/extlibs/tinydtls/tests/dtls-client.c
-index 35521e9..dfc822a 100644
---- a/extlibs/tinydtls/tests/dtls-client.c
-+++ b/extlibs/tinydtls/tests/dtls-client.c
-@@ -309,7 +309,7 @@ usage( const char *program, const char *version) {
-         "\t-p port\t\tlisten on specified port (default is %d)\n"
-         "\t-v num\t\tverbosity level (default: 3)\n"
-           "\t-c num\t\tcipher suite (default: 1)\n"
--          "\t\t\t1: TLS_ECDH_anon_WITH_AES_128_CBC_SHA \n"
-+          "\t\t\t1: TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256 \n"
-           "\t\t\t2: TLS_PSK_WITH_AES_128_CCM_8\n"
-           "\t\t\t3: TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8\n",
-          program, version, program, DEFAULT_PORT);
-@@ -347,7 +347,7 @@ main(int argc, char **argv) {
-   log_t log_level = DTLS_LOG_WARN;
-   int fd, result;
-   int on = 1;
--  dtls_cipher_t selected_cipher = TLS_ECDH_anon_WITH_AES_128_CBC_SHA;
-+  dtls_cipher_t selected_cipher = TLS_NULL_WITH_NULL_NULL;
-   dtls_cipher_enable_t ecdh_anon_enalbe = DTLS_CIPHER_ENABLE;
-   int opt, res;
-   session_t dst;
-@@ -417,7 +417,7 @@ main(int argc, char **argv) {
-     case 'c':
-       if( strcmp(optarg, "1") == 0)
-       {
--          selected_cipher = TLS_ECDH_anon_WITH_AES_128_CBC_SHA;
-+          selected_cipher = TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256;
-           ecdh_anon_enalbe = DTLS_CIPHER_ENABLE;
-       }
-       else if( strcmp(optarg, "2") == 0)
-@@ -500,7 +500,7 @@ main(int argc, char **argv) {
-   /* select cipher suite */
-   dtls_select_cipher(dtls_context, selected_cipher);
--  /* enable/disable tls_ecdh_anon_with_aes_128_cbc_sha */
-+  /* enable/disable tls_ecdh_anon_with_aes_128_cbc_sha_256 */
-   dtls_enables_anon_ecdh(dtls_context, ecdh_anon_enalbe);
-   dtls_set_handler(dtls_context, &cb);
-diff --git a/extlibs/tinydtls/tests/dtls-server.c b/extlibs/tinydtls/tests/dtls-server.c
-index d3da1a7..5893084 100644
---- a/extlibs/tinydtls/tests/dtls-server.c
-+++ b/extlibs/tinydtls/tests/dtls-server.c
-@@ -254,8 +254,8 @@ usage(const char *program, const char *version) {
-         "\t-p port\t\tlisten on specified port (default is %d)\n"
-         "\t-v num\t\tverbosity level (default: 3)\n"
-         "\t-a enable|disable\t(default: disable)\n"
--        "\t\t\t\tenable:enable TLS_ECDH_anon_with_AES_128_CBC_SHA\n"
--        "\t\t\t\tdisable:disable TLS_ECDH_anon_with_AES_128_CBC_SHA\n",
-+        "\t\t\t\tenable:enable TLS_ECDH_anon_with_AES_128_CBC_SHA_256\n"
-+        "\t\t\t\tdisable:disable TLS_ECDH_anon_with_AES_128_CBC_SHA_256\n",
-          program, version, program, DEFAULT_PORT);
- }
-@@ -280,7 +280,7 @@ main(int argc, char **argv) {
-   struct timeval timeout;
-   int fd, opt, result;
-   int on = 1;
--  int ecdh_anon_enalbe = DTLS_CIPHER_DISABLE;
-+  dtls_cipher_enable_t ecdh_anon_enalbe = DTLS_CIPHER_DISABLE;
-   struct sockaddr_in6 listen_addr;
-   memset(&listen_addr, 0, sizeof(struct sockaddr_in6));
-@@ -356,7 +356,7 @@ main(int argc, char **argv) {
-   the_context = dtls_new_context(&fd);
--  /* enable/disable tls_ecdh_anon_with_aes_128_cbc_sha */
-+  /* enable/disable tls_ecdh_anon_with_aes_128_cbc_sha_256 */
-   dtls_enables_anon_ecdh(the_context, ecdh_anon_enalbe);
-   dtls_set_handler(the_context, &cb);
-diff --git a/resource/csdk/connectivity/api/cainterface.h b/resource/csdk/connectivity/api/cainterface.h
-index 760df09..2f10fd5 100644
---- a/resource/csdk/connectivity/api/cainterface.h
-+++ b/resource/csdk/connectivity/api/cainterface.h
-@@ -290,7 +290,7 @@ CAResult_t CAHandleRequestResponse();
-  * Select the cipher suite for dtls handshake
-  *
-  * @param[IN] cipher  cipher suite (Note : Make sure endianness)
-- *                               0xC018 : TLS_ECDH_anon_WITH_AES_128_CBC_SHA
-+ *                               0xC018 : TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256
-  *                               0xC0A8 : TLS_PSK_WITH_AES_128_CCM_8
-  *                               0xC0AE : TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
-  *
-@@ -301,7 +301,7 @@ CAResult_t CAHandleRequestResponse();
- CAResult_t CASelectCipherSuite(const uint16_t cipher);
- /**
-- * Enable TLS_ECDH_anon_WITH_AES_128_CBC_SHA cipher suite in dtls
-+ * Enable TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256 cipher suite in dtls
-  *
-  * @param[IN] enable  TRUE/FALSE enables/disables anonymous cipher suite
-  *
-diff --git a/resource/csdk/connectivity/inc/caadapternetdtls.h b/resource/csdk/connectivity/inc/caadapternetdtls.h
-index f9f99d8..274321e 100644
---- a/resource/csdk/connectivity/inc/caadapternetdtls.h
-+++ b/resource/csdk/connectivity/inc/caadapternetdtls.h
-@@ -160,7 +160,7 @@ void CADTLSSetCredentialsCallback(CAGetDTLSCredentialsHandler credCallback);
-  * Select the cipher suite for dtls handshake
-  *
-  * @param[in] cipher    cipher suite
-- *                             0xC018 : TLS_ECDH_anon_WITH_AES_128_CBC_SHA
-+ *                             0xC018 : TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256
-  *                             0xC0A8 : TLS_PSK_WITH_AES_128_CCM_8
-  *                             0xC0AE : TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
-  *
-diff --git a/resource/csdk/connectivity/src/adapter_util/caadapternetdtls.c b/resource/csdk/connectivity/src/adapter_util/caadapternetdtls.c
-index 8f01c06..6fd83e8 100644
---- a/resource/csdk/connectivity/src/adapter_util/caadapternetdtls.c
-+++ b/resource/csdk/connectivity/src/adapter_util/caadapternetdtls.c
-@@ -598,7 +598,7 @@ CAResult_t CADtlsEnableAnonECDHCipherSuite(const bool enable)
-     dtls_enables_anon_ecdh(g_caDtlsContext->dtlsContext,
-         enable == true ? DTLS_CIPHER_ENABLE : DTLS_CIPHER_DISABLE);
-     ca_mutex_unlock(g_dtlsContextMutex);
--    OIC_LOG_V(DEBUG, NET_DTLS_TAG, "TLS_ECDH_anon_WITH_AES_128_CBC_SHA  is %s",
-+    OIC_LOG_V(DEBUG, NET_DTLS_TAG, "TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256  is %s",
-         enable ? "enabled" : "disabled");
-     OIC_LOG(DEBUG, NET_DTLS_TAG, "OUT CADtlsEnablesAnonEcdh");
-diff --git a/resource/csdk/security/provisioning/src/provisioningmanager.c b/resource/csdk/security/provisioning/src/provisioningmanager.c
-index defe4e6..301614d 100644
---- a/resource/csdk/security/provisioning/src/provisioningmanager.c
-+++ b/resource/csdk/security/provisioning/src/provisioningmanager.c
-@@ -1031,7 +1031,7 @@ static SPResult updateOperationMode(unsigned short timeout, SPTargetDeviceInfo_t
-  */
- static SPResult initiateDtlsHandshake(const SPTargetDeviceInfo_t *deviceInfo)
- {
--    CAResult_t caresult = CASelectCipherSuite(TLS_ECDH_anon_WITH_AES_128_CBC_SHA);
-+    CAResult_t caresult = CASelectCipherSuite(TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256);
-     if (CA_STATUS_OK != caresult)
-     {
--- 
-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
deleted file mode 100644 (file)
index 343c891..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-From 116451f8fab0df90e87d394d1fa1ac9e739c7dbe Mon Sep 17 00:00:00 2001
-From: Sachin Agrawal <sachin.agrawal@intel.com>
-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 <sachin.agrawal@intel.com>
----
- 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
deleted file mode 100644 (file)
index 4470e1a..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-From 6b26519bea04167b9cf68069bf641af4651c87e0 Mon Sep 17 00:00:00 2001
-From: Sachin Agrawal <sachin.agrawal@intel.com>
-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 <sachin.agrawal@intel.com>
----
- 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 <bergmann@tzi.org>\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/0001-add-support-of-X.509-into-tinyDTLS-external-library.patch b/extlibs/tinydtls/0001-add-support-of-X.509-into-tinyDTLS-external-library.patch
deleted file mode 100644 (file)
index 6baafd8..0000000
+++ /dev/null
@@ -1,1960 +0,0 @@
-From 3a354d276c3375fd0ef20f5ced8f6c4d8c39c419 Mon Sep 17 00:00:00 2001
-From: Oleksii Udod <o.udod@samsung.com>
-Date: Wed, 12 Aug 2015 17:20:21 +0300
-Subject: [PATCH 1/1] add support of X.509 into tinyDTLS external library
-
-Change-Id: I560506e0c0828674969829c9e900ae08bacaeef1
-Signed-off-by: Oleksii Udod <o.udod@samsung.com>
----
- extlibs/tinydtls/SConscript          |   5 +-
- extlibs/tinydtls/configure.in        |   6 +
- extlibs/tinydtls/crypto.c            |   2 +-
- extlibs/tinydtls/crypto.h            |   4 +-
- extlibs/tinydtls/dtls.c              | 257 ++++++++++++++++++++-----
- extlibs/tinydtls/dtls.h              | 108 ++++++++++-
- extlibs/tinydtls/dtls_config.h       |  51 +++++
- extlibs/tinydtls/dtls_config.h.in    |   3 +
- extlibs/tinydtls/global.h            |   7 +-
- extlibs/tinydtls/netq.h              |   2 +-
- extlibs/tinydtls/tests/Makefile.in   |   4 +-
- extlibs/tinydtls/tests/dtls-client.c | 336 ++++++++++++++++++++++++++++++--
- extlibs/tinydtls/tests/dtls-server.c | 358 +++++++++++++++++++++++++++++++++--
- extlibs/tinydtls/tinydtls.h          |   3 +
- extlibs/tinydtls/tinydtls.h.in       |   3 +
- 15 files changed, 1065 insertions(+), 84 deletions(-)
-
-diff --git a/extlibs/tinydtls/SConscript b/extlibs/tinydtls/SConscript
-index 4c6b4e1..7ca5ae2 100644
---- a/extlibs/tinydtls/SConscript
-+++ b/extlibs/tinydtls/SConscript
-@@ -31,7 +31,6 @@ if(target_os) == 'arduino':
-       env.Replace(CFLAGS = env.get('CXXFLAGS'))
- root_dir = './'
--
- tinydtls_src_path = root_dir
- env.AppendUnique(CPPPATH = [root_dir])
-@@ -62,7 +61,7 @@ tinydtls_src = [
- env.AppendUnique(TINYDTLS_SRC = tinydtls_src)
- if not env.get('RELEASE'):
--      if(target_os) not in ['arduino']:
-+      if(target_os) not in ['android', 'arduino']:
-               env.AppendUnique(TINYDTLS_SRC = ['debug.c'])
-       else:
-               env.AppendUnique(CPPDEFINES = ['NDEBUG'])
-@@ -71,6 +70,7 @@ else:
- env.AppendUnique(CPPDEFINES = ['DTLSV12',  'WITH_SHA256', 'DTLS_CHECK_CONTENTTYPE'])
-+
- libtinydtls = env.StaticLibrary('libtinydtls', env.get('TINYDTLS_SRC'), OBJPREFIX='libtinydtls_')
- ######################################################################
-@@ -94,6 +94,7 @@ if not env.get('RELEASE'):
-       samples_env.PrependUnique(LIBS = ['tinydtls'])
-       Alias("samples", [dtlsserver, dtlsclient])
-+
-       samples_env.AppendTarget('samples')
- env.InstallTarget(libtinydtls, 'libtinydtls');
-diff --git a/extlibs/tinydtls/configure.in b/extlibs/tinydtls/configure.in
-index 70b9a54..c3ebbf3 100644
---- a/extlibs/tinydtls/configure.in
-+++ b/extlibs/tinydtls/configure.in
-@@ -69,6 +69,12 @@ AC_ARG_WITH(psk,
-   [AC_DEFINE(DTLS_PSK, 1, [Define to 1 if building with PSK support])
-    DTLS_PSK=1])
-+AC_ARG_WITH(x509,
-+  [AS_HELP_STRING([--with-x509],[use dtls as transport protocol])],
-+  [AC_DEFINE(DTLS_X509, 1, [Define to 1 if building with X.509 support])
-+   DTLS_X509=1],
-+  [])
-+
- CPPFLAGS="${CPPFLAGS} -DDTLSv12 -DWITH_SHA256"
- OPT_OBJS="${OPT_OBJS} sha2/sha2.o"
-diff --git a/extlibs/tinydtls/crypto.c b/extlibs/tinydtls/crypto.c
-index deaf581..7433432 100644
---- a/extlibs/tinydtls/crypto.c
-+++ b/extlibs/tinydtls/crypto.c
-@@ -493,7 +493,7 @@ dtls_psk_pre_master_secret(unsigned char *key, size_t keylen,
- }
- #endif /* DTLS_PSK */
--#ifdef DTLS_ECC
-+#if defined(DTLS_ECC) || defined(DTLS_X509)
- int dtls_ec_key_from_uint32_asn1(const uint32_t *key, size_t key_size,
-                                unsigned char *buf) {
-diff --git a/extlibs/tinydtls/crypto.h b/extlibs/tinydtls/crypto.h
-index f4cfc66..cade1b2 100644
---- a/extlibs/tinydtls/crypto.h
-+++ b/extlibs/tinydtls/crypto.h
-@@ -131,14 +131,14 @@ typedef struct {
-   dtls_cipher_t cipher;               /**< cipher type */
-   unsigned int do_client_auth:1;
--#ifdef DTLS_ECC && DTLS_PSK
-+#if defined(DTLS_ECC) && defined(DTLS_PSK)
-   struct keyx_t {
-     dtls_handshake_parameters_ecc_t ecc;
-     dtls_handshake_parameters_psk_t psk;
-   } keyx;
- #else /* DTLS_ECC && DTLS_PSK */
-   union {
--#ifdef DTLS_ECC
-+#if defined(DTLS_ECC) || defined(DTLS_X509)
-     dtls_handshake_parameters_ecc_t ecc;
- #endif /* DTLS_ECC */
- #ifdef DTLS_PSK
-diff --git a/extlibs/tinydtls/dtls.c b/extlibs/tinydtls/dtls.c
-index 6104a08..f1e2486 100644
---- a/extlibs/tinydtls/dtls.c
-+++ b/extlibs/tinydtls/dtls.c
-@@ -479,7 +479,7 @@ static uint8 compression_methods[] = {
- /** 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
-+#if defined(DTLS_ECC) || defined(DTLS_X509)
-   return cipher == TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8;
- #else
-   return 0;
-@@ -532,13 +532,24 @@ static inline int is_psk_supported(dtls_context_t *ctx)
- 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) || 
-+  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 x509 */
-+static inline int is_x509_supported(dtls_context_t *ctx, int is_client)
-+{
-+#ifdef DTLS_X509
-+  return ctx && ctx->h && ((!is_client && ctx->h->get_x509_cert) ||
-+               (is_client && ctx->h->verify_x509_cert));
-+#else
-+  return 0;
-+#endif /* DTLS_X509 */
-+}
-+
- /** 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)
-@@ -550,6 +561,17 @@ static inline int is_ecdsa_client_auth_supported(dtls_context_t *ctx)
- #endif /* DTLS_ECC */
- }
-+/** Returns true if the application is configured for x509 with
-+  * client authentication */
-+static inline int is_x509_client_auth_supported(dtls_context_t *ctx)
-+{
-+#ifdef DTLS_X509
-+  return ctx && ctx->h && ctx->h->get_x509_cert && ctx->h->verify_x509_cert;
-+#else
-+  return 0;
-+#endif /* DTLS_X509 */
-+}
-+
- /** returns true if ecdh_anon_with_aes_128_cbc_sha is supported */
- static inline int is_ecdh_anon_supported(dtls_context_t *ctx)
- {
-@@ -586,16 +608,19 @@ known_cipher(dtls_context_t *ctx, dtls_cipher_t code, int is_client) {
-   int ecdsa;
-   int ecdh_anon;
-   int ecdhe_psk;
-+  int x509;
-   psk = is_psk_supported(ctx);
-   ecdsa = is_ecdsa_supported(ctx, is_client);
-   ecdh_anon = is_ecdh_anon_supported(ctx);
-   ecdhe_psk = is_ecdhe_psk_supported(ctx);
-+  x509 = is_x509_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)) ||
-        (ecdh_anon && is_tls_ecdh_anon_with_aes_128_cbc_sha_256(code)) ||
--       (ecdhe_psk && is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(code));
-+       (ecdhe_psk && is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(code)) ||
-+     (x509 && is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(code));
- }
- /**
-@@ -744,7 +769,7 @@ calculate_key_block(dtls_context_t *ctx,
-     break;
-   }
- #endif /* DTLS_PSK */
--#ifdef DTLS_ECC
-+#if defined(DTLS_ECC) || defined(DTLS_X509)
-   case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
-   case TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256: {
-     pre_master_len = dtls_ecdh_pre_master_secret(handshake->keyx.ecc.own_eph_priv,
-@@ -870,8 +895,13 @@ static int verify_ext_cert_type(uint8 *data, size_t data_length) {
-     cert_type = dtls_uint8_to_int(data);
-     data += sizeof(uint8);
-+
-     if (cert_type == TLS_CERT_TYPE_RAW_PUBLIC_KEY)
--      return 0;
-+        return 0;
-+#ifdef DTLS_X509
-+    if (cert_type == TLS_CERT_TYPE_X509)
-+        return 0;
-+#endif
-   }
-   dtls_warn("no supported certificate type found\n");
-@@ -962,7 +992,12 @@ dtls_check_tls_extension(dtls_peer_t *peer,
-         if (verify_ext_cert_type(data, j))
-             goto error;
-         } else {
-+#ifndef DTLS_X509
-         if (dtls_uint8_to_int(data) != TLS_CERT_TYPE_RAW_PUBLIC_KEY)
-+#else
-+        if ((dtls_uint8_to_int(data) != TLS_CERT_TYPE_RAW_PUBLIC_KEY) &&
-+            (dtls_uint8_to_int(data) != TLS_CERT_TYPE_X509))
-+#endif
-           goto error;
-         }
-         break;
-@@ -972,7 +1007,12 @@ dtls_check_tls_extension(dtls_peer_t *peer,
-         if (verify_ext_cert_type(data, j))
-             goto error;
-         } else {
-+#ifndef DTLS_X509
-         if (dtls_uint8_to_int(data) != TLS_CERT_TYPE_RAW_PUBLIC_KEY)
-+#else
-+        if ((dtls_uint8_to_int(data) != TLS_CERT_TYPE_RAW_PUBLIC_KEY) &&
-+            (dtls_uint8_to_int(data) != TLS_CERT_TYPE_X509))
-+#endif
-           goto error;
-         }
-         break;
-@@ -1138,7 +1178,7 @@ check_client_keyexchange(dtls_context_t *ctx,
-                        dtls_handshake_parameters_t *handshake,
-                        uint8 *data, size_t length) {
--#ifdef DTLS_ECC
-+#if defined(DTLS_ECC) || defined(DTLS_X509)
-   if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(handshake->cipher) ||
-        is_tls_ecdh_anon_with_aes_128_cbc_sha_256(handshake->cipher) ) {
-@@ -1529,7 +1569,6 @@ dtls_prepare_record(dtls_peer_t *peer, dtls_security_parameters_t *security,
-     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),
-@@ -1841,7 +1880,7 @@ dtls_verify_peer(dtls_context_t *ctx,
- #undef mycookie
- }
--#ifdef DTLS_ECC
-+#if defined(DTLS_ECC) || defined(DTLS_X509)
- static int
- dtls_check_ecdsa_signature_elem(uint8 *data, size_t data_length,
-                               unsigned char **result_r,
-@@ -2025,8 +2064,13 @@ dtls_send_server_hello(dtls_context_t *ctx, dtls_peer_t *peer)
-     /* length of this extension type */
-     dtls_int_to_uint16(p, 1);
-     p += sizeof(uint16);
-+#ifdef DTLS_X509
-+    if (CALL(ctx, is_x509_active) == 0)
-+      dtls_int_to_uint8(p, TLS_CERT_TYPE_X509);
-+    else
-+#endif /* DTLS_X509 */
-+      dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY);
--    dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY);
-     p += sizeof(uint8);
-     /* client certificate type extension */
-@@ -2037,7 +2081,13 @@ dtls_send_server_hello(dtls_context_t *ctx, dtls_peer_t *peer)
-     dtls_int_to_uint16(p, 1);
-     p += sizeof(uint16);
--    dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY);
-+#ifdef DTLS_X509
-+    if (CALL(ctx, is_x509_active) == 0)
-+      dtls_int_to_uint8(p, TLS_CERT_TYPE_X509);
-+    else
-+#endif /* DTLS_X509 */
-+      dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY);
-+
-     p += sizeof(uint8);
-     /* ec_point_formats */
-@@ -2072,7 +2122,7 @@ dtls_send_certificate_ecdsa(dtls_context_t *ctx, dtls_peer_t *peer,
-   uint8 buf[DTLS_CE_LENGTH];
-   uint8 *p;
--  /* Certificate 
-+  /* Certificate
-    *
-    * Start message construction at beginning of buffer. */
-   p = buf;
-@@ -2097,7 +2147,46 @@ dtls_send_certificate_ecdsa(dtls_context_t *ctx, dtls_peer_t *peer,
-   return dtls_send_handshake_msg(ctx, peer, DTLS_HT_CERTIFICATE,
-                                buf, p - buf);
- }
-+#endif /* DTLS_ECC */
-+
-+#ifdef DTLS_X509
-+static int
-+dtls_send_certificate_x509(dtls_context_t *ctx, dtls_peer_t *peer)
-+{
-+  uint8 buf[DTLS_MAX_CERT_SIZE];
-+  uint8 *p;
-+  int ret;
-+  unsigned char *cert;
-+  size_t cert_size;
-+
-+  dtls_info("\n dtls_send_certificate_ecdsa\n");
-+  ret = CALL(ctx, get_x509_cert, &peer->session,
-+          (const unsigned char **)&cert, &cert_size);
-+
-+  if (ret < 0) {
-+    dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE);
-+    return ret;
-+  }
-+
-+  /* Certificate
-+   *
-+   * Start message construction at beginning of buffer. */
-+  p = buf;
-+
-+  dtls_int_to_uint24(p, cert_size); /* certificates length */
-+  p += sizeof(uint24);
-+
-+  memcpy(p, cert, cert_size);
-+  p += cert_size;
-+
-+  assert(p - buf <= sizeof(buf));
-+
-+  return dtls_send_handshake_msg(ctx, peer, DTLS_HT_CERTIFICATE,
-+                               buf, p - buf);
-+}
-+#endif /* DTLS_X509 */
-+#if defined(DTLS_X509) || defined(DTLS_ECC)
- static uint8 *
- dtls_add_ecdsa_signature_elem(uint8 *p, uint32_t *point_r, uint32_t *point_s)
- {
-@@ -2204,7 +2293,6 @@ dtls_send_server_key_exchange_ecdh(dtls_context_t *ctx, dtls_peer_t *peer,
-   dtls_ecdsa_generate_key(config->keyx.ecc.own_eph_priv,
-               ephemeral_pub_x, ephemeral_pub_y,
-               DTLS_EC_KEY_SIZE);
--
-   if(ecdsa) {
-       /* sign the ephemeral and its paramaters */
-            dtls_ecdsa_create_sig(key->priv_key, DTLS_EC_KEY_SIZE,
-@@ -2221,7 +2309,7 @@ dtls_send_server_key_exchange_ecdh(dtls_context_t *ctx, dtls_peer_t *peer,
-   return dtls_send_handshake_msg(ctx, peer, DTLS_HT_SERVER_KEY_EXCHANGE,
-                                buf, p - buf);
- }
--#endif /* DTLS_ECC */
-+#endif /* defined(DTLS_X509) || defined(DTLS_ECC) */
- #if defined(DTLS_PSK) && defined(DTLS_ECC)
- static int dtls_send_server_key_exchange_ecdhe_psk(dtls_context_t *ctx, dtls_peer_t *peer,
-@@ -2327,7 +2415,7 @@ dtls_send_server_key_exchange_psk(dtls_context_t *ctx, dtls_peer_t *peer,
- }
- #endif /* DTLS_PSK */
--#ifdef DTLS_ECC
-+#if defined(DTLS_ECC) || defined(DTLS_X509)
- static int
- dtls_send_server_certificate_request(dtls_context_t *ctx, dtls_peer_t *peer)
- {
-@@ -2401,7 +2489,7 @@ dtls_send_server_hello_msgs(dtls_context_t *ctx, dtls_peer_t *peer)
-   ecdh_anon = is_tls_ecdh_anon_with_aes_128_cbc_sha_256(peer->handshake_params->cipher);
-   ecdhe_psk = is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(peer->handshake_params->cipher);
--#ifdef DTLS_ECC
-+#if defined(DTLS_ECC) || defined(DTLS_X509)
-   if(ecdh_anon) {
-       res = dtls_send_server_key_exchange_ecdh(ctx, peer, NULL);
-@@ -2413,13 +2501,24 @@ dtls_send_server_hello_msgs(dtls_context_t *ctx, dtls_peer_t *peer)
-   else if (ecdsa) {
-     const dtls_ecc_key_t *ecdsa_key;
--    res = CALL(ctx, get_ecdsa_key, &peer->session, &ecdsa_key);
-+#ifdef DTLS_X509
-+    if (CALL(ctx, is_x509_active) == 0)
-+      res = CALL(ctx, get_x509_key, &peer->session, &ecdsa_key);
-+    else
-+#endif /* DTLS_X509 */
-+      res = CALL(ctx, get_ecdsa_key, &peer->session, &ecdsa_key);
-+
-     if (res < 0) {
--      dtls_crit("no ecdsa certificate to send in certificate\n");
-+        dtls_debug("no ecdsa key to send\n");
-       return res;
-     }
--    res = dtls_send_certificate_ecdsa(ctx, peer, ecdsa_key);
-+#ifdef DTLS_X509
-+    if (CALL(ctx, is_x509_active) == 0)
-+      res = dtls_send_certificate_x509(ctx, peer);
-+    else
-+#endif /* DTLS_X509 */
-+      res = dtls_send_certificate_ecdsa(ctx, peer, ecdsa_key);
-     if (res < 0) {
-       dtls_debug("dtls_server_hello: cannot prepare Certificate record\n");
-@@ -2434,9 +2533,8 @@ dtls_send_server_hello_msgs(dtls_context_t *ctx, dtls_peer_t *peer)
-     }
-     if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher) &&
--      is_ecdsa_client_auth_supported(ctx)) {
-+      (is_ecdsa_client_auth_supported(ctx) || (is_x509_client_auth_supported(ctx)))) {
-       res = dtls_send_server_certificate_request(ctx, peer);
--
-       if (res < 0) {
-         dtls_debug("dtls_server_hello(with ECDSA): cannot prepare certificate Request record\n");
-         return res;
-@@ -2554,7 +2652,7 @@ dtls_send_client_key_exchange(dtls_context_t *ctx, dtls_peer_t *peer)
-     break;
-   }
- #endif /* DTLS_PSK */
--#ifdef DTLS_ECC
-+#if defined(DTLS_ECC) || defined(DTLS_X509)
-   case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
-   case TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256: {
-     uint8 *ephemeral_pub_x;
-@@ -2644,7 +2742,7 @@ dtls_send_client_key_exchange(dtls_context_t *ctx, dtls_peer_t *peer)
-                                buf, p - buf);
- }
--#ifdef DTLS_ECC
-+#if defined(DTLS_ECC) || defined(DTLS_X509)
- static int
- dtls_send_certificate_verify_ecdh(dtls_context_t *ctx, dtls_peer_t *peer,
-                                  const dtls_ecc_key_t *key)
-@@ -2723,6 +2821,7 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
-   int ecdsa = 0;
-   int ecdh_anon = 0;
-   int ecdhe_psk = 0;
-+  int x509 = 0;
-   dtls_handshake_parameters_t *handshake = peer->handshake_params;
-   dtls_tick_t now;
-@@ -2733,6 +2832,7 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
-         break;
-       case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
-         ecdsa = is_ecdsa_supported(ctx, 1);
-+        x509 = is_x509_supported(ctx, 1);
-         break;
-       case TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256:
-         ecdh_anon = is_ecdh_anon_supported(ctx);
-@@ -2745,11 +2845,12 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
-         ecdsa = is_ecdsa_supported(ctx, 1);
-         ecdh_anon = is_ecdh_anon_supported(ctx);
-         ecdhe_psk = is_ecdhe_psk_supported(ctx);
-+        x509 = is_x509_supported(ctx, 1);
-         break;
-    }
--  cipher_size = 2 + (ecdsa ? 2 : 0) + (psk ? 2 : 0) + (ecdh_anon ? 2 : 0) + (ecdhe_psk ? 2 : 0);
--  extension_size = (ecdsa) ? (2 + 6 + 6 + 8 + 6) : 0;
-+  cipher_size = 2 + ((ecdsa || x509) ? 2 : 0) + (psk ? 2 : 0) + (ecdh_anon ? 2 : 0) + (ecdhe_psk ? 2 : 0);
-+  extension_size = (ecdsa || x509) ? (2 + 6 + 6 + 8 + 6) : 0;
-   if (cipher_size == 0) {
-     dtls_crit("no cipher callbacks implemented\n");
-@@ -2799,7 +2900,7 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
-     dtls_int_to_uint16(p, TLS_PSK_WITH_AES_128_CCM_8);
-     p += sizeof(uint16);
-   }
--  if (ecdsa) {
-+  if (ecdsa || x509) {
-     dtls_int_to_uint16(p, TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8);
-     p += sizeof(uint16);
-   }
-@@ -2821,7 +2922,7 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
-     p += sizeof(uint16);
-   }
--  if (ecdsa) {
-+  if (ecdsa || x509) {
-     /* client certificate type extension */
-     dtls_int_to_uint16(p, TLS_EXT_CLIENT_CERTIFICATE_TYPE);
-     p += sizeof(uint16);
-@@ -2834,7 +2935,13 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
-     dtls_int_to_uint8(p, 1);
-     p += sizeof(uint8);
--    dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY);
-+#ifdef DTLS_X509
-+    if (CALL(ctx, is_x509_active) == 0)
-+      dtls_int_to_uint8(p, TLS_CERT_TYPE_X509);
-+    else
-+#endif /* DTLS_X509 */
-+      dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY);
-+
-     p += sizeof(uint8);
-     /* client certificate type extension */
-@@ -2849,7 +2956,13 @@ dtls_send_client_hello(dtls_context_t *ctx, dtls_peer_t *peer,
-     dtls_int_to_uint8(p, 1);
-     p += sizeof(uint8);
--    dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY);
-+#ifdef DTLS_X509
-+    if (CALL(ctx, is_x509_active) == 0)
-+      dtls_int_to_uint8(p, TLS_CERT_TYPE_X509);
-+    else
-+#endif /* DTLS_X509 */
-+      dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY);
-+
-     p += sizeof(uint8);
-     /* elliptic_curves */
-@@ -2985,8 +3098,9 @@ check_server_hello_verify_request(dtls_context_t *ctx,
- }
- #ifdef DTLS_ECC
-+
- static int
--check_server_certificate(dtls_context_t *ctx, 
-+check_peer_certificate(dtls_context_t *ctx,
-                        dtls_peer_t *peer,
-                        uint8 *data, size_t data_length)
- {
-@@ -3036,7 +3150,41 @@ check_server_certificate(dtls_context_t *ctx,
-   return 0;
- }
-+#endif /* DTLS_ECC */
-+
-+#ifdef DTLS_X509
-+static int
-+check_peer_certificate_x509(dtls_context_t *ctx,
-+                       dtls_peer_t *peer,
-+                       uint8 *data, size_t data_length)
-+{
-+  int ret;
-+  dtls_handshake_parameters_t *config = peer->handshake_params;
-+  int cert_length;
-+
-+  dtls_info("\n check_peer_certificate_x509\n");
-+  update_hs_hash(peer, data, data_length);
-+
-+  assert(is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(config->cipher));
-+
-+  data += DTLS_HS_LENGTH;
-+
-+  cert_length = dtls_uint24_to_int(data);
-+  data += sizeof(uint24);
-+
-+  ret = CALL(ctx, verify_x509_cert, &peer->session, data, cert_length,
-+          config->keyx.ecc.other_pub_x, sizeof(config->keyx.ecc.other_pub_x),
-+          config->keyx.ecc.other_pub_y, sizeof(config->keyx.ecc.other_pub_y));
-+  if (ret < 0) {
-+    dtls_warn("The certificate was not accepted\n");
-+    return ret;
-+  }
-+
-+  return 0;
-+}
-+#endif /* DTLS_X509 */
-+#if defined(DTLS_X509) || defined(DTLS_ECC)
- static int
- check_server_key_exchange_ecdsa(dtls_context_t *ctx,
-                               dtls_peer_t *peer,
-@@ -3385,13 +3533,17 @@ check_certificate_request(dtls_context_t *ctx,
- }
- static int
--check_server_hellodone(dtls_context_t *ctx, 
-+check_server_hellodone(dtls_context_t *ctx,
-                     dtls_peer_t *peer,
-                     uint8 *data, size_t data_length)
- {
--  int res;
-+  int res = 0;
- #ifdef DTLS_ECC
-   const dtls_ecc_key_t *ecdsa_key;
-+#ifdef DTLS_X509
-+  unsigned char *cert;
-+  size_t cert_size;
-+#endif /* DTLS_X509 */
- #endif /* DTLS_ECC */
-   dtls_handshake_parameters_t *handshake = peer->handshake_params;
-@@ -3400,16 +3552,25 @@ check_server_hellodone(dtls_context_t *ctx,
-   update_hs_hash(peer, data, data_length);
--#ifdef DTLS_ECC
-+#if defined(DTLS_ECC) || defined(DTLS_X509)
-   if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(handshake->cipher) && handshake->do_client_auth) {
--
--    res = CALL(ctx, get_ecdsa_key, &peer->session, &ecdsa_key);
-+#ifdef DTLS_X509
-+    if (CALL(ctx, is_x509_active) == 0)
-+      res = CALL(ctx, get_x509_key, &peer->session, &ecdsa_key);
-+    else
-+#endif /* DTLS_X509 */
-+      res = CALL(ctx, get_ecdsa_key, &peer->session, &ecdsa_key);
-     if (res < 0) {
--      dtls_crit("no ecdsa certificate to send in certificate\n");
-+      dtls_crit("no ecdsa key to use\n");
-       return res;
-     }
--    res = dtls_send_certificate_ecdsa(ctx, peer, ecdsa_key);
-+#ifdef DTLS_X509
-+    if (CALL(ctx, is_x509_active) == 0)
-+      res = dtls_send_certificate_x509(ctx, peer);
-+    else
-+#endif /* DTLS_X509 */
-+      res = dtls_send_certificate_ecdsa(ctx, peer, ecdsa_key);
-     if (res < 0) {
-       dtls_debug("dtls_server_hello: cannot prepare Certificate record\n");
-@@ -3428,7 +3589,6 @@ check_server_hellodone(dtls_context_t *ctx,
- #ifdef DTLS_ECC
-   if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(handshake->cipher) && handshake->do_client_auth) {
--
-     res = dtls_send_certificate_verify_ecdh(ctx, peer, ecdsa_key);
-     if (res < 0) {
-@@ -3655,16 +3815,21 @@ handle_handshake_msg(dtls_context_t *ctx, dtls_peer_t *peer, session_t *session,
-     break;
--#ifdef DTLS_ECC
-+#if defined(DTLS_ECC) || defined(DTLS_X509)
-   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);
-+#ifdef DTLS_X509
-+    if (CALL(ctx, is_x509_active) == 0)
-+      err = check_peer_certificate_x509(ctx, peer, data, data_length);
-+    else
-+#endif /* DTLS_X509 */
-+      err = check_peer_certificate(ctx, peer, data, data_length);
-     if (err < 0) {
--      dtls_warn("error in check_server_certificate err: %i\n", err);
-+      dtls_warn("error in check_peer_certificate err: %i\n", err);
-       return err;
-     }
-     if (role == DTLS_CLIENT) {
-@@ -3679,7 +3844,7 @@ handle_handshake_msg(dtls_context_t *ctx, dtls_peer_t *peer, session_t *session,
-   case DTLS_HT_SERVER_KEY_EXCHANGE:
--#ifdef DTLS_ECC
-+#if defined(DTLS_ECC) || defined(DTLS_X509)
-     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);
-@@ -3811,13 +3976,13 @@ handle_handshake_msg(dtls_context_t *ctx, dtls_peer_t *peer, session_t *session,
-     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))
-+            (is_ecdsa_client_auth_supported(ctx) || (is_x509_client_auth_supported(ctx))))
-       peer->state = DTLS_STATE_WAIT_CERTIFICATEVERIFY; //ecdsa
-     else
-       peer->state = DTLS_STATE_WAIT_CHANGECIPHERSPEC; //psk || ecdh_anon
-     break;
--#ifdef DTLS_ECC
-+#if defined(DTLS_ECC) || defined(DTLS_X509)
-   case DTLS_HT_CERTIFICATE_VERIFY:
-     if (state != DTLS_STATE_WAIT_CERTIFICATEVERIFY) {
-@@ -3934,7 +4099,7 @@ handle_handshake_msg(dtls_context_t *ctx, dtls_peer_t *peer, session_t *session,
-       return err;
-     }
-     if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher) &&
--      is_ecdsa_client_auth_supported(ctx))
-+            (is_ecdsa_client_auth_supported(ctx) || (is_x509_client_auth_supported(ctx))))
-       peer->state = DTLS_STATE_WAIT_CLIENTCERTIFICATE; //ecdhe
-     else
-       peer->state = DTLS_STATE_WAIT_CLIENTKEYEXCHANGE; //psk, ecdh_anon
-@@ -4261,7 +4426,7 @@ 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;       
-+          role = DTLS_SERVER;
-         } else {
-         int err =  dtls_alert_fatal_create(DTLS_ALERT_DECRYPT_ERROR);
-           dtls_info("decrypt_verify() failed\n");
-@@ -4506,7 +4671,7 @@ dtls_connect_peer(dtls_context_t *ctx, dtls_peer_t *peer) {
-   res = dtls_send_client_hello(ctx, peer, NULL, 0);
-   if (res < 0)
-     dtls_warn("cannot send ClientHello\n");
--  else 
-+  else
-     peer->state = DTLS_STATE_CLIENTHELLO;
-   return res;
-diff --git a/extlibs/tinydtls/dtls.h b/extlibs/tinydtls/dtls.h
-index 7d2bc19..c5a86df 100644
---- a/extlibs/tinydtls/dtls.h
-+++ b/extlibs/tinydtls/dtls.h
-@@ -56,6 +56,10 @@
- #define DTLS_VERSION 0xfefd   /* DTLS v1.2 */
- #endif
-+#ifdef DTLS_X509
-+#define DTLS_MAX_CERT_SIZE       1400
-+#endif
-+
- typedef enum dtls_credentials_type_t {
-   DTLS_PSK_HINT, DTLS_PSK_IDENTITY, DTLS_PSK_KEY
- } dtls_credentials_type_t;
-@@ -181,10 +185,11 @@ typedef struct {
-    *                session.
-    * @return @c 0 if result is set, or less than zero on error.
-    */
--  int (*get_ecdsa_key)(struct dtls_context_t *ctx, 
-+  int (*get_ecdsa_key)(struct dtls_context_t *ctx,
-                      const session_t *session,
-                      const dtls_ecc_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
-@@ -211,12 +216,111 @@ typedef struct {
-    *   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, 
-+  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 */
-+#ifdef DTLS_X509
-+  /**
-+   * 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 X.509
-+   * 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_x509_key)(struct dtls_context_t *ctx,
-+               const session_t *session,
-+               const dtls_ecc_key_t **result);
-+  /**
-+   * Called during handshake to get the server's or client's
-+   * certificate used to authenticate this server or client in this
-+   * session. If found, the certificate must be stored in @p cert and
-+   * the return value must be @c 0. If not found, @p cert is
-+   * undefined and the return value must be less than zero.
-+   *
-+   * If X.509 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 X.509
-+   * 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 certificate will be used.
-+   * @param cert      Must be set to the certificate object to used for
-+   *                  the given session.
-+   * @param cert_size Size of certificate in bytes.
-+   * @return @c 0 if result is set, or less than zero on error.
-+   */
-+  int (*get_x509_cert)(struct dtls_context_t *ctx,
-+                      const session_t *session,
-+                      const unsigned char **cert,
-+                      size_t *cert_size);
-+
-+  /**
-+   * Called during handshake to check the peer's certificate in this
-+   * session. If the certificate matches the session and is valid the
-+   * return value must be @c 0. If not valid, the return value must be
-+   * less than zero.
-+   *
-+   * If X.509 should not be supported, set this pointer to NULL.
-+   *
-+   * Implement this if you want to verify the other peers certificate.
-+   * This is mandatory for a DTLS client doing based X.509
-+   * 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 cert      Peer's certificate to check.
-+   * @param cert_size Size of certificate in bytes.
-+   * @param x         Allocated memory to store peer's public key part x.
-+   * @param x_size    Size of allocated memory to store peer's public key part x.
-+   * @param y         Allocated memory to store peer's public key part y.
-+   * @param y_size    Size of allocated memory to store peer's public key part y.
-+   * @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_x509_cert)(struct dtls_context_t *ctx,
-+                         const session_t *session,
-+                         const unsigned char *cert,
-+                         size_t cert_size,
-+               unsigned char *x,
-+                         size_t x_size,
-+               unsigned char *y,
-+                         size_t y_size);
-+
-+  /**
-+   * Called during handshake to check if certificate format should be X.509
-+   *
-+   * If X.509 should not be supported, set this pointer to NULL.
-+   *
-+   * @param ctx       The current dtls context.
-+   * @return @c 0 if certificate format should be X.509, or less than zero on error.
-+   */
-+  int (*is_x509_active)(struct dtls_context_t *ctx);
-+#endif /* DTLS_X509 */
- } dtls_handler_t;
- /** Holds global information of the DTLS engine. */
-diff --git a/extlibs/tinydtls/dtls_config.h b/extlibs/tinydtls/dtls_config.h
-index 39df8c9..c6c4e39 100644
---- a/extlibs/tinydtls/dtls_config.h
-+++ b/extlibs/tinydtls/dtls_config.h
-@@ -66,9 +66,27 @@
- #endif
- #endif /* CONTIKI */
-+/* Define if building universal (internal helper macro) */
-+/* #undef AC_APPLE_UNIVERSAL_BUILD */
-+
-+/* Define to 1 if building with X.509 support */
-+#define DTLS_X509 1
-+
-+/* Define to 1 if you have the <arpa/inet.h> header file. */
-+#define HAVE_ARPA_INET_H 1
-+
- /* Define to 1 if you have the <assert.h> header file. */
- #define HAVE_ASSERT_H 1
-+/* Define to 1 if you have the <fcntl.h> header file. */
-+#define HAVE_FCNTL_H 1
-+
-+/* Define to 1 if you have the `fls' function. */
-+/* #undef HAVE_FLS */
-+
-+/* Define to 1 if you have the <inttypes.h> header file. */
-+#define HAVE_INTTYPES_H 1
-+
- /* Define to 1 if your system has a GNU libc compatible `malloc' function, and
-    to 0 otherwise. */
- #define HAVE_MALLOC 1
-@@ -79,6 +97,21 @@
- /* Define to 1 if you have the `memset' function. */
- #define HAVE_MEMSET 1
-+/* Define to 1 if you have the <netdb.h> header file. */
-+#define HAVE_NETDB_H 1
-+
-+/* Define to 1 if you have the <netinet/in.h> header file. */
-+#define HAVE_NETINET_IN_H 1
-+
-+/* Define to 1 if you have the `select' function. */
-+#define HAVE_SELECT 1
-+
-+/* 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. */
-+#define HAVE_SOCKET 1
-+
- /* Define to 1 if you have the <stddef.h> header file. */
- #define HAVE_STDDEF_H 1
-@@ -103,9 +136,27 @@
- /* Define to 1 if you have the `strnlen' function. */
- #define HAVE_STRNLEN 1
-+/* Define to 1 if you have the <sys/param.h> header file. */
-+#define HAVE_SYS_PARAM_H 1
-+
-+/* Define to 1 if you have the <sys/socket.h> header file. */
-+#define HAVE_SYS_SOCKET_H 1
-+
-+/* Define to 1 if you have the <sys/stat.h> header file. */
-+#define HAVE_SYS_STAT_H 1
-+
-+/* Define to 1 if you have the <sys/time.h> header file. */
-+#define HAVE_SYS_TIME_H 1
-+
-+/* Define to 1 if you have the <sys/types.h> header file. */
-+#define HAVE_SYS_TYPES_H 1
-+
- /* Define to 1 if you have the <time.h> header file. */
- #define HAVE_TIME_H 1
-+/* Define to 1 if you have the <unistd.h> header file. */
-+#define HAVE_UNISTD_H 1
-+
- /* Define to 1 if you have the `vprintf' function. */
- #define HAVE_VPRINTF 1
-diff --git a/extlibs/tinydtls/dtls_config.h.in b/extlibs/tinydtls/dtls_config.h.in
-index a29077c..adc8dc5 100644
---- a/extlibs/tinydtls/dtls_config.h.in
-+++ b/extlibs/tinydtls/dtls_config.h.in
-@@ -68,6 +68,9 @@
- /* Define if building universal (internal helper macro) */
- #undef AC_APPLE_UNIVERSAL_BUILD
-+/* Define to 1 if building with X.509 support */
-+#undef DTLS_X509
-+
- /* Define to 1 if you have the <arpa/inet.h> header file. */
- #undef HAVE_ARPA_INET_H
-diff --git a/extlibs/tinydtls/global.h b/extlibs/tinydtls/global.h
-index 8b3c518..048bacd 100644
---- a/extlibs/tinydtls/global.h
-+++ b/extlibs/tinydtls/global.h
-@@ -55,7 +55,7 @@ typedef unsigned char uint48[6];
-     When Peers are sending bigger messages this causes problems. Californium
-     with ECDSA needs at least 220 */
- #ifdef WITH_CONTIKI
--#ifdef DTLS_ECC
-+#if defined(DTLS_ECC) || defined(DTLS_X509)
- #define DTLS_MAX_BUF 200
- #else /* DTLS_ECC */
- #define DTLS_MAX_BUF 100
-@@ -96,7 +96,10 @@ typedef enum {
- #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 */
-+/* see http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#tls-extensiontype-values-3 */
-+#define TLS_CERT_TYPE_X509              0 /* see RFC 6091 */
-+#define TLS_CERT_TYPE_RAW_PUBLIC_KEY    2 /* see RFC 7250 */
-+
- #define TLS_EXT_ELLIPTIC_CURVES_SECP256R1     23 /* see RFC 4492 */
-diff --git a/extlibs/tinydtls/netq.h b/extlibs/tinydtls/netq.h
-index a771b23..fea7511 100644
---- a/extlibs/tinydtls/netq.h
-+++ b/extlibs/tinydtls/netq.h
-@@ -23,7 +23,7 @@
-  */
- #ifndef NETQ_MAXCNT
--#ifdef DTLS_ECC
-+#if defined(DTLS_ECC) || defined(DTLS_X509)
- #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 */
-diff --git a/extlibs/tinydtls/tests/Makefile.in b/extlibs/tinydtls/tests/Makefile.in
-index 3a50695..a2d8ca4 100644
---- a/extlibs/tinydtls/tests/Makefile.in
-+++ b/extlibs/tinydtls/tests/Makefile.in
-@@ -41,9 +41,9 @@ SOURCES:= dtls-server.c ccm-test.c prf-test.c \
- OBJECTS:= $(patsubst %.c, %.o, $(SOURCES))
- PROGRAMS:= $(patsubst %.c, %, $(SOURCES))
- HEADERS:=
--CFLAGS:=-Wall @CFLAGS@ 
-+CFLAGS:=-Wall @CFLAGS@
- CPPFLAGS:=-I$(top_srcdir) @CPPFLAGS@
--LDFLAGS:=-L$(top_builddir) 
-+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
-diff --git a/extlibs/tinydtls/tests/dtls-client.c b/extlibs/tinydtls/tests/dtls-client.c
-index dfd34c8..2c4eff9 100644
---- a/extlibs/tinydtls/tests/dtls-client.c
-+++ b/extlibs/tinydtls/tests/dtls-client.c
-@@ -16,9 +16,34 @@
- #include <netdb.h>
- #include <signal.h>
--#include "global.h" 
--#include "debug.h" 
--#include "dtls.h" 
-+#include "global.h"
-+#include "debug.h"
-+#include "dtls.h"
-+
-+/**
-+ * @struct byte_array
-+ *
-+ * General purpose byte array structure.
-+ *
-+ * Contains pointer to array of bytes and it's length.
-+ */
-+
-+typedef struct
-+{
-+    uint8_t *data;    /**< Pointer to the byte array */
-+    size_t len;      /**< Data size */
-+} byte_array;
-+
-+
-+/**@def BYTE_ARRAY_INITIALIZER
-+ *
-+ * Initializes of existing byte array pointer to \a NULL.
-+ */
-+#undef BYTE_ARRAY_INITIALIZER
-+#define BYTE_ARRAY_INITIALIZER {NULL, 0}
-+
-+#define DTLS_PRIVATE_KEY_SIZE        (32)
-+#define DTLS_PUBLIC_KEY_SIZE         (64)
- #define DEFAULT_PORT 20220
-@@ -26,6 +51,7 @@
- #define PSK_SERVER_IDENTITY  "Server_identity"
- #define PSK_DEFAULT_KEY      "secretPSK"
- #define PSK_OPTIONS          "i:s:k:"
-+#define X509_OPTIONS         "x:r:u:"
- #ifdef __GNUC__
- #define UNUSED_PARAM __attribute__((unused))
-@@ -46,7 +72,105 @@ 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;
-+#ifdef DTLS_X509
-+#define CLIENT_CRT_LEN 293
-+static const unsigned char g_client_certificate[CLIENT_CRT_LEN] = {
-+        0x00, 0x01, 0x22,
-+        0x30, 0x82, 0x01, 0x1e, 0x30, 0x81, 0xc4, 0xa0,
-+        0x03, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x38,
-+        0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
-+        0x3d, 0x04, 0x03, 0x02, 0x05, 0x00, 0x30, 0x17,
-+        0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04,
-+        0x03, 0x0c, 0x0c, 0x4c, 0x6f, 0x63, 0x61, 0x6c,
-+        0x20, 0x49, 0x53, 0x53, 0x55, 0x45, 0x52, 0x30,
-+        0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x31, 0x30,
-+        0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
-+        0x17, 0x0d, 0x34, 0x39, 0x30, 0x31, 0x30, 0x31,
-+        0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30,
-+        0x17, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55,
-+        0x04, 0x03, 0x0c, 0x0c, 0x4c, 0x6f, 0x63, 0x61,
-+        0x6c, 0x20, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54,
-+        0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
-+        0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a,
-+        0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
-+        0x42, 0x00, 0x04, 0xe3, 0xd1, 0x67, 0x1e, 0xdc,
-+        0x46, 0xf4, 0x19, 0x50, 0x15, 0x2e, 0x3a, 0x2f,
-+        0xd8, 0x68, 0x6b, 0x37, 0x32, 0x84, 0x9e, 0x83,
-+        0x81, 0xbf, 0x25, 0x5d, 0xbb, 0x18, 0x07, 0x3c,
-+        0xbd, 0xf3, 0xab, 0xd3, 0xbf, 0x53, 0x59, 0xc9,
-+        0x1e, 0xce, 0x5b, 0x39, 0x6a, 0xe5, 0x60, 0xf3,
-+        0x70, 0xdb, 0x66, 0xb6, 0x80, 0xcb, 0x65, 0x0b,
-+        0x35, 0x2a, 0x62, 0x44, 0x89, 0x63, 0x64, 0x6f,
-+        0x6f, 0xbd, 0xf0, 0x30, 0x0c, 0x06, 0x08, 0x2a,
-+        0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x05,
-+        0x00, 0x03, 0x47, 0x00, 0x30, 0x44, 0x02, 0x20,
-+        0x60, 0xdc, 0x45, 0x77, 0x7d, 0xcb, 0xc3, 0xb4,
-+        0xba, 0x60, 0x5a, 0x2e, 0xe5, 0x4e, 0x19, 0x8b,
-+        0x48, 0x8a, 0x87, 0xd4, 0x66, 0xb4, 0x1a, 0x86,
-+        0x23, 0x67, 0xb8, 0xb6, 0x50, 0xfe, 0x4d, 0xde,
-+        0x02, 0x20, 0x60, 0x68, 0x46, 0xff, 0x74, 0x11,
-+        0xfb, 0x36, 0x13, 0xf4, 0xa7, 0x3d, 0xb7, 0x35,
-+        0x79, 0x23, 0x29, 0x14, 0x6a, 0x28, 0x09, 0xff,
-+        0x8c, 0x19, 0x26, 0xe3, 0x41, 0xc8, 0xe4, 0x13,
-+        0xbc, 0x8e};
-+//default client's key pair
-+static const unsigned char x509_priv_key[] = {
-+        0xf9, 0x42, 0xb4, 0x16, 0x89, 0x10, 0xf4, 0x07,
-+        0x99, 0xb2, 0xe2, 0x9a, 0xed, 0xd4, 0x39, 0xb8,
-+        0xca, 0xd4, 0x9d, 0x76, 0x11, 0x43, 0x3a, 0xac,
-+        0x14, 0xba, 0x17, 0x9d, 0x3e, 0xbb, 0xbf, 0xbc};
-+
-+static const unsigned char x509_pub_key_x[] = {
-+        0xe3, 0xd1, 0x67, 0x1e, 0xdc, 0x46, 0xf4, 0x19,
-+        0x50, 0x15, 0x2e, 0x3a, 0x2f, 0xd8, 0x68, 0x6b,
-+        0x37, 0x32, 0x84, 0x9e, 0x83, 0x81, 0xbf, 0x25,
-+        0x5d, 0xbb, 0x18, 0x07, 0x3c, 0xbd, 0xf3, 0xab};
-+
-+static const unsigned char x509_pub_key_y[] = {
-+        0xd3, 0xbf, 0x53, 0x59, 0xc9, 0x1e, 0xce, 0x5b,
-+        0x39, 0x6a, 0xe5, 0x60, 0xf3, 0x70, 0xdb, 0x66,
-+        0xb6, 0x80, 0xcb, 0x65, 0x0b, 0x35, 0x2a, 0x62,
-+        0x44, 0x89, 0x63, 0x64, 0x6f, 0x6f, 0xbd, 0xf0};
-+
-+//default CA pub key
-+static const unsigned char x509_ca_pub_x[] = {
-+        0x57, 0x94, 0x7f, 0x98, 0x7a, 0x02, 0x67, 0x09,
-+        0x25, 0xc1, 0xcb, 0x5a, 0xf5, 0x46, 0xfb, 0xad,
-+        0xf7, 0x68, 0x94, 0x8c, 0xa7, 0xe3, 0xf0, 0x5b,
-+        0xc3, 0x6b, 0x5c, 0x9b, 0xd3, 0x7d, 0x74, 0x12
-+};
-+static const unsigned char x509_ca_pub_y[] = {
-+        0xce, 0x68, 0xbc, 0x55, 0xf5, 0xf8, 0x1b, 0x3d,
-+        0xef, 0xed, 0x1f, 0x2b, 0xd2, 0x69, 0x5d, 0xcf,
-+        0x79, 0x16, 0xa6, 0xbd, 0x97, 0x96, 0x27, 0x60,
-+        0x5d, 0xd1, 0xb7, 0x93, 0xa2, 0x4a, 0x62, 0x4d
-+};
-+
-+//default server's key pair
-+static const unsigned char serv_pub_key_x[] = {
-+        0x07, 0x88, 0x10, 0xdc, 0x62, 0xd7, 0xe6, 0x9b,
-+        0x7c, 0xad, 0x6e, 0x78, 0xb0, 0x5f, 0x9a, 0x00,
-+        0x11, 0x74, 0x2c, 0x8b, 0xaf, 0x09, 0x65, 0x7c,
-+        0x86, 0x8e, 0x55, 0xcb, 0x39, 0x55, 0x72, 0xc6};
-+
-+static const unsigned char serv_pub_key_y[] = {
-+        0x65, 0x71, 0xcd, 0x03, 0xdc, 0x2a, 0x4f, 0x46,
-+        0x5b, 0x14, 0xc8, 0x27, 0x74, 0xab, 0xf4, 0x1f,
-+        0xc1, 0x35, 0x0d, 0x42, 0xbc, 0xc2, 0x9f, 0xb5,
-+        0xc1, 0x79, 0xb6, 0x8b, 0xca, 0xdb, 0xff, 0x82};
-+
-+
-+static unsigned char x509_client_cert[DTLS_MAX_CERT_SIZE];
-+static size_t x509_client_cert_len = 0;
-+static unsigned char x509_client_priv[DTLS_PRIVATE_KEY_SIZE+1];
-+static size_t x509_client_priv_is_set = 0;
-+static unsigned char x509_ca_pub[DTLS_PUBLIC_KEY_SIZE+1];
-+static size_t x509_ca_pub_is_set = 0;
-+
-+static int x509_info_from_file = 0;
-+#endif /*DTLS_X509*/
-+#ifdef DTLS_ECC
- static const unsigned char ecdsa_priv_key[] = {
-                       0x41, 0xC1, 0xCB, 0x6B, 0x51, 0x24, 0x7A, 0x14,
-                       0x43, 0x21, 0x43, 0x5B, 0x7A, 0x80, 0xE7, 0x14,
-@@ -65,7 +189,8 @@ static const unsigned char ecdsa_pub_key_y[] = {
-                       0xE9, 0x3F, 0x98, 0x72, 0x09, 0xDA, 0xED, 0x0B,
-                       0x4F, 0xAB, 0xC3, 0x6F, 0xC7, 0x72, 0xF8, 0x29};
--#ifdef DTLS_PSK
-+#endif /*DTLS_ECC*/
-+#if defined(DTLS_PSK) || defined(DTLS_X509)
- ssize_t
- read_from_file(char *arg, unsigned char *buf, size_t max_buf_len) {
-   FILE *f;
-@@ -87,11 +212,11 @@ read_from_file(char *arg, unsigned char *buf, size_t max_buf_len) {
-     result += bytes_read;
-     max_buf_len -= bytes_read;
-   }
--
-   fclose(f);
-   return result;
- }
--
-+#endif /*DTLS_PSK||DTLS_X509*/
-+#ifdef DTLS_PSK
- /* The PSK information for DTLS */
- #define PSK_ID_MAXLEN 256
- #define PSK_MAXLEN 256
-@@ -149,13 +274,14 @@ static int
- get_ecdsa_key(struct dtls_context_t *ctx,
-             const session_t *session,
-             const dtls_ecc_key_t **result) {
-+    (void)ctx;
-+    (void)session;
-   static const dtls_ecc_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;
- }
-@@ -166,10 +292,115 @@ verify_ecdsa_key(struct dtls_context_t *ctx,
-                const unsigned char *other_pub_x,
-                const unsigned char *other_pub_y,
-                size_t key_size) {
-+  (void)ctx;
-+  (void)session;
-+  (void)other_pub_x;
-+  (void)other_pub_y;
-+  (void)key_size;
-   return 0;
- }
-+
- #endif /* DTLS_ECC */
-+#ifdef DTLS_X509
-+static int
-+get_x509_key(struct dtls_context_t *ctx,
-+          const session_t *session,
-+          const dtls_ecc_key_t **result) {
-+    (void)ctx;
-+    (void)session;
-+  static dtls_ecc_key_t ecdsa_key = {
-+    .curve = DTLS_ECDH_CURVE_SECP256R1,
-+    .priv_key = x509_priv_key,
-+    .pub_key_x = x509_pub_key_x,
-+    .pub_key_y = x509_pub_key_y
-+  };
-+  if (x509_info_from_file)
-+      ecdsa_key.priv_key = x509_client_priv;
-+  *result = &ecdsa_key;
-+  return 0;
-+}
-+
-+static int
-+get_x509_cert(struct dtls_context_t *ctx,
-+        const session_t *session,
-+        const unsigned char **cert,
-+        size_t *cert_size)
-+{
-+    (void)ctx;
-+    (void)session;
-+    if (x509_info_from_file)
-+    {
-+        *cert = x509_client_cert;
-+        *cert_size = x509_client_cert_len;
-+    }
-+    else
-+    {
-+        *cert = g_client_certificate;
-+        *cert_size = CLIENT_CRT_LEN;
-+    }
-+
-+    return 0;
-+}
-+
-+int check_certificate(byte_array cert_der_code, byte_array ca_public_key)
-+{
-+    (void)cert_der_code;
-+    (void)ca_public_key;
-+    return 0;
-+}
-+
-+static int verify_x509_cert(struct dtls_context_t *ctx, const session_t *session,
-+                                  const unsigned char *cert, size_t cert_size,
-+                                  unsigned char *x,
-+                                  size_t x_size,
-+                                  unsigned char *y,
-+                                  size_t y_size)
-+{
-+    int ret;
-+    const unsigned char *ca_pub_x;
-+    const unsigned char *ca_pub_y;
-+    byte_array cert_der_code = BYTE_ARRAY_INITIALIZER;
-+    byte_array ca_public_key = BYTE_ARRAY_INITIALIZER;
-+    unsigned char ca_pub_key[DTLS_PUBLIC_KEY_SIZE];
-+    (void)ctx;
-+    (void)session;
-+
-+    if (x509_info_from_file)
-+    {
-+        ca_pub_x = x509_ca_pub;
-+        ca_pub_y = x509_ca_pub + DTLS_PUBLIC_KEY_SIZE/2;
-+    }
-+    else
-+    {
-+        ca_pub_x = x509_ca_pub_x;
-+        ca_pub_y = x509_ca_pub_y;
-+    }
-+
-+    cert_der_code.data = (uint8_t *)cert;
-+    cert_der_code.len = cert_size;
-+
-+    ca_public_key.len = DTLS_PUBLIC_KEY_SIZE;
-+    ca_public_key.data = ca_pub_key;
-+    memcpy(ca_public_key.data, ca_pub_x, DTLS_PUBLIC_KEY_SIZE/2);
-+    memcpy(ca_public_key.data + DTLS_PUBLIC_KEY_SIZE/2, ca_pub_y, DTLS_PUBLIC_KEY_SIZE/2);
-+
-+    memcpy(x, serv_pub_key_x, x_size);
-+    memcpy(y, serv_pub_key_y, y_size);
-+
-+    ret = (int) check_certificate(cert_der_code, ca_public_key);
-+
-+    return -ret;
-+}
-+
-+static int is_x509_active(struct dtls_context_t *ctx)
-+{
-+    (void)ctx;
-+    return 0;
-+}
-+
-+#endif /* DTLS_X509 */
-+
- static void
- try_send(struct dtls_context_t *ctx, session_t *dst) {
-   int res;
-@@ -190,6 +421,8 @@ static int
- read_from_peer(struct dtls_context_t *ctx, 
-              session_t *session, uint8 *data, size_t len) {
-   size_t i;
-+  (void)ctx;
-+  (void)session;
-   for (i = 0; i < len; i++)
-     printf("%c", data[i]);
-   return 0;
-@@ -295,16 +528,24 @@ usage( const char *program, const char *version) {
-   fprintf(stderr, "%s v%s -- DTLS client implementation\n"
-         "(c) 2011-2014 Olaf Bergmann <bergmann@tzi.org>\n\n"
-+        "usage: %s"
- #ifdef DTLS_PSK
--        "usage: %s [-i file] [-s file] [-k file] [-o file] [-p port] [-v num] [-c num] addr [port]\n"
--#else /*  DTLS_PSK */
--        "usage: %s [-o file] [-p port] [-v num] [-c num] addr [port]\n"
-+          " [-i file] [-s file] [-k file]"
- #endif /* DTLS_PSK */
-+#ifdef DTLS_X509
-+          " [-x file] [-r file] [-u file]"
-+#endif /* DTLS_X509 */
-+          " [-o file] [-p port] [-v num] [-c num] addr [port]\n"
- #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 */
-+#ifdef DTLS_X509
-+          "\t-x file\tread Client certificate from file\n"
-+          "\t-r file\tread Client private key from file\n"
-+          "\t-u file\tread CA public key from file\n"
-+#endif /* DTLS_X509 */
-         "\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"
-@@ -325,8 +566,15 @@ static dtls_handler_t cb = {
- #endif /* DTLS_PSK */
- #ifdef DTLS_ECC
-   .get_ecdsa_key = get_ecdsa_key,
--  .verify_ecdsa_key = verify_ecdsa_key
-+  .verify_ecdsa_key = verify_ecdsa_key,
- #endif /* DTLS_ECC */
-+#ifdef DTLS_X509
-+  .get_x509_key = get_x509_key,
-+  .verify_x509_cert = verify_x509_cert,
-+  .get_x509_cert = get_x509_cert,
-+  .is_x509_active = is_x509_active,
-+#endif /* DTLS_X509 */
-+
- };
- #define DTLS_CLIENT_CMD_CLOSE "client:close"
-@@ -365,7 +613,7 @@ main(int argc, char **argv) {
-   memcpy(psk_key, PSK_DEFAULT_KEY, psk_key_length);
- #endif /* DTLS_PSK */
--  while ((opt = getopt(argc, argv, "p:o:v:c:" PSK_OPTIONS)) != -1) {
-+  while ((opt = getopt(argc, argv, "p:o:v:c:" PSK_OPTIONS X509_OPTIONS)) != -1) {
-     switch (opt) {
- #ifdef DTLS_PSK
-     case 'i' : {
-@@ -396,6 +644,47 @@ main(int argc, char **argv) {
-       break;
-     }
- #endif /* DTLS_PSK */
-+#ifdef DTLS_X509
-+    case 'x' :
-+    {
-+      ssize_t result = read_from_file(optarg, x509_client_cert, DTLS_MAX_CERT_SIZE);
-+      if (result < 0)
-+      {
-+          dtls_warn("Cannot read Client certificate. Using default\n");
-+      }
-+      else
-+      {
-+          x509_client_cert_len = result;
-+      }
-+      break;
-+    }
-+    case 'r' :
-+    {
-+      ssize_t result = read_from_file(optarg, x509_client_priv, DTLS_PRIVATE_KEY_SIZE+1);
-+      if (result < 0)
-+      {
-+          dtls_warn("Cannot read Client private key. Using default\n");
-+      }
-+      else
-+      {
-+          x509_client_priv_is_set = result;
-+      }
-+      break;
-+    }
-+    case 'u' :
-+    {
-+      ssize_t result = read_from_file(optarg, x509_ca_pub, DTLS_PUBLIC_KEY_SIZE+1);
-+      if (result < 0)
-+      {
-+          dtls_warn("Cannot read CA public key. Using default\n");
-+      }
-+      else
-+      {
-+          x509_ca_pub_is_set = result;
-+      }
-+      break;
-+    }
-+#endif /* DTLS_X509 */
-     case 'p' :
-       strncpy(port_str, optarg, NI_MAXSERV-1);
-       port_str[NI_MAXSERV - 1] = '\0';
-@@ -403,7 +692,7 @@ main(int argc, char **argv) {
-     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);
-@@ -444,12 +733,29 @@ main(int argc, char **argv) {
-   }
-   dtls_set_log_level(log_level);
--  
-+
-   if (argc <= optind) {
-     usage(argv[0], dtls_package_version());
-     exit(1);
-   }
--  
-+
-+#ifdef DTLS_X509
-+  if (x509_client_cert_len && x509_client_priv_is_set && x509_ca_pub_is_set)
-+  {
-+      x509_info_from_file = 1;
-+  }
-+  else if(!(x509_client_cert_len || x509_client_priv_is_set || x509_ca_pub_is_set))
-+  {
-+      x509_info_from_file = 0;
-+  }
-+  else
-+  {
-+      fprintf(stderr,"please set -x, -r, -u options simultaneously");
-+      usage(argv[0], dtls_package_version());
-+      exit(1);
-+  }
-+#endif /* DTLS_X509 */
-+
-   memset(&dst, 0, sizeof(session_t));
-   /* resolve destination address where server should be sent */
-   res = resolve_address(argv[optind++], &dst.addr.sa);
-diff --git a/extlibs/tinydtls/tests/dtls-server.c b/extlibs/tinydtls/tests/dtls-server.c
-index 5893084..a3ede4d 100644
---- a/extlibs/tinydtls/tests/dtls-server.c
-+++ b/extlibs/tinydtls/tests/dtls-server.c
-@@ -14,12 +14,138 @@
- #include <netdb.h>
- #include <signal.h>
--#include "tinydtls.h" 
--#include "dtls.h" 
--#include "debug.h" 
-+#include "tinydtls.h"
-+#include "dtls.h"
-+#include "debug.h"
-+
-+#ifdef DTLS_X509
-+#define DTLS_PRIVATE_KEY_SIZE        (32)
-+#define DTLS_PUBLIC_KEY_SIZE         (64)
-+#endif
- #define DEFAULT_PORT 20220
-+/**
-+ * @struct byte_array
-+ *
-+ * General purpose byte array structure.
-+ *
-+ * Contains pointer to array of bytes and it's length.
-+ */
-+
-+typedef struct
-+{
-+    uint8_t *data;    /**< Pointer to the byte array */
-+    size_t len;      /**< Data size */
-+} byte_array;
-+
-+
-+/**@def BYTE_ARRAY_INITIALIZER
-+ *
-+ * Initializes of existing byte array pointer to \a NULL.
-+ */
-+#undef BYTE_ARRAY_INITIALIZER
-+#define BYTE_ARRAY_INITIALIZER {NULL, 0}
-+
-+#ifdef DTLS_X509
-+#define X509_OPTIONS         "x:r:u:"
-+#define SERVER_CRT_LEN 295
-+static const unsigned char g_server_certificate[SERVER_CRT_LEN] = {
-+        0x00, 0x01, 0x24,
-+        0x30, 0x82, 0x01, 0x20, 0x30, 0x81, 0xc4, 0xa0,
-+        0x03, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x37,
-+        0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
-+        0x3d, 0x04, 0x03, 0x02, 0x05, 0x00, 0x30, 0x17,
-+        0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04,
-+        0x03, 0x0c, 0x0c, 0x4c, 0x6f, 0x63, 0x61, 0x6c,
-+        0x20, 0x49, 0x53, 0x53, 0x55, 0x45, 0x52, 0x30,
-+        0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x31, 0x30,
-+        0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
-+        0x17, 0x0d, 0x34, 0x39, 0x30, 0x31, 0x30, 0x31,
-+        0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30,
-+        0x17, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55,
-+        0x04, 0x03, 0x0c, 0x0c, 0x4c, 0x6f, 0x63, 0x61,
-+        0x6c, 0x20, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52,
-+        0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
-+        0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a,
-+        0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
-+        0x42, 0x00, 0x04, 0x07, 0x88, 0x10, 0xdc, 0x62,
-+        0xd7, 0xe6, 0x9b, 0x7c, 0xad, 0x6e, 0x78, 0xb0,
-+        0x5f, 0x9a, 0x00, 0x11, 0x74, 0x2c, 0x8b, 0xaf,
-+        0x09, 0x65, 0x7c, 0x86, 0x8e, 0x55, 0xcb, 0x39,
-+        0x55, 0x72, 0xc6, 0x65, 0x71, 0xcd, 0x03, 0xdc,
-+        0x2a, 0x4f, 0x46, 0x5b, 0x14, 0xc8, 0x27, 0x74,
-+        0xab, 0xf4, 0x1f, 0xc1, 0x35, 0x0d, 0x42, 0xbc,
-+        0xc2, 0x9f, 0xb5, 0xc1, 0x79, 0xb6, 0x8b, 0xca,
-+        0xdb, 0xff, 0x82, 0x30, 0x0c, 0x06, 0x08, 0x2a,
-+        0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x05,
-+        0x00, 0x03, 0x49, 0x00, 0x30, 0x46, 0x02, 0x21,
-+        0x00, 0xb1, 0x81, 0x81, 0x92, 0x0e, 0x76, 0x7c,
-+        0xeb, 0xf5, 0x37, 0xde, 0x27, 0xc4, 0x01, 0xc8,
-+        0x96, 0xc3, 0xe5, 0x9f, 0x47, 0x7e, 0x25, 0x92,
-+        0xa4, 0xba, 0x22, 0x25, 0xa3, 0x81, 0x19, 0xcf,
-+        0x0d, 0x02, 0x21, 0x00, 0xca, 0x92, 0xbe, 0x79,
-+        0xc7, 0x82, 0x84, 0x64, 0xc4, 0xc4, 0xf4, 0x3d,
-+        0x69, 0x79, 0x68, 0xc0, 0xf1, 0xba, 0xaf, 0x6c,
-+        0xbb, 0xdd, 0x54, 0x7d, 0x07, 0xe7, 0x53, 0x3b,
-+        0xc3, 0x1b, 0x87, 0x04};
-+
-+//default server's key pair
-+static const unsigned char x509_priv_key[] = {
-+        0xaa, 0xa3, 0x46, 0xf1, 0x3c, 0x56, 0x5d, 0x08,
-+        0x5e, 0x59, 0xba, 0x7f, 0xd2, 0x21, 0x62, 0xc6,
-+        0xcc, 0x5d, 0xfa, 0x3f, 0xb5, 0x25, 0xa9, 0x89,
-+        0x4f, 0x32, 0xe8, 0x2a, 0xe0, 0xee, 0x9b, 0x4c};
-+
-+static const unsigned char x509_pub_key_x[] = {
-+        0x07, 0x88, 0x10, 0xdc, 0x62, 0xd7, 0xe6, 0x9b,
-+        0x7c, 0xad, 0x6e, 0x78, 0xb0, 0x5f, 0x9a, 0x00,
-+        0x11, 0x74, 0x2c, 0x8b, 0xaf, 0x09, 0x65, 0x7c,
-+        0x86, 0x8e, 0x55, 0xcb, 0x39, 0x55, 0x72, 0xc6};
-+
-+static const unsigned char x509_pub_key_y[] = {
-+        0x65, 0x71, 0xcd, 0x03, 0xdc, 0x2a, 0x4f, 0x46,
-+        0x5b, 0x14, 0xc8, 0x27, 0x74, 0xab, 0xf4, 0x1f,
-+        0xc1, 0x35, 0x0d, 0x42, 0xbc, 0xc2, 0x9f, 0xb5,
-+        0xc1, 0x79, 0xb6, 0x8b, 0xca, 0xdb, 0xff, 0x82};
-+
-+//default CA pub key
-+static const unsigned char x509_ca_pub_x[] = {
-+        0x57, 0x94, 0x7f, 0x98, 0x7a, 0x02, 0x67, 0x09,
-+        0x25, 0xc1, 0xcb, 0x5a, 0xf5, 0x46, 0xfb, 0xad,
-+        0xf7, 0x68, 0x94, 0x8c, 0xa7, 0xe3, 0xf0, 0x5b,
-+        0xc3, 0x6b, 0x5c, 0x9b, 0xd3, 0x7d, 0x74, 0x12
-+};
-+
-+static const unsigned char x509_ca_pub_y[] = {
-+        0xce, 0x68, 0xbc, 0x55, 0xf5, 0xf8, 0x1b, 0x3d,
-+        0xef, 0xed, 0x1f, 0x2b, 0xd2, 0x69, 0x5d, 0xcf,
-+        0x79, 0x16, 0xa6, 0xbd, 0x97, 0x96, 0x27, 0x60,
-+        0x5d, 0xd1, 0xb7, 0x93, 0xa2, 0x4a, 0x62, 0x4d
-+};
-+
-+static const unsigned char client_pub_key_x[] = {
-+        0xe3, 0xd1, 0x67, 0x1e, 0xdc, 0x46, 0xf4, 0x19,
-+        0x50, 0x15, 0x2e, 0x3a, 0x2f, 0xd8, 0x68, 0x6b,
-+        0x37, 0x32, 0x84, 0x9e, 0x83, 0x81, 0xbf, 0x25,
-+        0x5d, 0xbb, 0x18, 0x07, 0x3c, 0xbd, 0xf3, 0xab};
-+
-+static const unsigned char client_pub_key_y[] = {
-+        0xd3, 0xbf, 0x53, 0x59, 0xc9, 0x1e, 0xce, 0x5b,
-+        0x39, 0x6a, 0xe5, 0x60, 0xf3, 0x70, 0xdb, 0x66,
-+        0xb6, 0x80, 0xcb, 0x65, 0x0b, 0x35, 0x2a, 0x62,
-+        0x44, 0x89, 0x63, 0x64, 0x6f, 0x6f, 0xbd, 0xf0};
-+
-+static unsigned char x509_server_cert[DTLS_MAX_CERT_SIZE];
-+static size_t x509_server_cert_len = 0;
-+static unsigned char x509_server_priv[DTLS_PRIVATE_KEY_SIZE+1];
-+static size_t x509_server_priv_is_set = 0;
-+static unsigned char x509_ca_pub[DTLS_PUBLIC_KEY_SIZE+1];
-+static size_t x509_ca_pub_is_set = 0;
-+
-+static int x509_info_from_file = 0;
-+#endif /*DTLS_X509*/
-+#ifdef DTLS_ECC
- static const unsigned char ecdsa_priv_key[] = {
-                       0xD9, 0xE2, 0x70, 0x7A, 0x72, 0xDA, 0x6A, 0x05,
-                       0x04, 0x99, 0x5C, 0x86, 0xED, 0xDB, 0xE3, 0xEF,
-@@ -37,7 +163,7 @@ static const unsigned char ecdsa_pub_key_y[] = {
-                       0x1D, 0xDC, 0xF4, 0xF4, 0x2E, 0x2F, 0x26, 0x31,
-                       0xD0, 0x43, 0xB1, 0xFB, 0x03, 0xE2, 0x2F, 0x4D,
-                       0x17, 0xDE, 0x43, 0xF9, 0xF9, 0xAD, 0xEE, 0x70};
--
-+#endif /*DTLS_ECC*/
- #if 0
- /* SIGINT handler: set quit to 1 for graceful termination */
- void
-@@ -46,6 +172,34 @@ handle_sigint(int signum) {
- }
- #endif
-+#ifdef DTLS_X509
-+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;
-+}
-+#endif /*DTLS_X509*/
-+
- #ifdef DTLS_PSK
- #define PSK_SERVER_HINT  "Server_identity"
-@@ -59,6 +213,8 @@ get_psk_info(struct dtls_context_t *ctx, const session_t *session,
-            const unsigned char *id, size_t id_len,
-            unsigned char *result, size_t result_length) {
-+  (void)ctx;
-+  (void)session;
-   struct keymap_t {
-     unsigned char *id;
-     size_t id_length;
-@@ -86,7 +242,7 @@ get_psk_info(struct dtls_context_t *ctx, const session_t *session,
-   case DTLS_PSK_KEY:
-     if (id) {
-       int i;
--      for (i = 0; i < sizeof(psk)/sizeof(struct keymap_t); i++) {
-+      for (i = 0; i < (int)(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");
-@@ -114,6 +270,8 @@ static int
- get_ecdsa_key(struct dtls_context_t *ctx,
-             const session_t *session,
-             const dtls_ecc_key_t **result) {
-+    (void)ctx;
-+    (void)session;
-   static const dtls_ecc_key_t ecdsa_key = {
-     .curve = DTLS_ECDH_CURVE_SECP256R1,
-     .priv_key = ecdsa_priv_key,
-@@ -131,15 +289,120 @@ verify_ecdsa_key(struct dtls_context_t *ctx,
-                const unsigned char *other_pub_x,
-                const unsigned char *other_pub_y,
-                size_t key_size) {
-+  (void)ctx;
-+  (void)session;
-+  (void)other_pub_x;
-+  (void)other_pub_y;
-+  (void)key_size;
-   return 0;
- }
- #endif /* DTLS_ECC */
-+#ifdef DTLS_X509
-+static int
-+get_x509_key(struct dtls_context_t *ctx,
-+          const session_t *session,
-+          const dtls_ecc_key_t **result) {
-+    (void)ctx;
-+    (void)session;
-+  static dtls_ecc_key_t ecdsa_key = {
-+    .curve = DTLS_ECDH_CURVE_SECP256R1,
-+    .priv_key = x509_priv_key,
-+    .pub_key_x = x509_pub_key_x,
-+    .pub_key_y = x509_pub_key_y
-+  };
-+  if (x509_info_from_file)
-+      ecdsa_key.priv_key = x509_server_priv;
-+
-+  *result = &ecdsa_key;
-+  return 0;
-+}
-+
-+static int
-+get_x509_cert(struct dtls_context_t *ctx,
-+              const session_t *session,
-+              const unsigned char **cert,
-+              size_t *cert_size)
-+{
-+    (void)ctx;
-+    (void)session;
-+    if (x509_info_from_file)
-+    {
-+        *cert = x509_server_cert;
-+        *cert_size = x509_server_cert_len;
-+    }
-+    else
-+    {
-+        *cert = g_server_certificate;
-+        *cert_size = SERVER_CRT_LEN;
-+    }
-+
-+    return 0;
-+}
-+
-+static int check_certificate(byte_array cert_der_code, byte_array ca_public_key)
-+{
-+    (void)cert_der_code;
-+    (void)ca_public_key;
-+    return 0;
-+}
-+
-+static int verify_x509_cert(struct dtls_context_t *ctx, const session_t *session,
-+                                  const unsigned char *cert, size_t cert_size,
-+                                  unsigned char *x,
-+                                  size_t x_size,
-+                                  unsigned char *y,
-+                                  size_t y_size)
-+{
-+    int ret;
-+    const unsigned char *ca_pub_x;
-+    const unsigned char *ca_pub_y;
-+    byte_array cert_der_code = BYTE_ARRAY_INITIALIZER;
-+    byte_array ca_public_key = BYTE_ARRAY_INITIALIZER;
-+    unsigned char ca_pub_key[DTLS_PUBLIC_KEY_SIZE];
-+    (void)ctx;
-+    (void)session;
-+
-+    if (x509_info_from_file)
-+    {
-+        ca_pub_x = x509_ca_pub;
-+        ca_pub_y = x509_ca_pub + DTLS_PUBLIC_KEY_SIZE/2;
-+    }
-+    else
-+    {
-+        ca_pub_x = x509_ca_pub_x;
-+        ca_pub_y = x509_ca_pub_y;
-+    }
-+
-+    cert_der_code.data = (uint8_t *)cert;
-+    cert_der_code.len = cert_size;
-+
-+    ca_public_key.len = DTLS_PUBLIC_KEY_SIZE;
-+    ca_public_key.data = ca_pub_key;
-+    memcpy(ca_public_key.data, ca_pub_x, DTLS_PUBLIC_KEY_SIZE/2);
-+    memcpy(ca_public_key.data + DTLS_PUBLIC_KEY_SIZE/2, ca_pub_y, DTLS_PUBLIC_KEY_SIZE/2);
-+
-+    memcpy(x, client_pub_key_x, x_size);
-+    memcpy(y, client_pub_key_y, y_size);
-+
-+    ret = (int) check_certificate(cert_der_code, ca_public_key);
-+
-+  return -ret;
-+}
-+
-+static int is_x509_active(struct dtls_context_t *ctx)
-+{
-+    (void)ctx;
-+    return 0;
-+}
-+#endif /* DTLS_X509 */
-+
-+
- #define DTLS_SERVER_CMD_CLOSE "server:close"
- #define DTLS_SERVER_CMD_RENEGOTIATE "server:renegotiate"
- static int
--read_from_peer(struct dtls_context_t *ctx, 
-+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++)
-@@ -190,7 +453,7 @@ dtls_handle_read(struct dtls_context_t *ctx) {
-   } else {
-     dtls_debug("got %d bytes from port %d\n", len, 
-            ntohs(session.addr.sin6.sin6_port));
--    if (sizeof(buf) < len) {
-+    if ((int)(sizeof(buf)) < len) {
-       dtls_warn("packet was truncated (%d bytes lost)\n", len - sizeof(buf));
-     }
-   }
-@@ -250,13 +513,21 @@ usage(const char *program, const char *version) {
-   fprintf(stderr, "%s v%s -- DTLS server implementation\n"
-         "(c) 2011-2014 Olaf Bergmann <bergmann@tzi.org>\n\n"
-         "usage: %s [-A address] [-p port] [-v num] [-a enable|disable]\n"
-+#ifdef DTLS_X509
-+      " [-x file] [-r file] [-u file]"
-+#endif /* DTLS_X509 */
-         "\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"
-         "\t-a enable|disable\t(default: disable)\n"
-         "\t\t\t\tenable:enable TLS_ECDH_anon_with_AES_128_CBC_SHA_256\n"
--        "\t\t\t\tdisable:disable TLS_ECDH_anon_with_AES_128_CBC_SHA_256\n",
--         program, version, program, DEFAULT_PORT);
-+        "\t\t\t\tdisable:disable TLS_ECDH_anon_with_AES_128_CBC_SHA_256\n"
-+#ifdef DTLS_X509
-+      "\t-x file\tread Server certificate from file\n"
-+      "\t-r file\tread Server private key from file\n"
-+      "\t-u file\tread CA public key from file\n"
-+#endif /* DTLS_X509 */
-+      ,program, version, program, DEFAULT_PORT);
- }
- static dtls_handler_t cb = {
-@@ -268,11 +539,18 @@ static dtls_handler_t cb = {
- #endif /* DTLS_PSK */
- #ifdef DTLS_ECC
-   .get_ecdsa_key = get_ecdsa_key,
--  .verify_ecdsa_key = verify_ecdsa_key
-+  .verify_ecdsa_key = verify_ecdsa_key,
- #endif /* DTLS_ECC */
-+#ifdef DTLS_X509
-+  .get_x509_key = get_x509_key,
-+  .verify_x509_cert = verify_x509_cert,
-+  .get_x509_cert = get_x509_cert,
-+  .is_x509_active = is_x509_active,
-+#endif
-+
- };
--int 
-+int
- main(int argc, char **argv) {
-   dtls_context_t *the_context = NULL;
-   log_t log_level = DTLS_LOG_WARN;
-@@ -312,6 +590,47 @@ main(int argc, char **argv) {
-       if( strcmp(optarg, "enable") == 0)
-           ecdh_anon_enalbe = DTLS_CIPHER_ENABLE;
-       break;
-+#ifdef DTLS_X509
-+    case 'x' :
-+    {
-+      ssize_t result = read_from_file(optarg, x509_server_cert, DTLS_MAX_CERT_SIZE);
-+      if (result < 0)
-+      {
-+          dtls_warn("Cannot read Server certificate. Using default\n");
-+      }
-+      else
-+      {
-+          x509_server_cert_len = result;
-+      }
-+      break;
-+    }
-+    case 'r' :
-+    {
-+      ssize_t result = read_from_file(optarg, x509_server_priv, DTLS_PRIVATE_KEY_SIZE+1);
-+      if (result < 0)
-+      {
-+          dtls_warn("Cannot read Server private key. Using default\n");
-+      }
-+      else
-+      {
-+          x509_server_priv_is_set = result;
-+      }
-+      break;
-+    }
-+    case 'u' :
-+    {
-+      ssize_t result = read_from_file(optarg, x509_ca_pub, DTLS_PUBLIC_KEY_SIZE+1);
-+      if (result < 0)
-+      {
-+          dtls_warn("Cannot read CA public key. Using default\n");
-+      }
-+      else
-+      {
-+          x509_ca_pub_is_set = result;
-+      }
-+      break;
-+    }
-+#endif /* DTLS_X509 */
-     default:
-       usage(argv[0], dtls_package_version());
-       exit(1);
-@@ -320,6 +639,23 @@ main(int argc, char **argv) {
-   dtls_set_log_level(log_level);
-+#ifdef DTLS_X509
-+  if (x509_server_cert_len && x509_server_priv_is_set && x509_ca_pub_is_set)
-+  {
-+      x509_info_from_file = 1;
-+  }
-+  else if(!(x509_server_cert_len || x509_server_priv_is_set || x509_ca_pub_is_set))
-+  {
-+      x509_info_from_file = 0;
-+  }
-+  else
-+  {
-+      fprintf(stderr,"please set -x, -r, -u options simultaneously");
-+      usage(argv[0], dtls_package_version());
-+      exit(1);
-+  }
-+#endif /* DTLS_X509 */
-+
-   /* init socket and set it to non-blocking */
-   fd = socket(listen_addr.sin6_family, SOCK_DGRAM, 0);
-diff --git a/extlibs/tinydtls/tinydtls.h b/extlibs/tinydtls/tinydtls.h
-index b1b8cdf..dd27c55 100644
---- a/extlibs/tinydtls/tinydtls.h
-+++ b/extlibs/tinydtls/tinydtls.h
-@@ -42,4 +42,7 @@
- /** Defined to 1 if tinydtls is built for Contiki OS */
- /* #undef WITH_CONTIKI */
-+/** Define to 1 if building with X.509 support */
-+#define DTLS_X509 1
-+
- #endif /* _DTLS_TINYDTLS_H_ */
-diff --git a/extlibs/tinydtls/tinydtls.h.in b/extlibs/tinydtls/tinydtls.h.in
-index a2e6685..10a8d9a 100644
---- a/extlibs/tinydtls/tinydtls.h.in
-+++ b/extlibs/tinydtls/tinydtls.h.in
-@@ -41,4 +41,7 @@
- /** Defined to 1 if tinydtls is built for Contiki OS */
- #undef WITH_CONTIKI
-+/** Define to 1 if building with X.509 support */
-+#undef DTLS_X509
-+
- #endif /* _DTLS_TINYDTLS_H_ */
--- 
-1.9.1
-
diff --git a/extlibs/tinydtls/Android.mk b/extlibs/tinydtls/Android.mk
deleted file mode 100644 (file)
index a507a51..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-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 -DNDEBUG
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/extlibs/tinydtls/LICENSE b/extlibs/tinydtls/LICENSE
deleted file mode 100644 (file)
index 2588fe2..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License
-
-Copyright (c) 2011--2012 Olaf Bergmann <bergmann@tzi.org>
-
-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
deleted file mode 100644 (file)
index 9a52e4c..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-# Makefile for tinydtls
-#
-# Copyright (C) 2011--2014 Olaf Bergmann <bergmann@tzi.org>
-#
-# 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
deleted file mode 100644 (file)
index 88affc4..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-# 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
deleted file mode 100644 (file)
index 4f8fe55..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-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/README_Iotivity b/extlibs/tinydtls/README_Iotivity
deleted file mode 100644 (file)
index 3d18404..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-SUPPORTED CIPHER-SUITES
-  TLS_PSK_WITH_AES_128_CCM_8(0xC0A8)
-  TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8(0xC0AE)
-  TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256(0xC037)
-  TLS_ECDH_anon_WITH_AES_128_CBC_SHA256(0xC018)
-
-TEST APPLICATIONS
-These applications can be build from Iotivity's root directory using below commands:
-scons extlibs/tinydtls/dtls-client SECURED=1 RELEASE=0
-scons extlibs/tinydtls/dtls-server SECURED=1 RELEASE=0
-
-
-INTER-OPERABILITY TESTING
-tinyDTLS's cipher-suite implementations can be verified for compatibility against other
-SSL libraries.
-Use below commands to perform compatibility testing against mBed SSL library.
-./ssl_server2 debug_level=5 dtls=1 psk=73656372657450534b psk_identity=Client_identity \
-    force_version=dtls1_2 force_ciphersuite=TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256
-./dtls-client -v 6 -c 4 localhost 4433
-
-./ssl_client2 debug_level=5 dtls=1 psk=73656372657450534b psk_identity=Client_identity \
-    force_version=dtls1_2 force_ciphersuite=TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256
-./dtls-server -v 6 localhost -p 4433
-
-Above commands can also be tested with TLS-PSK-WITH-AES-128-CCM-8 cipher suite.
-
diff --git a/extlibs/tinydtls/SConscript b/extlibs/tinydtls/SConscript
deleted file mode 100644 (file)
index 82aafeb..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-# *****************************************************************
-#
-#  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
-
-dtls_env = env.Clone()
-
-dtls_env.PrependUnique(CPPPATH = [root_dir])
-dtls_env.AppendUnique(CPPPATH = [root_dir+'aes/'])
-dtls_env.AppendUnique(CPPPATH = [root_dir+'ecc/'])
-dtls_env.AppendUnique(CPPPATH = [root_dir+'sha2/'])
-
-######################################################################
-# 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',
-        ]
-
-if not dtls_env.get('RELEASE'):
-       if(target_os) not in ['arduino']:
-               tinydtls_src += ['debug.c']
-       else:
-               dtls_env.AppendUnique(CPPDEFINES = ['NDEBUG'])
-else:
-       dtls_env.AppendUnique(CPPDEFINES = ['NDEBUG'])
-
-dtls_env.AppendUnique(CPPDEFINES = ['DTLSV12',  'WITH_SHA256', 'DTLS_CHECK_CONTENTTYPE', 'SHA2_USE_INTTYPES_H'])
-env.AppendUnique(CPPDEFINES = ['SHA2_USE_INTTYPES_H'])
-
-libtinydtls = dtls_env.StaticLibrary('tinydtls', 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 = dtls_env.Clone()
-
-       if target_os not in ['arduino', 'windows']:
-               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'])
-
-       if target_os in ['windows', 'msys_nt']:
-               samples_env.AppendUnique(LIBS = ['ws2_32', 'iphlpapi', 'advapi32', 'bcrypt'])
-
-       Alias("samples", [dtlsserver, dtlsclient])
-
-       samples_env.AppendTarget('samples')
-
-dtls_env.InstallTarget(libtinydtls, 'tinydtls');
-
diff --git a/extlibs/tinydtls/aes/Makefile.in b/extlibs/tinydtls/aes/Makefile.in
deleted file mode 100644 (file)
index 4cf29d4..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-# Makefile for tinydtls
-#
-# Copyright (C) 2011 Olaf Bergmann <bergmann@tzi.org>
-#
-# 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
deleted file mode 100644 (file)
index 33001a8..0000000
+++ /dev/null
@@ -1,1287 +0,0 @@
-/*     $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 <vincent.rijmen@esat.kuleuven.ac.be>
- * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
- * @author Paulo Barreto <paulo.barreto@terra.com.br>
- *
- * 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 <sys/param.h> */
-/* #include <sys/systm.h> */
-
-#include "rijndael.h"
-
-#ifdef ARDUINO_AVR_MEGA2560
-       #include <pgmspace.h>
-#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
deleted file mode 100644 (file)
index 712798b..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*     $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 <vincent.rijmen@esat.kuleuven.ac.be>
- * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
- * @author Paulo Barreto <paulo.barreto@terra.com.br>
- *
- * 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 <stdint.h>
-
-#define WITH_AES_DECRYPT 1
-#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
deleted file mode 100644 (file)
index a589dd7..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/* alert.h -- DTLS alert protocol
- *
- * Copyright (C) 2012 Olaf Bergmann <bergmann@tzi.org>
- *
- * 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 */
-
-INLINE_API int
-dtls_alert_create(dtls_alert_level_t level, dtls_alert_t desc)
-{
-  return -((level << 8) | desc);
-}
-
-INLINE_API 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
deleted file mode 100644 (file)
index 1366145..0000000
+++ /dev/null
@@ -1,311 +0,0 @@
-/* dtls -- a very basic DTLS implementation
- *
- * Copyright (C) 2011--2014 Olaf Bergmann <bergmann@tzi.org>
- *
- * 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 <string.h>
-
-#include "dtls_config.h"
-#include "global.h"
-#include "numeric.h"
-#include "ccm.h"
-
-#ifdef HAVE_ASSERT_H
-# include <assert.h>
-#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;                                            \
-  }
-
-INLINE_API 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);  
-  } 
-}
-
-INLINE_API 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);
-}
-
-INLINE_API 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
deleted file mode 100644 (file)
index c3949d2..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/* dtls -- a very basic DTLS implementation
- *
- * Copyright (C) 2011--2012 Olaf Bergmann <bergmann@tzi.org>
- *
- * 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
deleted file mode 100644 (file)
index b341497..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-#                                               -*- Autoconf -*-
-# Process this file with autoconf to produce a configure script.
-#
-# Copyright (C) 2011--2014 Olaf Bergmann <bergmann@tzi.org>
-#
-# 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])
-
-AC_ARG_WITH(x509,
-  [AS_HELP_STRING([--with-x509],[use dtls as transport protocol])],
-  [AC_DEFINE(DTLS_X509, 1, [Define to 1 if building with X.509 support])
-   DTLS_X509=1],
-  [])
-
-AC_ARG_WITH(hal,
-  [AS_HELP_STRING([--with-hal],[use a hardware abstraction layer for crypto functions])],
-  [AC_DEFINE(DTLS_CRYPTO_HAL, 1, [Define to 1 if building with Hardware Abstraction Layer])
-   DTLS_CRYPTO_HAL=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 <netinet/in.h>])
-
-# 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
deleted file mode 100644 (file)
index f1e8542..0000000
+++ /dev/null
@@ -1,801 +0,0 @@
-/* dtls -- a very basic DTLS implementation
- *
- * Copyright (C) 2011--2012 Olaf Bergmann <bergmann@tzi.org>
- * Copyright (C) 2013 Hauke Mehrtens <hauke@hauke-m.de>
- *
- *
- * 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 <stdio.h>
-
-#include "tinydtls.h"
-#include "dtls_config.h"
-
-#ifdef HAVE_ASSERT_H
-#include <assert.h>
-#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 "aes/rijndael.h"
-#include "sha2/sha2.h"
-#include "prng.h"
-#include "netq.h"
-#include "hmac.h"
-
-#if !defined(WITH_CONTIKI) && !defined(_WIN32)
-#include <pthread.h>
-#endif
-
-#define HMAC_UPDATE_SEED(Context,Seed,Length)          \
-  if (Seed) dtls_hmac_update(Context, (Seed), (Length))
-
-static struct dtls_cipher_context_t cipher_context;
-#if !defined(WITH_CONTIKI) && !defined(_WIN32)
-static pthread_mutex_t cipher_context_mutex = PTHREAD_MUTEX_INITIALIZER;
-#endif
-
-static struct dtls_cipher_context_t *dtls_cipher_context_get(void)
-{
-#if !defined(WITH_CONTIKI) && !defined(_WIN32)
-  pthread_mutex_lock(&cipher_context_mutex);
-#endif
-  return &cipher_context;
-}
-
-static void dtls_cipher_context_release(void)
-{
-#if !defined(WITH_CONTIKI) && !defined(_WIN32)
-  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_<hash>(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_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_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;
-}
-
-static size_t
-dtls_cbc_encrypt(aes128_t *aes_ctx,
-                 unsigned char *mac_key, size_t mac_keylen,
-                 const unsigned char *iv,
-                 const unsigned char *src, size_t srclen,
-                 unsigned char *buf) {
-
-    unsigned char cbc[DTLS_BLK_LENGTH];
-    unsigned char tmp[DTLS_BLK_LENGTH];
-    unsigned char *pos;
-    const unsigned char *dtls_hdr = NULL;
-    int i, j;
-    int blocks;
-    dtls_hmac_context_t* hmac_ctx = NULL;
-    int paddinglen = 0;
-
-    pos = buf;
-
-    dtls_hdr = src - DTLS_CBC_IV_LENGTH - sizeof(dtls_record_header_t);
-
-    //Calculate MAC : Append the MAC code to end of content
-    hmac_ctx = dtls_hmac_new(mac_key, mac_keylen);
-    dtls_mac(hmac_ctx,
-             dtls_hdr,
-             src, srclen,
-             buf + srclen);
-    dtls_hmac_free(hmac_ctx);
-    
-    dtls_debug_dump("[MAC]",
-                    buf + srclen,
-                    DTLS_HMAC_DIGEST_SIZE);
-
-    paddinglen = DTLS_BLK_LENGTH - ((srclen + DTLS_HMAC_DIGEST_SIZE) % DTLS_BLK_LENGTH);
-    
-    //TLS padding
-    memset(buf + (srclen + DTLS_HMAC_DIGEST_SIZE), paddinglen - 1, paddinglen);
-
-    memcpy(cbc, iv, DTLS_BLK_LENGTH);
-    blocks = (srclen + DTLS_HMAC_DIGEST_SIZE + paddinglen) / DTLS_BLK_LENGTH;
-
-    for (i = 0; i < blocks; i++) {
-        for (j = 0; j < DTLS_BLK_LENGTH; j++) {
-            cbc[j] ^= pos[j];
-        }
-
-        rijndael_encrypt(&aes_ctx->ctx, cbc, tmp);
-        memcpy(cbc, tmp, DTLS_BLK_LENGTH);
-        memcpy(pos, cbc, DTLS_BLK_LENGTH);
-        pos += DTLS_BLK_LENGTH;
-    }
-
-    dtls_debug_dump("[Encrypted Data]",
-                    buf,
-                    srclen + DTLS_HMAC_DIGEST_SIZE + paddinglen);
-    
-    return srclen + DTLS_HMAC_DIGEST_SIZE + paddinglen;
-}
-
-
-static size_t
-dtls_cbc_decrypt(aes128_t *aes_ctx,
-                 unsigned char *mac_key, size_t mac_keylen,
-                 const unsigned char *iv,
-                 const unsigned char *src, size_t srclen,
-                 unsigned char *buf) {
-
-    unsigned char cbc[DTLS_BLK_LENGTH];
-    unsigned char tmp[DTLS_BLK_LENGTH];
-    unsigned char tmp2[DTLS_BLK_LENGTH];
-    unsigned char mac_buf[DTLS_HMAC_DIGEST_SIZE] = {0,};
-    const unsigned char *dtls_hdr = NULL;
-    unsigned char *pos;
-    int i, j;
-    int blocks;
-    int depaddinglen = 0;
-    uint8_t wrongpadding_flag = 0;
-    dtls_hmac_context_t* hmac_ctx = NULL;
-
-    pos = buf;
-
-    dtls_hdr = src - DTLS_CBC_IV_LENGTH - sizeof(dtls_record_header_t);
-
-    memcpy(cbc, iv, DTLS_BLK_LENGTH);
-    blocks = srclen / DTLS_BLK_LENGTH;
-
-    for (i = 0; i < blocks; i++)
-    {
-        memcpy(tmp, pos, DTLS_BLK_LENGTH);
-        rijndael_decrypt(&aes_ctx->ctx, pos, tmp2);
-        memcpy(pos, tmp2, DTLS_BLK_LENGTH);
-
-        for (j = 0; j < DTLS_BLK_LENGTH; j++) {
-            pos[j] ^= cbc[j];
-        }
-
-        memcpy(cbc, tmp, DTLS_BLK_LENGTH);
-        pos += DTLS_BLK_LENGTH;
-    }
-
-    //de-padding
-    depaddinglen = buf[srclen -1];
-
-    /**
-     * message validation check in case of wrong key.
-     * In case of wrong padding legnth was detected
-     * set depadding length to zero in order to resist the padding oracle attack
-     * and prevent invalid memory access.
-     */
-    if(srclen <= DTLS_HMAC_DIGEST_SIZE + depaddinglen + 1) {
-        depaddinglen = 0;
-        wrongpadding_flag = 1;
-    }
-
-    //Calculate MAC
-    hmac_ctx = dtls_hmac_new(mac_key, mac_keylen);
-    if(!hmac_ctx) {
-        return -1;
-    }
-    dtls_mac(hmac_ctx, dtls_hdr, buf,
-             srclen - DTLS_HMAC_DIGEST_SIZE - depaddinglen - 1,
-             mac_buf);
-    dtls_hmac_free(hmac_ctx);
-
-    dtls_debug_dump("[MAC]",
-                    mac_buf,
-                    DTLS_HMAC_DIGEST_SIZE);
-    dtls_debug_dump("[Decrypted data]",
-                    buf,
-                    srclen - DTLS_HMAC_DIGEST_SIZE - depaddinglen - 1);
-
-    //verify the MAC
-    if(memcmp(mac_buf,
-              buf + (srclen - DTLS_HMAC_DIGEST_SIZE - depaddinglen - 1),
-              DTLS_HMAC_DIGEST_SIZE) != 0 || wrongpadding_flag)
-    {
-        dtls_crit("Failed to verification of MAC\n");
-        return -1;
-    }
-
-    //verify the padding bytes
-    for (i =0; i < depaddinglen; i++)
-    {
-        if (buf[srclen - depaddinglen - 1 + i] != depaddinglen)
-        {
-            dtls_crit("Failed to verify padding bytes\n");
-            return -1;
-        }
-    }
-
-    return srclen - DTLS_HMAC_DIGEST_SIZE - depaddinglen - 1;
-}
-
-#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 */
-
-#if defined(DTLS_ECC) || defined(DTLS_X509)
-
-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])
-{
-    uint8_t sign[64];
-
-    // Check the buffers
-    if (priv_key == NULL || key_size < 32)
-        return;
-    if (sign_hash == NULL || sign_hash_size < 32)
-        return;
-
-    uECC_sign(priv_key, sign_hash, sign);
-
-    int i;
-    for (i = 0; i < 32; i++)
-    {
-        ((uint8_t *) point_r)[i] = sign[31 - i];
-        ((uint8_t *) point_s)[i] = sign[63 - i];
-    }
-}
-
-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 sign[64];
-
-    // Check the buffers
-    if (pub_key_x == NULL || pub_key_y == NULL || key_size < 32)
-        return 0;
-    if (sign_hash == NULL || sign_hash_size < 32)
-        return 0;
-    if (result_r == NULL || result_s == NULL)
-        return 0;
-
-    // Copy the public key into a single buffer
-    memcpy(publicKey, pub_key_x, 32);
-    memcpy(publicKey + 32, pub_key_y, 32);
-
-    // Copy the signature into a single buffer
-    memcpy(sign, result_r, 32);
-    memcpy(sign + 32, result_s, 32);
-
-    return uECC_verify(publicKey, sign_hash, 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 */
-
-#if defined(DTLS_PSK) && defined(DTLS_ECC)
-int dtls_ecdhe_psk_pre_master_secret(unsigned char *psk, size_t psklen,
-                                     unsigned char *ecc_priv_key,
-                                     unsigned char *ecc_pub_key_x,
-                                     unsigned char *ecc_pub_key_y,
-                                     size_t ecc_key_size,
-                                     unsigned char *result,
-                                     size_t result_len)
-{
-  uint8_t eccPublicKey[64];
-  uint8_t eccPrivateKey[32];
-  unsigned char *p = result;
-
-  if (result_len < uECC_BYTES + psklen + (sizeof(uint16) * 2)) {
-    return -1;
-  }
-
-  dtls_int_to_uint16(p, uECC_BYTES);
-  p += sizeof(uint16);
-
-  memcpy(eccPublicKey, ecc_pub_key_x, 32);
-  memcpy(eccPublicKey + 32, ecc_pub_key_y, 32);
-  memcpy(eccPrivateKey, ecc_priv_key, 32);
-  uECC_shared_secret(eccPublicKey, eccPrivateKey, p);
-  p += uECC_BYTES;
-
-  dtls_int_to_uint16(p, psklen);
-  p += sizeof(uint16);
-
-  memcpy(p, psk, psklen);
-
-  return uECC_BYTES + psklen + (sizeof(uint16) * 2);
-}
-#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
-
-int
-dtls_encrypt(const unsigned char *src, size_t length,
-            unsigned char *buf,
-            unsigned char *nounce,
-            unsigned char *write_key, size_t write_keylen,
-            unsigned char *mac_key, size_t mac_keylen,
-            const unsigned char *aad, size_t la,
-            const dtls_cipher_t cipher)
-{
-  int ret = 0;
-  struct dtls_cipher_context_t *ctx = dtls_cipher_context_get();
-
-  if(cipher == TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 ||
-     cipher == TLS_PSK_WITH_AES_128_CCM_8) {
-      ret = rijndael_set_key_enc_only(&ctx->data.ctx, write_key, 8 * write_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);
-  }
-  if(cipher == TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256 ||
-     cipher == TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256) {
-      ret = rijndael_set_key(&ctx->data.ctx, write_key, 8 * write_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_cbc_encrypt(&ctx->data, mac_key, mac_keylen, nounce, src, length, buf);
-  }
-
-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 *read_key, size_t read_keylen,
-            unsigned char *mac_key, size_t mac_keylen,
-            const unsigned char *aad, size_t la,
-            const dtls_cipher_t cipher)
-{
-  int ret = 0;
-  struct dtls_cipher_context_t *ctx = dtls_cipher_context_get();
-
-  if(cipher == TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 ||
-     cipher == TLS_PSK_WITH_AES_128_CCM_8) {
-      ret = rijndael_set_key_enc_only(&ctx->data.ctx, read_key, 8 * read_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);
-  }
-
-  if(cipher == TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256 ||
-     cipher == TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256) {
-      ret = rijndael_set_key(&ctx->data.ctx, read_key, 8 * read_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_cbc_decrypt(&ctx->data, mac_key, mac_keylen, nounce, src, length, buf);
-    }
-
-error:
-  dtls_cipher_context_release();
-  return ret;
-}
-
diff --git a/extlibs/tinydtls/crypto.h b/extlibs/tinydtls/crypto.h
deleted file mode 100644 (file)
index 8acf787..0000000
+++ /dev/null
@@ -1,437 +0,0 @@
-/* dtls -- a very basic DTLS implementation
- *
- * Copyright (C) 2011--2012 Olaf Bergmann <bergmann@tzi.org>
- * Copyright (C) 2013 Hauke Mehrtens <hauke@hauke-m.de>
- *
- * 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 <stdlib.h>            /* for rand() and srand() */
-#include <stdint.h>
-
-#include "t_list.h"
-
-#include "aes/rijndael.h"
-
-#include "global.h"
-#include "state.h"
-#include "numeric.h"
-#include "hmac.h"
-#include "ccm.h"
-#include "ecc/ecc.h"
-
-/* TLS_PSK_WITH_AES_128_CCM_8 */
-#define DTLS_CCM_MAC_KEY_LENGTH        0       /* MAC Key length for AES-CCM cipher suites */
-#define DTLS_CBC_MAC_KEY_LENGTH       32       /* MAC Key length for AES-CBC Cipher suites */
-#define DTLS_KEY_LENGTH        16 /* AES-128 */
-#define DTLS_BLK_LENGTH        16 /* AES-128 */
-#define DTLS_MAC_LENGTH        DTLS_HMAC_DIGEST_SIZE
-#define DTLS_CCM_IV_LENGTH     4  /* length of nonce_explicit */
-#define DTLS_CBC_IV_LENGTH     16
-
-/** 
- * 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 CCM_KB_LENGTH  \
-    (2 * DTLS_KEY_LENGTH + 2 * DTLS_CCM_IV_LENGTH)
-
-#define CBC_KB_LENGTH  \
-    (2 * DTLS_CBC_MAC_KEY_LENGTH + 2 * DTLS_KEY_LENGTH )
-
-#define MAX_KEYBLOCK_LENGTH  \
-    ((CCM_KB_LENGTH) > (CBC_KB_LENGTH) ? (CCM_KB_LENGTH) : (CBC_KB_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_t;
-
-typedef struct dtls_cipher_context_t {
-  /** numeric identifier of this cipher suite in host byte order. */
-  aes128_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_ecc_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;
-
-#if defined(DTLS_ECC) && defined(DTLS_PSK)
-  struct keyx_t {
-    dtls_handshake_parameters_ecc_t ecc;
-    dtls_handshake_parameters_psk_t psk;
-  } keyx;
-#else /* DTLS_ECC && DTLS_PSK */
-  union {
-#if defined(DTLS_ECC) || defined(DTLS_X509)
-    dtls_handshake_parameters_ecc_t ecc;
-#endif /* DTLS_ECC */
-#ifdef DTLS_PSK
-    dtls_handshake_parameters_psk_t psk;
-#endif /* DTLS_PSK */
-  } keyx;
-#endif /* DTLS_ECC && DTLS_PSK */
-} dtls_handshake_parameters_t;
-
-/* The following macros provide access to the components of the
- * key_block in the security parameters. */
-
-INLINE_API int dtls_kb_mac_secret_size(dtls_cipher_t cipher)
-{
-    switch(cipher)
-    {
-        case TLS_NULL_WITH_NULL_NULL:
-
-            return 0;
-            break;
-
-        case TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256:
-        case TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256:
-
-            return DTLS_CBC_MAC_KEY_LENGTH;
-            break;
-
-        case TLS_PSK_WITH_AES_128_CCM_8:
-        case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
-
-            return DTLS_CCM_MAC_KEY_LENGTH;
-            break;
-    }
-
-    return -1;
-}
-
-
-INLINE_API int dtls_kb_iv_size(dtls_cipher_t cipher)
-{
-    switch(cipher)
-    {
-        case TLS_NULL_WITH_NULL_NULL:
-        case TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256:
-        case TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256:
-
-            return 0;
-            break;
-
-        case TLS_PSK_WITH_AES_128_CCM_8:
-        case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
-
-            return DTLS_CCM_IV_LENGTH;
-            break;
-    }
-
-    return -1;
-}
-
-
-
-
-#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_kb_mac_secret_size((Param)->cipher))
-#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_client_write_key(Param, Role)                          \
-  (dtls_kb_server_mac_secret(Param, Role) + dtls_kb_mac_secret_size((Param)->cipher))
-#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_kb_iv_size((Param)->cipher))
-#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_size(Param, Role)                                      \
-  (2 * (dtls_kb_mac_secret_size((Param)->cipher) +                     \
-       dtls_kb_key_size(Param, Role) + dtls_kb_iv_size((Param)->cipher)))
-
-/* 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 *write_key, size_t write_keylen,
-                unsigned char *mac_key, size_t mac_keylen,
-                const unsigned char *aad, size_t aad_length,
-                const dtls_cipher_t cipher);
-
-/** 
- * 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 *read_key, size_t read_keylen,
-                unsigned char *mac_key, size_t mac_keylen,
-                const unsigned char *a_data, size_t a_data_length,
-                const dtls_cipher_t cipher);
-
-/* 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_ecdhe_psk_pre_master_secret(unsigned char *psk, size_t psklen,
-                               unsigned char *ecc_priv_key,
-                               unsigned char *ecc_pub_key_x,
-                               unsigned char *ecc_pub_key_y,
-                               size_t ecc_key_size,
-                               unsigned char *result,
-                               size_t result_len);
-
-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
deleted file mode 100644 (file)
index 5b458bc..0000000
+++ /dev/null
@@ -1,439 +0,0 @@
-/* debug.c -- debug utilities
- *
- * Copyright (C) 2011--2012 Olaf Bergmann <bergmann@tzi.org>
- *
- * 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 <assert.h>
-#endif
-
-#include <stdarg.h>
-#include <stdio.h>
-
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-
-#ifdef HAVE_TIME_H
-#include <time.h>
-#endif
-
-#ifdef __ANDROID__
-#include <android/log.h>
-#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 */
-#ifdef __ANDROID__
-static android_LogPriority loglevels_android[] = {
-  ANDROID_LOG_FATAL,
-  ANDROID_LOG_ERROR,
-  ANDROID_LOG_ERROR,
-  ANDROID_LOG_WARN,
-  ANDROID_LOG_INFO,
-  ANDROID_LOG_INFO,
-  ANDROID_LOG_DEBUG
-};
-#else
-static char *loglevels[] = {
-  "EMRG", "ALRT", "CRIT", "WARN", "NOTE", "INFO", "DEBG" 
-};
-#endif
-
-#ifdef HAVE_TIME_H
-
-INLINE_API 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 */
-
-INLINE_API 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.
- */
-INLINE_API 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) {
-#if defined(HAVE_ARPA_INET_H) || defined(_WIN32)
-  const void *addrptr = NULL;
-#if defined(__ANDROID__) || defined(_WIN32)
-  unsigned short int port;
-#else
-  in_port_t port;
-#endif
-  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
-}
-
-#ifdef __ANDROID__
-void
-dsrv_log(log_t level, char *format, ...) {
-  va_list ap;
-
-  if (maxlog < level)
-    return;
-
-  va_start(ap, format);
-  __android_log_vprint(loglevels_android[level], PACKAGE_NAME, format, ap);
-  va_end(ap);
-}
-#elif !defined (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);
-}
-
-#ifdef __ANDROID__
-void
-dtls_dsrv_hexdump_log(log_t level, const char *name, const unsigned char *buf, size_t length, int extend) {
-  char *hex_dump_text;
-  char *p;
-  int ret;
-  int size;
-
-  if (maxlog < level)
-    return;
-
-  size = length * 3 + strlen(name) + 22;
-  hex_dump_text = malloc(size);
-  if (!hex_dump_text)
-    return;
-
-  p = hex_dump_text;
-
-  ret = snprintf(p, size, "%s: (%zu bytes): ", name, length);
-  if (ret >= size)
-    goto print;
-  p += ret;
-  size -= ret;
-  while (length--) {
-    ret = snprintf(p, size, "%02X ", *buf++);
-    if (ret >= size)
-      goto print;
-    p += ret;
-    size -= ret;
-  }
-print:
-  __android_log_print(loglevels_android[level], PACKAGE_NAME, "%s\n", hex_dump_text);
-  free(hex_dump_text);
-}
-#elif !defined (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
deleted file mode 100644 (file)
index b5c8199..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-/* debug.h -- debug utilities
- *
- * Copyright (C) 2011--2012 Olaf Bergmann <bergmann@tzi.org>
- *
- * 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 <stdlib.h>
-
-#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;
-
-INLINE_API 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 */
-INLINE_API void check_stack() {
-}
-#endif /* CONTIKI_TARGET_MBXXX */
-#else /* WITH_CONTKI */
-#define PRINTF(...)
-
-INLINE_API void check_stack() {
-}
-#endif
-
-/** 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 */
-
-INLINE_API log_t dtls_get_log_level()
-{
-  return DTLS_LOG_EMERG;
-}
-
-INLINE_API void dtls_set_log_level(log_t level)
-{}
-
-INLINE_API void dsrv_log(log_t level, char *format, ...)
-{}
-
-INLINE_API void hexdump(const unsigned char *packet, int length)
-{}
-
-INLINE_API void dump(unsigned char *buf, size_t len)
-{}
-
-INLINE_API void
-dtls_dsrv_hexdump_log(log_t level, const char *name, const unsigned char *buf, size_t length, int extend)
-{}
-
-INLINE_API void
-dtls_dsrv_log_addr(log_t level, const char *name, const 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
deleted file mode 100644 (file)
index 9f7ffdf..0000000
+++ /dev/null
@@ -1,1551 +0,0 @@
-# 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 <command> <input-file>, where <command> is the value of
-# the FILE_VERSION_FILTER tag, and <input-file> 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 <filter> <input-file>, where <filter>
-# is the value of the INPUT_FILTER tag, and <input-file> 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
-# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
-
-QHP_CUST_FILTER_ATTRS  =
-
-# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's
-# filter section matches.
-# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>.
-
-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
deleted file mode 100644 (file)
index 1c8525c..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-<doxygenlayout version="1.0">
-  <!-- Navigation index tabs for HTML output -->
-  <navindex>
-    <tab type="mainpage" visible="yes" title=""/>
-    <tab type="pages" visible="yes" title=""/>
-    <tab type="modules" visible="yes" title=""/>
-    <tab type="namespaces" visible="yes" title="">
-      <tab type="namespaces" visible="yes" title=""/>
-      <tab type="namespacemembers" visible="yes" title=""/>
-    </tab>
-    <tab type="classes" visible="yes" title="">
-      <tab type="classes" visible="yes" title=""/>
-      <tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/> 
-      <tab type="hierarchy" visible="yes" title=""/>
-      <tab type="classmembers" visible="yes" title=""/>
-    </tab>
-    <tab type="files" visible="yes" title="">
-      <tab type="files" visible="yes" title=""/>
-      <tab type="globals" visible="yes" title=""/>
-    </tab>
-    <tab type="dirs" visible="yes" title=""/>
-    <tab type="examples" visible="yes" title=""/>  
-  </navindex>
-
-  <!-- Layout definition for a class page -->
-  <class>
-    <briefdescription visible="yes"/>
-    <includes visible="$SHOW_INCLUDE_FILES"/>
-    <inheritancegraph visible="$CLASS_GRAPH"/>
-    <collaborationgraph visible="$COLLABORATION_GRAPH"/>
-    <allmemberslink visible="yes"/>
-    <memberdecl>
-      <nestedclasses visible="yes" title=""/>
-      <publictypes title=""/>
-      <publicslots title=""/>
-      <signals title=""/>
-      <publicmethods title=""/>
-      <publicstaticmethods title=""/>
-      <publicattributes title=""/>
-      <publicstaticattributes title=""/>
-      <protectedtypes title=""/>
-      <protectedslots title=""/>
-      <protectedmethods title=""/>
-      <protectedstaticmethods title=""/>
-      <protectedattributes title=""/>
-      <protectedstaticattributes title=""/>
-      <packagetypes title=""/>
-      <packagemethods title=""/>
-      <packagestaticmethods title=""/>
-      <packageattributes title=""/>
-      <packagestaticattributes title=""/>
-      <properties title=""/>
-      <events title=""/>
-      <privatetypes title=""/>
-      <privateslots title=""/>
-      <privatemethods title=""/>
-      <privatestaticmethods title=""/>
-      <privateattributes title=""/>
-      <privatestaticattributes title=""/>
-      <friends title=""/>
-      <related title="" subtitle=""/>
-      <membergroups visible="yes"/>
-    </memberdecl>
-    <detaileddescription title=""/>
-    <memberdef>
-      <typedefs title=""/>
-      <enums title=""/>
-      <constructors title=""/>
-      <functions title=""/>
-      <related title=""/>
-      <variables title=""/>
-      <properties title=""/>
-      <events title=""/>
-    </memberdef>
-    <usedfiles visible="$SHOW_USED_FILES"/>
-    <authorsection visible="yes"/>
-  </class>
-
-  <!-- Layout definition for a namespace page -->
-  <namespace>
-    <briefdescription visible="yes"/>
-    <memberdecl>
-      <nestednamespaces visible="yes" title=""/>
-      <classes visible="yes" title=""/>
-      <typedefs title=""/>
-      <enums title=""/>
-      <functions title=""/>
-      <variables title=""/>
-      <membergroups visible="yes"/>
-    </memberdecl>
-    <detaileddescription title=""/>
-    <memberdef>
-      <typedefs title=""/>
-      <enums title=""/>
-      <functions title=""/>
-      <variables title=""/>
-    </memberdef>
-    <authorsection visible="yes"/>
-  </namespace>
-
-  <!-- Layout definition for a file page -->
-  <file>
-    <briefdescription visible="yes"/>
-    <includes visible="$SHOW_INCLUDE_FILES"/>
-    <includegraph visible="$INCLUDE_GRAPH"/>
-    <includedbygraph visible="$INCLUDED_BY_GRAPH"/>
-    <sourcelink visible="yes"/>
-    <memberdecl>
-      <classes visible="yes" title=""/>
-      <namespaces visible="yes" title=""/>
-      <defines title=""/>
-      <typedefs title=""/>
-      <enums title=""/>
-      <functions title=""/>
-      <variables title=""/>
-      <membergroups visible="yes"/>
-    </memberdecl>
-    <detaileddescription title=""/>
-    <memberdef>
-      <defines title=""/>
-      <typedefs title=""/>
-      <enums title=""/>
-      <functions title=""/>
-      <variables title=""/>
-    </memberdef>
-    <authorsection/>
-  </file>
-
-  <!-- Layout definition for a group page -->
-  <group>
-    <briefdescription visible="yes"/>
-    <groupgraph visible="$GROUP_GRAPHS"/>
-    <memberdecl>
-      <classes visible="yes" title=""/>
-      <namespaces visible="yes" title=""/>
-      <dirs visible="yes" title=""/>
-      <nestedgroups visible="yes" title=""/>
-      <files visible="yes" title=""/>
-      <defines title=""/>
-      <typedefs title=""/>
-      <enums title=""/>
-      <enumvalues title=""/>
-      <functions title=""/>
-      <variables title=""/>
-      <signals title=""/>
-      <publicslots title=""/>
-      <protectedslots title=""/>
-      <privateslots title=""/>
-      <events title=""/>
-      <properties title=""/>
-      <friends title=""/>
-      <membergroups visible="yes"/>
-    </memberdecl>
-    <detaileddescription title=""/>
-    <memberdef>
-      <pagedocs/>
-      <defines title=""/>
-      <typedefs title=""/>
-      <enums title=""/>
-      <enumvalues title=""/>
-      <functions title=""/>
-      <variables title=""/>
-      <signals title=""/>
-      <publicslots title=""/>
-      <protectedslots title=""/>
-      <privateslots title=""/>
-      <events title=""/>
-      <properties title=""/>
-      <friends title=""/>
-    </memberdef>
-    <authorsection visible="yes"/>
-  </group>
-
-  <!-- Layout definition for a directory page -->
-  <directory>
-    <briefdescription visible="yes"/>
-    <directorygraph visible="yes"/>
-    <memberdecl>
-      <dirs visible="yes"/>
-      <files visible="yes"/>
-    </memberdecl>
-    <detaileddescription title=""/>
-  </directory>
-</doxygenlayout>
diff --git a/extlibs/tinydtls/doc/Makefile.in b/extlibs/tinydtls/doc/Makefile.in
deleted file mode 100644 (file)
index a07101e..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-# 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
deleted file mode 100644 (file)
index 5f2e400..0000000
+++ /dev/null
@@ -1,4982 +0,0 @@
-/* dtls -- a very basic DTLS implementation
- *
- * Copyright (C) 2011--2012,2014 Olaf Bergmann <bergmann@tzi.org>
- * Copyright (C) 2013 Hauke Mehrtens <hauke@hauke-m.de>
- *
- * 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 <stdio.h>
-#include <stdlib.h>
-#ifdef HAVE_ASSERT_H
-#include <assert.h>
-#endif
-#ifndef WITH_CONTIKI
-#include <stdlib.h>
-#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_SKEXEC_ECDH_ANON_LENGTH (1 + 2 + 1 + 1 + DTLS_EC_KEY_SIZE + DTLS_EC_KEY_SIZE)
-#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;
-
-INLINE_API dtls_context_t *
-malloc_context() {
-  return &the_dtls_context;
-}
-
-INLINE_API void
-free_context(dtls_context_t *context) {
-}
-
-#else /* WITH_CONTIKI */
-
-INLINE_API dtls_context_t *
-malloc_context() {
-  return (dtls_context_t *)malloc(sizeof(dtls_context_t));
-}
-
-INLINE_API void
-free_context(dtls_context_t *context) {
-  free(context);
-}
-#endif
-
-void
-dtls_init() {
-  dtls_clock_init();
-  crypto_init();
-  netq_init();
-  peer_init();
-}
-
- void
- dtls_enables_anon_ecdh(dtls_context_t* ctx, dtls_cipher_enable_t is_enable)
-{
-    if(ctx)
-    {
-        ctx->is_anon_ecdh_eabled = is_enable;
-    }
-}
-
-void
-dtls_select_cipher(dtls_context_t* ctx, const dtls_cipher_t cipher)
-{
-    if(ctx)
-    {
-        ctx->selected_cipher = cipher;
-    }
-}
-
-/* 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);
-
-/**
- * Starts retransmissions of handshake messages for @p peer.
- */
-static void dtls_start_retransmission(dtls_context_t *context, dtls_peer_t *peer);
-
-/**
- * Clears retransmissions of handshake messages for @p peer.
- */
-static void dtls_clear_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];
-  int len;
-  size_t 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.
- */ 
-INLINE_API 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
- */ 
-INLINE_API 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 */
-INLINE_API int is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(dtls_cipher_t cipher)
-{
-#if defined(DTLS_ECC) || defined(DTLS_X509)
-  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 */
-INLINE_API 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 cipher matches TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256 */
-INLINE_API int is_tls_ecdh_anon_with_aes_128_cbc_sha_256(dtls_cipher_t cipher)
-{
-#ifdef DTLS_ECC
-    return cipher == TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256;
-#else
-    return 0;
-#endif
-}
-
-/** returns true if the cipher matches TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256 */
-INLINE_API int is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(dtls_cipher_t cipher)
-{
-#if defined(DTLS_ECC) && defined(DTLS_PSK)
-  return cipher == TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256;
-#else
-  return 0;
-#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
-}
-
-
-
-/** returns true if the application is configured for psk */
-INLINE_API 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 */
-INLINE_API 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 x509 */
-INLINE_API int is_x509_supported(dtls_context_t *ctx, int is_client)
-{
-#ifdef DTLS_X509
-  return ctx && ctx->h && ((!is_client && ctx->h->get_x509_cert) ||
-               (is_client && ctx->h->verify_x509_cert));
-#else
-  return 0;
-#endif /* DTLS_X509 */
-}
-
-/** Returns true if the application is configured for ecdhe_ecdsa with
-  * client authentication */
-INLINE_API 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 true if the application is configured for x509 with
-  * client authentication */
-INLINE_API int is_x509_client_auth_supported(dtls_context_t *ctx)
-{
-#ifdef DTLS_X509
-  return ctx && ctx->h && ctx->h->get_x509_cert && ctx->h->verify_x509_cert;
-#else
-  return 0;
-#endif /* DTLS_X509 */
-}
-
-/** returns true if ecdh_anon_with_aes_128_cbc_sha is supported */
-INLINE_API int is_ecdh_anon_supported(dtls_context_t *ctx)
-{
-#ifdef DTLS_ECC
-    return ctx &&  (ctx->is_anon_ecdh_eabled == DTLS_CIPHER_ENABLE);
-#else
-    return 0;
-#endif
-}
-
-/** returns true if ecdhe_psk_with_aes_128_cbc_sha_256 is supported */
-INLINE_API int is_ecdhe_psk_supported(dtls_context_t *ctx)
-{
-#if defined(DTLS_ECC) && defined(DTLS_PSK)
-    return is_psk_supported(ctx);
-#else
-    return 0;
-#endif /* defined(DTLS_PSK) && defined(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;
-  int ecdh_anon;
-  int ecdhe_psk;
-  int x509;
-
-  psk = is_psk_supported(ctx);
-  ecdsa = is_ecdsa_supported(ctx, is_client);
-  ecdh_anon = is_ecdh_anon_supported(ctx);
-  ecdhe_psk = is_ecdhe_psk_supported(ctx);
-  x509 = is_x509_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)) ||
-        (ecdh_anon && is_tls_ecdh_anon_with_aes_128_cbc_sha_256(code)) ||
-        (ecdhe_psk && is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(code)) ||
-     (x509 && 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->cipher));
-
-  dtls_debug_dump("  server_MAC_secret",
-                 dtls_kb_server_mac_secret(config, peer->role),
-                 dtls_kb_mac_secret_size(config->cipher));
-
-  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->cipher));
-
-  dtls_debug_dump("  server_IV",
-                 dtls_kb_server_iv(config, peer->role),
-                 dtls_kb_iv_size(config->cipher));
-}
-
-/** 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) {
-#if defined(DTLS_PSK) && defined(DTLS_ECC)
-  unsigned char pre_master_secret[MAX_KEYBLOCK_LENGTH + uECC_BYTES];
-#else
-  unsigned char pre_master_secret[MAX_KEYBLOCK_LENGTH];
-#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
-  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);
-  }
-
-  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 */
-#if defined(DTLS_ECC) || defined(DTLS_X509)
-  case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
-  case TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256: {
-    pre_master_len = dtls_ecdh_pre_master_secret(handshake->keyx.ecc.own_eph_priv,
-                                                handshake->keyx.ecc.other_eph_pub_x,
-                                                handshake->keyx.ecc.other_eph_pub_y,
-                                                sizeof(handshake->keyx.ecc.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 */
-#if defined(DTLS_PSK) && defined(DTLS_ECC)
-    case TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256: {
-      unsigned char psk[DTLS_PSK_MAX_KEY_LEN];
-      int psklen;
-
-      psklen = 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 (psklen < 0) {
-        dtls_crit("no psk key for session available\n");
-        return psklen;
-      }
-
-      pre_master_len = dtls_ecdhe_psk_pre_master_secret(psk, psklen,
-                           handshake->keyx.ecc.own_eph_priv,
-                           handshake->keyx.ecc.other_eph_pub_x,
-                           handshake->keyx.ecc.other_eph_pub_y,
-                           sizeof(handshake->keyx.ecc.own_eph_priv),
-                           pre_master_secret,
-                           MAX_KEYBLOCK_LENGTH + uECC_BYTES);
-
-      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 /* defined(DTLS_PSK) && defined(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) */
-  security->cipher = handshake->cipher;
-  security->compression = handshake->compression;
-  security->rseq = 0;
-
-  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);
-
-
-  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;
-#ifdef DTLS_X509
-    if (cert_type == TLS_CERT_TYPE_X509)
-        return 0;
-#endif
-  }
-
-  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 {
-#ifndef DTLS_X509
-         if (dtls_uint8_to_int(data) != TLS_CERT_TYPE_RAW_PUBLIC_KEY)
-#else
-         if ((dtls_uint8_to_int(data) != TLS_CERT_TYPE_RAW_PUBLIC_KEY) &&
-             (dtls_uint8_to_int(data) != TLS_CERT_TYPE_X509))
-#endif
-           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 {
-#ifndef DTLS_X509
-         if (dtls_uint8_to_int(data) != TLS_CERT_TYPE_RAW_PUBLIC_KEY)
-#else
-         if ((dtls_uint8_to_int(data) != TLS_CERT_TYPE_RAW_PUBLIC_KEY) &&
-             (dtls_uint8_to_int(data) != TLS_CERT_TYPE_X509))
-#endif
-           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;
-  unsigned int 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.
- */
-INLINE_API int
-check_client_keyexchange(dtls_context_t *ctx, 
-                        dtls_handshake_parameters_t *handshake,
-                        uint8 *data, size_t length) {
-
-#if defined(DTLS_ECC) || defined(DTLS_X509)
-  if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(handshake->cipher) ||
-       is_tls_ecdh_anon_with_aes_128_cbc_sha_256(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.ecc.other_eph_pub_x, data,
-          sizeof(handshake->keyx.ecc.other_eph_pub_x));
-    data += sizeof(handshake->keyx.ecc.other_eph_pub_x);
-
-    memcpy(handshake->keyx.ecc.other_eph_pub_y, data,
-          sizeof(handshake->keyx.ecc.other_eph_pub_y));
-    data += sizeof(handshake->keyx.ecc.other_eph_pub_y);
-  }
-#endif /* DTLS_ECC */
-#if defined(DTLS_PSK) && defined(DTLS_ECC)
-  if (is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(handshake->cipher)) {
-    int id_length;
-
-    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;
-
-    //PSK hint
-    id_length = dtls_uint16_to_int(data);
-    data += sizeof(uint16);
-
-    if (DTLS_HS_LENGTH + DTLS_CKXPSK_LENGTH_MIN + DTLS_CKXEC_LENGTH + 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);
-    data += id_length;
-
-    //ECDH public
-    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.ecc.other_eph_pub_x, data,
-       sizeof(handshake->keyx.ecc.other_eph_pub_x));
-    data += sizeof(handshake->keyx.ecc.other_eph_pub_x);
-
-    memcpy(handshake->keyx.ecc.other_eph_pub_y, data,
-       sizeof(handshake->keyx.ecc.other_eph_pub_y));
-    data += sizeof(handshake->keyx.ecc.other_eph_pub_y);
-  }
-#endif /* defined(DTLS_PSK) && defined(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;
-}
-
-INLINE_API 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));
-}
-
-INLINE_API size_t
-finalize_hs_hash(dtls_peer_t *peer, uint8 *buf) {
-  return dtls_hash_finalize(buf, &peer->handshake_params->hs_state.hs_hash);
-}
-
-INLINE_API 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 if (is_tls_ecdh_anon_with_aes_128_cbc_sha_256(security->cipher) ||
-             is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(security->cipher)) {
-
-    unsigned char nonce[DTLS_CBC_IV_LENGTH];
-
-    /** Add IV into body of packet in case of AES CBC mode according to RFC 5246, Section 6.2.3.2
-     *
-     *    opaque IV[SecurityParameters.record_iv_length];
-     *    block-ciphered struct {
-     *        opaque content[TLSCompressed.length];
-     *        opaque MAC[SecurityParameters.mac_length];
-     *        uint8 padding[GenericBlockCipher.padding_length];
-     *        uint8 padding_length;
-     * };
-     *
-     */
-
-    res = 0;
-    dtls_prng(nonce, DTLS_CBC_IV_LENGTH);
-    memcpy(p , nonce, DTLS_CBC_IV_LENGTH);
-    p += DTLS_CBC_IV_LENGTH;
-    res += DTLS_CBC_IV_LENGTH;
-
-    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];
-     }
-
-     res = dtls_encrypt(start + DTLS_CBC_IV_LENGTH, res - DTLS_CBC_IV_LENGTH,
-               start + DTLS_CBC_IV_LENGTH, nonce,
-               dtls_kb_local_write_key(security, peer->role),
-               dtls_kb_key_size(security, peer->role),
-               dtls_kb_local_mac_secret(security, peer->role),
-               dtls_kb_mac_secret_size(security->cipher),
-               NULL, 0,
-               security->cipher);
-     if (res < 0)
-       return res;
-
-     res += DTLS_CBC_IV_LENGTH;
-
-  } 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->cipher));
-    memcpy(nonce + dtls_kb_iv_size(security->cipher), 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),
-               dtls_kb_local_mac_secret(security, peer->role),
-               dtls_kb_mac_secret_size(security->cipher),
-               A_DATA, A_DATA_LEN,
-               security->cipher);
-
-    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);
-}
-
-INLINE_API 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
-}
-
-#if defined(DTLS_ECC) || defined(DTLS_X509)
-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.ecc.other_pub_x, config->keyx.ecc.other_pub_y,
-                                   sizeof(config->keyx.ecc.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);
-#ifdef DTLS_X509
-    if (CALL(ctx, is_x509_active) == 0)
-      dtls_int_to_uint8(p, TLS_CERT_TYPE_X509);
-    else
-#endif /* DTLS_X509 */
-      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);
-
-#ifdef DTLS_X509
-    if (CALL(ctx, is_x509_active) == 0)
-      dtls_int_to_uint8(p, TLS_CERT_TYPE_X509);
-    else
-#endif /* DTLS_X509 */
-      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
-#define DTLS_EC_SUBJECTPUBLICKEY_SIZE (2 * DTLS_EC_KEY_SIZE + sizeof(cert_asn1_header))
-
-static int
-dtls_send_certificate_ecdsa(dtls_context_t *ctx, dtls_peer_t *peer,
-                           const dtls_ecc_key_t *key)
-{
-  uint8 buf[DTLS_CE_LENGTH];
-  uint8 *p;
-
-  /* Certificate
-   *
-   * Start message construction at beginning of buffer. */
-  p = buf;
-
-  /* length of this certificate */
-  dtls_int_to_uint24(p, DTLS_EC_SUBJECTPUBLICKEY_SIZE);
-  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);
-}
-#endif /* DTLS_ECC */
-
-#ifdef DTLS_X509
-static int
-dtls_send_certificate_x509(dtls_context_t *ctx, dtls_peer_t *peer)
-{
-  uint8 buf[DTLS_MAX_CERT_SIZE];
-  uint8 *p;
-  int ret;
-  unsigned char *cert;
-  size_t cert_size;
-
-  dtls_info("\n dtls_send_certificate_ecdsa\n");
-  ret = CALL(ctx, get_x509_cert, &peer->session,
-          (const unsigned char **)&cert, &cert_size);
-
-  if (ret < 0) {
-    dtls_alert_fatal_create(DTLS_ALERT_HANDSHAKE_FAILURE);
-    return ret;
-  }
-
-  /* Certificate
-   *
-   * Start message construction at beginning of buffer. */
-  p = buf;
-
-  dtls_int_to_uint24(p, cert_size); /* certificates length */
-  p += sizeof(uint24);
-
-  memcpy(p, cert, cert_size);
-  p += cert_size;
-
-  assert(p - buf <= sizeof(buf));
-
-  return dtls_send_handshake_msg(ctx, peer, DTLS_HT_CERTIFICATE,
-                                buf, p - buf);
-}
-#endif /* DTLS_X509 */
-
-#if defined(DTLS_X509) || defined(DTLS_ECC)
-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_ecc_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];
-  int ecdsa;
-  dtls_handshake_parameters_t *config = peer->handshake_params;
-
-  ecdsa = is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher);
-  /* 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.ecc.own_eph_priv,
-              ephemeral_pub_x, ephemeral_pub_y,
-              DTLS_EC_KEY_SIZE);
-  if(ecdsa) {
-      /* 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 /* defined(DTLS_X509) || defined(DTLS_ECC) */
-
-#if defined(DTLS_PSK) && defined(DTLS_ECC)
-static int dtls_send_server_key_exchange_ecdhe_psk(dtls_context_t *ctx, dtls_peer_t *peer,
-                                 const unsigned char *psk_hint, size_t psk_hint_len)
-{
-  /* 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 + DTLS_SKEXECPSK_LENGTH_MAX + 2];
-  uint8 *p;
-  uint8 *ephemeral_pub_x;
-  uint8 *ephemeral_pub_y;
-  dtls_handshake_parameters_t *config = peer->handshake_params;
-
-  /* ServerKeyExchange
-    * Please see Session 2, RFC 5489.
-
-         struct {
-          select (KeyExchangeAlgorithm) {
-              //other cases for rsa, diffie_hellman, etc.
-              case ec_diffie_hellman_psk:  // NEW
-                  opaque psk_identity_hint<0..2^16-1>;
-                  ServerECDHParams params;
-          };
-      } ServerKeyExchange; */
-  p = buf;
-
-  assert(psk_hint_len <= DTLS_PSK_MAX_CLIENT_IDENTITY_LEN);
-  if (psk_hint_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);
-  }
-
-  // psk_identity_hint
-  dtls_int_to_uint16(p, psk_hint_len);
-  p += sizeof(uint16);
-
-  memcpy(p, psk_hint, psk_hint_len);
-  p += psk_hint_len;
-
-  /* ServerECDHParams. */
-  /* ECCurveType curve_type: named_curve */
-  dtls_int_to_uint8(p, TLS_EC_CURVE_TYPE_NAMED_CURVE);
-  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.ecc.own_eph_priv,
-              ephemeral_pub_x, ephemeral_pub_y,
-              DTLS_EC_KEY_SIZE);
-
-  assert(p - buf <= sizeof(buf));
-
-  return dtls_send_handshake_msg(ctx, peer, DTLS_HT_SERVER_KEY_EXCHANGE,
-                                buf, p - buf);
-}
-#endif /* defined(DTLS_PSK) && defined(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 */
-
-#if defined(DTLS_ECC) || defined(DTLS_X509)
-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;
-  int ecdsa;
-  int ecdh_anon;
-  int ecdhe_psk;
-
-  res = dtls_send_server_hello(ctx, peer);
-
-  if (res < 0) {
-    dtls_debug("dtls_server_hello: cannot prepare ServerHello record\n");
-    return res;
-  }
-
-  ecdsa = is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(peer->handshake_params->cipher);
-  ecdh_anon = is_tls_ecdh_anon_with_aes_128_cbc_sha_256(peer->handshake_params->cipher);
-  ecdhe_psk = is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(peer->handshake_params->cipher);
-
-#if defined(DTLS_ECC) || defined(DTLS_X509)
-  if(ecdh_anon) {
-      res = dtls_send_server_key_exchange_ecdh(ctx, peer, NULL);
-
-      if (res < 0) {
-        dtls_debug("dtls_server_hello(with ECDH): cannot prepare Server Key Exchange record\n");
-        return res;
-      }
-  }
-  else if (ecdsa) {
-    const dtls_ecc_key_t *ecdsa_key;
-
-#ifdef DTLS_X509
-    if (CALL(ctx, is_x509_active) == 0)
-      res = CALL(ctx, get_x509_key, &peer->session, &ecdsa_key);
-    else
-#endif /* DTLS_X509 */
-      res = CALL(ctx, get_ecdsa_key, &peer->session, &ecdsa_key);
-
-    if (res < 0) {
-        dtls_debug("no ecdsa key to send\n");
-      return res;
-    }
-
-#ifdef DTLS_X509
-    if (CALL(ctx, is_x509_active) == 0)
-      res = dtls_send_certificate_x509(ctx, peer);
-    else
-#endif /* DTLS_X509 */
-      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) || (is_x509_client_auth_supported(ctx)))) {
-      res = dtls_send_server_certificate_request(ctx, peer);
-      if (res < 0) {
-        dtls_debug("dtls_server_hello(with ECDSA): cannot prepare certificate Request record\n");
-        return res;
-      }
-    }
-  }
-#endif /* DTLS_ECC */
-#if defined(DTLS_PSK) && defined(DTLS_ECC)
-  else if(ecdhe_psk) {
-    unsigned char psk_hint[DTLS_PSK_MAX_CLIENT_IDENTITY_LEN];
-    int psk_len;
-
-    /* The identity hint is optional, therefore we ignore the result
-     * and check psk only. */
-    psk_len = CALL(ctx, get_psk_info, &peer->session, DTLS_PSK_HINT,
-              NULL, 0, psk_hint, DTLS_PSK_MAX_CLIENT_IDENTITY_LEN);
-
-    if (psk_len < 0) {
-      dtls_debug("dtls_server_hello: cannot create ServerKeyExchange\n");
-      return psk_len;
-    }
-
-    if (psk_len > 0) {
-      res = dtls_send_server_key_exchange_ecdhe_psk(ctx, peer, psk_hint, (size_t)psk_len);
-
-      if (res < 0) {
-        dtls_debug("dtls_server_hello(with ECDHE): cannot prepare Server Key Exchange record\n");
-        return res;
-      }
-    }
-  }
-#endif /* defined(DTLS_PSK) && defined(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;
-}
-
-INLINE_API 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)
-{
-#if defined(DTLS_PSK) && defined(DTLS_ECC)
-  uint8 buf[DTLS_CKXEC_LENGTH + 2 + DTLS_PSK_MAX_CLIENT_IDENTITY_LEN];
-#else
-  uint8 buf[DTLS_CKXEC_LENGTH];
-#endif /* defined(DTLS_PSK) && defined(DTLS_ECC) */
-  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 */
-#if defined(DTLS_ECC) || defined(DTLS_X509)
-  case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
-  case TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256: {
-    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.ecc.own_eph_priv,
-                           ephemeral_pub_x, ephemeral_pub_y,
-                           DTLS_EC_KEY_SIZE);
-
-    break;
-  }
-#endif /* DTLS_ECC */
-#if defined(DTLS_PSK) && defined(DTLS_ECC)
-  case TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256: {
-      int psk_len;
-      uint8 *ephemeral_pub_x;
-      uint8 *ephemeral_pub_y;
-
-    /* Please see Session 2, RFC 5489.
-         struct {
-            select (KeyExchangeAlgorithm) {
-                // other cases for rsa, diffie_hellman, etc.
-                case ec_diffie_hellman_psk:
-                    opaque psk_identity<0..2^16-1>;
-                    ClientECDiffieHellmanPublic public;
-            } exchange_keys;
-        } ClientKeyExchange;
-    */
-
-    psk_len = CALL(ctx, get_psk_info, &peer->session, DTLS_PSK_IDENTITY,
-               NULL, 0,
-               client_id,
-               sizeof(client_id));
-    if (psk_len < 0) {
-      dtls_crit("no psk identity set in kx\n");
-      return psk_len;
-    }
-
-    if (psk_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, psk_len);
-    p += sizeof(uint16);
-
-    memcpy(p, client_id, psk_len);
-    p += psk_len;
-
-    dtls_int_to_uint8(p, 1 + 2 * DTLS_EC_KEY_SIZE);
-    p += sizeof(uint8);
-
-    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.ecc.own_eph_priv,
-                           ephemeral_pub_x, ephemeral_pub_y,
-                           DTLS_EC_KEY_SIZE);
-    break;
-  }
-#endif /* defined(DTLS_PSK) && defined(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);
-}
-
-#if defined(DTLS_ECC) || defined(DTLS_X509)
-static int
-dtls_send_certificate_verify_ecdh(dtls_context_t *ctx, dtls_peer_t *peer,
-                                  const dtls_ecc_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 = 0;
-  uint8_t extension_size = 0;
-  int psk = 0;
-  int ecdsa = 0;
-  int ecdh_anon = 0;
-  int ecdhe_psk = 0;
-  int x509 = 0;
-  dtls_handshake_parameters_t *handshake = peer->handshake_params;
-  dtls_tick_t now;
-
-  switch(ctx->selected_cipher)
-  {
-      case TLS_PSK_WITH_AES_128_CCM_8:
-        psk = is_psk_supported(ctx);
-        break;
-      case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
-        ecdsa = is_ecdsa_supported(ctx, 1);
-        x509 = is_x509_supported(ctx, 1);
-        break;
-      case TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256:
-        ecdh_anon = is_ecdh_anon_supported(ctx);
-        break;
-      case TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256:
-        ecdhe_psk = is_ecdhe_psk_supported(ctx);
-        break;
-      default:
-        psk = is_psk_supported(ctx);
-        ecdsa = is_ecdsa_supported(ctx, 1);
-        ecdh_anon = is_ecdh_anon_supported(ctx);
-        ecdhe_psk = is_ecdhe_psk_supported(ctx);
-        x509 = is_x509_supported(ctx, 1);
-        break;
-   }
-
-  cipher_size = 2 + ((ecdsa || x509) ? 2 : 0) + (psk ? 2 : 0) + (ecdh_anon ? 2 : 0) + (ecdhe_psk ? 2 : 0);
-
-  /* Is extension needed? */
-  extension_size = (ecdsa || x509 || ecdhe_psk || ecdh_anon) ? 2 : 0;
-  /* Supported EC and Supported Point Formats */
-  extension_size += (ecdsa || x509 || ecdhe_psk | ecdh_anon) ? ( 8 + 6) : 0;
-  /* Supported Client and Server Cert Types */
-  extension_size += (ecdsa || x509) ? ( 6 + 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 (ecdh_anon) {
-    dtls_int_to_uint16(p, TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256);
-    p += sizeof(uint16);
-  }
-  if (psk) {
-    dtls_int_to_uint16(p, TLS_PSK_WITH_AES_128_CCM_8);
-    p += sizeof(uint16);
-  }
-  if (ecdsa || x509) {
-    dtls_int_to_uint16(p, TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8);
-    p += sizeof(uint16);
-  }
-  if (ecdhe_psk) {
-      dtls_int_to_uint16(p, TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256);
-      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 || x509) {
-    /* 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);
-
-#ifdef DTLS_X509
-    if (CALL(ctx, is_x509_active) == 0)
-      dtls_int_to_uint8(p, TLS_CERT_TYPE_X509);
-    else
-#endif /* DTLS_X509 */
-      dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY);
-
-    p += sizeof(uint8);
-
-    /* server 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);
-
-#ifdef DTLS_X509
-    if (CALL(ctx, is_x509_active) == 0)
-      dtls_int_to_uint8(p, TLS_CERT_TYPE_X509);
-    else
-#endif /* DTLS_X509 */
-      dtls_int_to_uint8(p, TLS_CERT_TYPE_RAW_PUBLIC_KEY);
-
-    p += sizeof(uint8);
-  }
-
-  if (ecdsa || x509 || ecdhe_psk || ecdh_anon ) {
-    /* 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_peer_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) != DTLS_EC_SUBJECTPUBLICKEY_SIZE) {
-    dtls_alert("expect length of %d bytes for certificate\n",
-              DTLS_EC_SUBJECTPUBLICKEY_SIZE);
-    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.ecc.other_pub_x, data,
-        sizeof(config->keyx.ecc.other_pub_x));
-  data += sizeof(config->keyx.ecc.other_pub_x);
-
-  memcpy(config->keyx.ecc.other_pub_y, data,
-        sizeof(config->keyx.ecc.other_pub_y));
-  data += sizeof(config->keyx.ecc.other_pub_y);
-
-  err = CALL(ctx, verify_ecdsa_key, &peer->session,
-            config->keyx.ecc.other_pub_x,
-            config->keyx.ecc.other_pub_y,
-            sizeof(config->keyx.ecc.other_pub_x));
-  if (err < 0) {
-    dtls_warn("The certificate was not accepted\n");
-    return err;
-  }
-
-  return 0;
-}
-#endif /* DTLS_ECC */
-
-#ifdef DTLS_X509
-static int
-check_peer_certificate_x509(dtls_context_t *ctx,
-                        dtls_peer_t *peer,
-                        uint8 *data, size_t data_length)
-{
-  int ret;
-  dtls_handshake_parameters_t *config = peer->handshake_params;
-  int cert_length;
-
-  dtls_info("\n check_peer_certificate_x509\n");
-  update_hs_hash(peer, data, data_length);
-
-  assert(is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(config->cipher));
-
-  data += DTLS_HS_LENGTH;
-
-  cert_length = dtls_uint24_to_int(data);
-  data += sizeof(uint24);
-
-  ret = CALL(ctx, verify_x509_cert, &peer->session, data, cert_length,
-          config->keyx.ecc.other_pub_x, sizeof(config->keyx.ecc.other_pub_x),
-          config->keyx.ecc.other_pub_y, sizeof(config->keyx.ecc.other_pub_y));
-  if (ret < 0) {
-    dtls_warn("The certificate was not accepted\n");
-    return ret;
-  }
-
-  return 0;
-}
-#endif /* DTLS_X509 */
-
-#if defined(DTLS_X509) || defined(DTLS_ECC)
-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.ecc.other_eph_pub_x, data, sizeof(config->keyx.ecc.other_eph_pub_y));
-  data += sizeof(config->keyx.ecc.other_eph_pub_y);
-  data_length -= sizeof(config->keyx.ecc.other_eph_pub_y);
-
-  memcpy(config->keyx.ecc.other_eph_pub_y, data, sizeof(config->keyx.ecc.other_eph_pub_y));
-  data += sizeof(config->keyx.ecc.other_eph_pub_y);
-  data_length -= sizeof(config->keyx.ecc.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.ecc.other_pub_x, config->keyx.ecc.other_pub_y,
-                              sizeof(config->keyx.ecc.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;
-}
-
-static int
-check_server_key_exchange_ecdh(dtls_context_t *ctx,
-                               dtls_peer_t *peer,
-                               uint8 *data, size_t data_length)
-{
-  dtls_handshake_parameters_t *config = peer->handshake_params;
-
-  update_hs_hash(peer, data, data_length);
-
-  assert(is_tls_ecdh_anon_with_aes_128_cbc_sha_256(config->cipher));
-
-  data += DTLS_HS_LENGTH;
-
-  if (data_length < DTLS_HS_LENGTH + DTLS_SKEXEC_ECDH_ANON_LENGTH) {
-    dtls_alert("the packet length does not match the expected\n");
-    return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR);
-  }
-
-  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.ecc.other_eph_pub_x, data, sizeof(config->keyx.ecc.other_eph_pub_x));
-  data += sizeof(config->keyx.ecc.other_eph_pub_x);
-  data_length -= sizeof(config->keyx.ecc.other_eph_pub_x);
-
-  memcpy(config->keyx.ecc.other_eph_pub_y, data, sizeof(config->keyx.ecc.other_eph_pub_y));
-  data += sizeof(config->keyx.ecc.other_eph_pub_y);
-  data_length -= sizeof(config->keyx.ecc.other_eph_pub_y);
-
-  return 0;
-}
-#endif /* DTLS_ECC */
-#if defined(DTLS_PSK) && defined(DTLS_ECC)
-check_server_key_exchange_ecdhe_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 psk_len = 0;
-
-  /* ServerKeyExchange
-    * Please see Session 2, RFC 5489.
-
-         struct {
-          select (KeyExchangeAlgorithm) {
-              //other cases for rsa, diffie_hellman, etc.
-              case ec_diffie_hellman_psk:  // NEW
-                  opaque psk_identity_hint<0..2^16-1>;
-                  ServerECDHParams params;
-          };
-      } ServerKeyExchange; */
-
-  update_hs_hash(peer, data, data_length);
-
-  assert(is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(config->cipher));
-
-  data += DTLS_HS_LENGTH;
-
-  psk_len = dtls_uint16_to_int(data);
-  data += sizeof(uint16);
-
-  if (psk_len != data_length - DTLS_HS_LENGTH - DTLS_SKEXEC_ECDH_ANON_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 (psk_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 = psk_len;
-  memcpy(config->keyx.psk.identity, data, psk_len);
-
-  data += psk_len;
-  data_length -= psk_len;
-
-  if (data_length < DTLS_HS_LENGTH + DTLS_SKEXEC_ECDH_ANON_LENGTH) {
-    dtls_alert("the packet length does not match the expected\n");
-    return dtls_alert_fatal_create(DTLS_ALERT_DECODE_ERROR);
-  }
-
-  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.ecc.other_eph_pub_x, data, sizeof(config->keyx.ecc.other_eph_pub_x));
-  data += sizeof(config->keyx.ecc.other_eph_pub_x);
-  data_length -= sizeof(config->keyx.ecc.other_eph_pub_x);
-
-  memcpy(config->keyx.ecc.other_eph_pub_y, data, sizeof(config->keyx.ecc.other_eph_pub_y));
-  data += sizeof(config->keyx.ecc.other_eph_pub_y);
-  data_length -= sizeof(config->keyx.ecc.other_eph_pub_y);
-
-  return 0;
-}
-#endif /* defined(DTLS_PSK) && defined(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 = 0;
-#ifdef DTLS_ECC
-  const dtls_ecc_key_t *ecdsa_key;
-#ifdef DTLS_X509
-  unsigned char *cert;
-  size_t cert_size;
-#endif /* DTLS_X509 */
-#endif /* DTLS_ECC */
-
-  dtls_handshake_parameters_t *handshake = peer->handshake_params;
-
-  /* calculate master key, send CCS */
-
-  update_hs_hash(peer, data, data_length);
-
-#if defined(DTLS_ECC) || defined(DTLS_X509)
-  if (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(handshake->cipher) && handshake->do_client_auth) {
-#ifdef DTLS_X509
-    if (CALL(ctx, is_x509_active) == 0)
-      res = CALL(ctx, get_x509_key, &peer->session, &ecdsa_key);
-    else
-#endif /* DTLS_X509 */
-      res = CALL(ctx, get_ecdsa_key, &peer->session, &ecdsa_key);
-    if (res < 0) {
-      dtls_crit("no ecdsa key to use\n");
-      return res;
-    }
-
-#ifdef DTLS_X509
-    if (CALL(ctx, is_x509_active) == 0)
-      res = dtls_send_certificate_x509(ctx, peer);
-    else
-#endif /* DTLS_X509 */
-      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 (is_tls_ecdhe_ecdsa_with_aes_128_ccm_8(handshake->cipher) && 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 if (is_tls_ecdh_anon_with_aes_128_cbc_sha_256(security->cipher) ||
-             is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(security->cipher)) {
-
-    unsigned char nonce[DTLS_CBC_IV_LENGTH];
-
-    if (clen < (DTLS_CBC_IV_LENGTH + DTLS_HMAC_DIGEST_SIZE))           /* need at least IV and MAC */
-      return -1;
-
-    memcpy(nonce, *cleartext , DTLS_CBC_IV_LENGTH);
-    clen -= DTLS_CBC_IV_LENGTH;
-    *cleartext += DTLS_CBC_IV_LENGTH ;
-
-    clen = dtls_decrypt(*cleartext, clen, *cleartext, nonce,
-                      dtls_kb_remote_write_key(security, peer->role),
-                      dtls_kb_key_size(security, peer->role),
-                       dtls_kb_remote_mac_secret(security, peer->role),
-                       dtls_kb_mac_secret_size(security->cipher),
-                      NULL, 0,
-                      security->cipher);
-
-  } 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->cipher));
-
-    /* read epoch and seq_num from message */
-    memcpy(nonce + dtls_kb_iv_size(security->cipher), *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),
-                       dtls_kb_remote_mac_secret(security, peer->role),
-                       dtls_kb_mac_secret_size(security->cipher),
-                      A_DATA, A_DATA_LEN,
-                      security->cipher);
-  }
-
-  if (clen < 0)
-    dtls_warn("decryption failed\n");
-  else {
-#ifndef NDEBUG
-    dtls_debug("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_handshake_header_t *hs_header = DTLS_HANDSHAKE_HEADER(data);
-    if (state == DTLS_STATE_WAIT_CHANGECIPHERSPEC && hs_header->msg_type ==  DTLS_HT_FINISHED) {
-      return 0;
-    }
-    dtls_clear_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; //ecdsa
-    else if (is_tls_ecdh_anon_with_aes_128_cbc_sha_256(peer->handshake_params->cipher) ||
-        is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(peer->handshake_params->cipher))
-        peer->state = DTLS_STATE_WAIT_SERVERKEYEXCHANGE; //ecdh
-    else
-      peer->state = DTLS_STATE_WAIT_SERVERHELLODONE; //psk
-    /* update_hs_hash(peer, data, data_length); */
-
-    break;
-
-#if defined(DTLS_ECC) || defined(DTLS_X509)
-  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);
-    }
-#ifdef DTLS_X509
-    if (CALL(ctx, is_x509_active) == 0)
-      err = check_peer_certificate_x509(ctx, peer, data, data_length);
-    else
-#endif /* DTLS_X509 */
-      err = check_peer_certificate(ctx, peer, data, data_length);
-    if (err < 0) {
-      dtls_warn("error in check_peer_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:
-
-#if defined(DTLS_ECC) || defined(DTLS_X509)
-    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);
-    }
-
-    if (is_tls_ecdh_anon_with_aes_128_cbc_sha_256(peer->handshake_params->cipher)) {
-      if (state != DTLS_STATE_WAIT_SERVERKEYEXCHANGE) {
-        return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE);
-      }
-      err = check_server_key_exchange_ecdh(ctx, peer, data, data_length);
-    }
-#endif /* DTLS_ECC */
-
-#if defined(DTLS_PSK) && defined(DTLS_ECC)
-    if (is_tls_ecdhe_psk_with_aes_128_cbc_sha_256(peer->handshake_params->cipher)) {
-        if (state != DTLS_STATE_WAIT_SERVERKEYEXCHANGE) {
-          return dtls_alert_fatal_create(DTLS_ALERT_UNEXPECTED_MESSAGE);
-        }
-      err = check_server_key_exchange_ecdhe_psk(ctx, peer, data, data_length);
-    }
-#endif /* defined(DTLS_PSK) && defined(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) || (is_x509_client_auth_supported(ctx))))
-      peer->state = DTLS_STATE_WAIT_CERTIFICATEVERIFY; //ecdsa
-    else
-      peer->state = DTLS_STATE_WAIT_CHANGECIPHERSPEC; //psk || ecdh_anon
-    break;
-
-#if defined(DTLS_ECC) || defined(DTLS_X509)
-  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) || (is_x509_client_auth_supported(ctx))))
-      peer->state = DTLS_STATE_WAIT_CLIENTCERTIFICATE; //ecdhe
-    else
-      peer->state = DTLS_STATE_WAIT_CLIENTKEYEXCHANGE; //psk, ecdh_anon
-
-    /* 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;
-    }
-  }
-  /* This is a ClientHello send when doing retransmission */
-  if (peer && hs_header->msg_type == DTLS_HT_CLIENT_HELLO &&
-              dtls_uint16_to_int(hs_header->message_seq) == 0) {
-     res = dtls_verify_peer(ctx, peer, session, state, data, data_length);
-     if (res < 0) {
-       dtls_warn("error in dtls_verify_peer err: %i\n", res);
-     }
-     if (res > 0) {
-       dtls_debug("server hello verify was sent\n");
-     }
-     return res;
-  }
-
-  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;
-
-  /* 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);
-
-  handshake = peer->handshake_params;
-  /* 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_clear_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 {
-         if (DTLS_CT_HANDSHAKE == msg[0] && DTLS_STATE_WAIT_FINISHED == peer->state) {
-           int err =  dtls_alert_fatal_create(DTLS_ALERT_DECRYPT_ERROR);
-           dtls_info("decrypt_verify() failed\n");
-
-           dtls_alert_send_from_err(ctx, peer, &peer->session, err);
-
-           (void)CALL(ctx, event, &peer->session,
-                   DTLS_ALERT_LEVEL_FATAL, DTLS_ALERT_HANDSHAKE_FAILURE);
-           peer->state = DTLS_STATE_CLOSED;
-                 /* dtls_clear_retransmission(ctx, peer); */
-           dtls_destroy_peer(ctx, peer, 1);
-           return err;
-         } else {
-           data = msg + DTLS_RH_LENGTH;
-           data_length = rlen - DTLS_RH_LENGTH;
-           role = peer->role;
-           state = peer->state;
-         }
-       }
-      } 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:
-      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);
-        if (peer) {
-         (void)CALL(ctx, event, &peer->session,
-                DTLS_ALERT_LEVEL_FATAL, DTLS_ALERT_HANDSHAKE_FAILURE);
-
-         /* invalidate peer */
-         dtls_clear_retransmission(ctx, peer);
-         dtls_destroy_peer(ctx, peer, 1);
-         peer = NULL;
-        }
-       return err;
-      }
-      break;
-
-    case DTLS_CT_ALERT:
-      if (peer) {
-        dtls_clear_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) {
-
-             /* Handle the client's last flight retransmission when the server's
-              * Finished message is lost. This avoids deadlock. */
-       if (DTLS_SERVER == role && DTLS_STATE_CONNECTED == state) {
-         dtls_start_retransmission(ctx, peer);
-         break;
-       }
-       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);
-
-      if (peer) {
-        (void)CALL(ctx, event, &peer->session,
-              DTLS_ALERT_LEVEL_FATAL, DTLS_ALERT_HANDSHAKE_FAILURE);
-        dtls_clear_retransmission(ctx, peer);
-        dtls_destroy_peer(ctx, peer, 1);
-      }
-
-       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_clear_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;
-#if defined(_WIN32)
-  unsigned int randValue;
-  errno_t err;
-#endif
-#if !defined(WITH_CONTIKI) && !defined(_WIN32)
-  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);
-#elif defined(_WIN32)
-  err = rand_s(&randValue);
-  if (err != 0)
-  {
-    dtls_emerg("cannot initialize PRNG\n");
-    return NULL;
-  }
-  dtls_prng_init(randValue);
-#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");
-    fclose(urandom);
-    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_clear_retransmission(ctx, p);
-      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++;
-      if (node->t == 1) {
-        node->t = 0;
-      } else {
-        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)) {
-      node->t = 0;
-    }
-    node = list_item_next(node);
-  }
-}
-
-static void
-dtls_start_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)) {
-      node->retransmit_cnt = 0;
-      node->t = 1;
-    }
-    node = list_item_next(node);
-  }
-}
-
-static void
-dtls_clear_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) {
-    if (node->t && node->t <= now){
-      netq_pop_first(context->sendqueue);
-      dtls_retransmit(context, node);
-      node = netq_head(context->sendqueue);
-    } else {
-      node = list_item_next(node);
-    }
-  }
-}
-
-size_t
-dtls_prf_with_current_keyblock(dtls_context_t *ctx, session_t *session,
-                               const uint8_t* label, const uint32_t labellen,
-                               const uint8_t* random1, const uint32_t random1len,
-                               const uint8_t* random2, const uint32_t random2len,
-                               uint8_t* buf, const uint32_t buflen) {
-  dtls_peer_t *peer = NULL;
-  dtls_security_parameters_t *security = NULL;
-  size_t keysize = 0;
-
-  if(!ctx || !session || !label || !buf || labellen == 0 || buflen == 0) {
-    dtls_warn("dtls_prf_with_current_keyblock(): invalid parameter\n");
-    return 0;
-  }
-
-  peer = dtls_get_peer(ctx, session);
-  if (!peer) {
-    dtls_warn("dtls_prf_with_current_keyblock(): cannot find peer\n");
-    return 0;
-  }
-
-  security = dtls_security_params(peer);
-  if (!security) {
-    dtls_crit("dtls_prf_with_current_keyblock(): peer has empty security parameters\n");
-    return 0;
-  }
-
-  /* note that keysize should never be zero as bad things will happen */
-  keysize = dtls_kb_size(security, peer->role);
-  assert(keysize > 0);
-
-  return dtls_prf(security->key_block, keysize,
-                 label, labellen,
-                 random1, random1len,
-                 random2, random2len,
-                 buf, buflen);
-}
-
-#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
deleted file mode 100644 (file)
index 471943f..0000000
+++ /dev/null
@@ -1,909 +0,0 @@
-/* dtls -- a very basic DTLS implementation
- *
- * Copyright (C) 2011--2013 Olaf Bergmann <bergmann@tzi.org>
- * Copyright (C) 2013 Hauke Mehrtens <hauke@hauke-m.de>
- *
- * 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 <stdint.h>
-
-#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
-
-#ifdef DTLS_X509
-#define DTLS_MAX_CERT_SIZE       1400
-#endif
-
-typedef enum dtls_credentials_type_t {
-  DTLS_PSK_HINT, DTLS_PSK_IDENTITY, DTLS_PSK_KEY
-} dtls_credentials_type_t;
-
-typedef struct dtls_ecc_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_ecc_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_ecc_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
-   * considered 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 */
-#ifdef DTLS_X509
-  /**
-   * 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 X.509
-   * 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_x509_key)(struct dtls_context_t *ctx,
-               const session_t *session,
-               const dtls_ecc_key_t **result);
-  /**
-   * Called during handshake to get the server's or client's
-   * certificate used to authenticate this server or client in this
-   * session. If found, the certificate must be stored in @p cert and
-   * the return value must be @c 0. If not found, @p cert is
-   * undefined and the return value must be less than zero.
-   *
-   * If X.509 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 X.509
-   * 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 certificate will be used.
-   * @param cert      Must be set to the certificate object to used for
-   *                  the given session.
-   * @param cert_size Size of certificate in bytes.
-   * @return @c 0 if result is set, or less than zero on error.
-   */
-  int (*get_x509_cert)(struct dtls_context_t *ctx,
-                       const session_t *session,
-                       const unsigned char **cert,
-                       size_t *cert_size);
-
-  /**
-   * Called during handshake to check the peer's certificate in this
-   * session. If the certificate matches the session and is valid the
-   * return value must be @c 0. If not valid, the return value must be
-   * less than zero.
-   *
-   * If X.509 should not be supported, set this pointer to NULL.
-   *
-   * Implement this if you want to verify the other peers certificate.
-   * This is mandatory for a DTLS client doing based X.509
-   * 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 cert      Peer's certificate to check.
-   * @param cert_size Size of certificate in bytes.
-   * @param x         Allocated memory to store peer's public key part x.
-   * @param x_size    Size of allocated memory to store peer's public key part x.
-   * @param y         Allocated memory to store peer's public key part y.
-   * @param y_size    Size of allocated memory to store peer's public key part y.
-   * @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_x509_cert)(struct dtls_context_t *ctx,
-                          const session_t *session,
-                          const unsigned char *cert,
-                          size_t cert_size,
-               unsigned char *x,
-                          size_t x_size,
-               unsigned char *y,
-                          size_t y_size);
-
-  /**
-   * Called during handshake to check if certificate format should be X.509
-   *
-   * If X.509 should not be supported, set this pointer to NULL.
-   *
-   * @param ctx       The current dtls context.
-   * @return @c 0 if certificate format should be X.509, or less than zero on error.
-   */
-  int (*is_x509_active)(struct dtls_context_t *ctx);
-#endif /* DTLS_X509 */
-
-} 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 */
-
-  dtls_cipher_enable_t is_anon_ecdh_eabled;    /**< enable/disable the TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256 */
-
-  dtls_cipher_t selected_cipher; /**< selected ciper suite for handshake */
-
-  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. */
-INLINE_API void dtls_set_handler(dtls_context_t *ctx, dtls_handler_t *h) {
-  ctx->h = h;
-}
-
- /**
-  * @brief Enabling the TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256
-  *
-  * @param ctx              The DTLS context to use.
-  * @param is_enable    DTLS_CIPHER_ENABLE(1) or DTLS_CIPHER_DISABLE(0)
-  */
-void dtls_enables_anon_ecdh(dtls_context_t* ctx, dtls_cipher_enable_t is_enable);
-
-/**
- * @brief Select the cipher suite for handshake
- *
- * @param ctx              The DTLS context to use.
- * @param cipher         TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256 (0xC018)
- *                                  TLS_PSK_WITH_AES_128_CCM_8 (0xX0A8)
- *                                  TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 (0xC0AE)
- */
-void dtls_select_cipher(dtls_context_t* ctx, const dtls_cipher_t cipher);
-
-/**
- * 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
-
-#if defined(_MSC_VER)
-#define PACKED_STRUCT_START __pragma(pack(push,1)); typedef struct
-#define PACKED_STRUCT_END   __pragma(pack(pop))
-#else
-#define PACKED_STRUCT_START typedef struct __attribute__((__packed__))
-#define PACKED_STRUCT_END
-#endif
-
-/** Generic header structure of the DTLS record layer. */
-PACKED_STRUCT_START {
-  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;
-PACKED_STRUCT_END;
-
-/* 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. */
-PACKED_STRUCT_START {
-  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;
-PACKED_STRUCT_END;
-
-/** Structure of the Client Hello message. */
-PACKED_STRUCT_START {
-  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;
-PACKED_STRUCT_END;
-
-/** Structure of the Hello Verify Request. */
-PACKED_STRUCT_START {
-  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;  
-PACKED_STRUCT_END;
-
-#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);
-
-/**
-* Invokes the DTLS PRF using the current key block for @p session as
-* key and @p label + @p random1 + @p random2 as its input. This function
-* writes upto @p buflen bytes into the given output buffer @p buf.
-*
-* @param ctx The dtls context to use.
-* @param session The session whose key shall be used.
-* @param label A PRF label.
-* @param labellen Actual length of @p label.
-* @param random1 Random seed.
-* @param random1len Actual length of @p random1 (may be zero).
-* @param random2 Random seed.
-* @param random2len Actual length of @p random2 (may be zero).
-* @param buf Output buffer for generated random data.
-* @param buflen Maximum size of @p buf.
-*
-* @return The actual number of bytes written to @p buf or @c 0 on error.
-*/
-size_t dtls_prf_with_current_keyblock(dtls_context_t *ctx, session_t *session,
-                                      const uint8_t* label, const uint32_t labellen,
-                                      const uint8_t* random1, const uint32_t random1len,
-                                      const uint8_t* random2, const uint32_t random2len,
-                                      uint8_t* buf, const uint32_t buflen);
-
-
-#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 <a 
- * href="http://www.opensource.org/licenses/mit-license.php">MIT License</a>.
- * 
- * @subsection uthash UTHash
- *
- * This library uses <a href="http://uthash.sourceforge.net/">uthash</a> to manage
- * its peers (not used for Contiki). @b uthash uses the <b>BSD revised license</b>, see
- * <a href="http://uthash.sourceforge.net/license.html">http://uthash.sourceforge.net/license.html</a>.
- *
- * @subsection sha256 Aaron D. Gifford's SHA256 Implementation
- *
- * tinyDTLS provides HMAC-SHA256 with BSD-licensed code from Aaron D. Gifford, 
- * see <a href="http://www.aarongifford.com/">www.aarongifford.com</a>.
- *
- * @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 <a 
- * href="http://www.openbsd.org/cgi-bin/cvsweb/src/sys/crypto/rijndael.c">rijndael.c</a> 
- * for License info.
- *
- * @section download Getting the Files
- *
- * You can get the sources either from the <a 
- * href="http://sourceforge.net/projects/tinydtls/files">downloads</a> section or 
- * through git from the <a 
- * href="http://sourceforge.net/projects/tinydtls/develop">project develop page</a>.
- *
- * @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
deleted file mode 100644 (file)
index 5e0103a..0000000
+++ /dev/null
@@ -1,241 +0,0 @@
-/* dtls_config.h.  Generated from dtls_config.h.in by configure.  */
-/* tinydtls -- a very basic DTLS implementation
- *
- * Copyright (C) 2011--2014 Olaf Bergmann <bergmann@tzi.org>
- * Copyright (C) 2013 Hauke Mehrtens <hauke@hauke-m.de>
- *
- * 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 if building universal (internal helper macro) */
-/* #undef AC_APPLE_UNIVERSAL_BUILD */
-
-/* Define to 1 if building with X.509 support */
-#define DTLS_X509 1
-
-/* Define to 1 if you have the <arpa/inet.h> header file. */
-#ifndef _WIN32
-#define HAVE_ARPA_INET_H 1
-#endif
-
-/* Define to 1 if you have the <assert.h> header file. */
-#define HAVE_ASSERT_H 1
-
-/* Define to 1 if you have the <fcntl.h> header file. */
-#define HAVE_FCNTL_H 1
-
-/* Define to 1 if you have the `fls' function. */
-/* #undef HAVE_FLS */
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_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 <memory.h> 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 <netdb.h> header file. */
-#ifndef _WIN32
-#define HAVE_NETDB_H 1
-#endif
-
-/* Define to 1 if you have the <netinet/in.h> header file. */
-#ifndef _WIN32
-#define HAVE_NETINET_IN_H 1
-#endif
-
-/* Define to 1 if you have the `select' function. */
-#define HAVE_SELECT 1
-
-/* 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. */
-#define HAVE_SOCKET 1
-
-/* Define to 1 if you have the <stddef.h> header file. */
-#define HAVE_STDDEF_H 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> 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 <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> 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 <sys/param.h> header file. */
-#define HAVE_SYS_PARAM_H 1
-
-/* Define to 1 if you have the <sys/socket.h> header file. */
-#ifndef _WIN32
-#define HAVE_SYS_SOCKET_H 1
-#endif
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/time.h> header file. */
-#ifndef _WIN32
-#define HAVE_SYS_TIME_H 1
-#endif
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <time.h> header file. */
-#define HAVE_TIME_H 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_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 <sys/types.h> does not define. */
-
-/* #undef size_t */
-#if defined(_MSC_VER) && (_MSC_VER < 1900)
-#define ssize_t SSIZE_T
-#define snprintf vs12_snprintf
-#endif
-#if defined(_WIN32)
-#define MSG_DONTWAIT 0
-#define HAVE_WINSOCK2_H 1
-#define HAVE_WS2TCPIP_H 1
-#endif
-
-/************************************************************************/
-/* 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
deleted file mode 100644 (file)
index adc8dc5..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-/* tinydtls -- a very basic DTLS implementation
- *
- * Copyright (C) 2011--2014 Olaf Bergmann <bergmann@tzi.org>
- * Copyright (C) 2013 Hauke Mehrtens <hauke@hauke-m.de>
- *
- * 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 building with X.509 support */
-#undef DTLS_X509
-
-/* Define to 1 if you have the <arpa/inet.h> header file. */
-#undef HAVE_ARPA_INET_H
-
-/* Define to 1 if you have the <assert.h> header file. */
-#undef HAVE_ASSERT_H
-
-/* Define to 1 if you have the <fcntl.h> 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 <inttypes.h> 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 <memory.h> 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 <netdb.h> header file. */
-#undef HAVE_NETDB_H
-
-/* Define to 1 if you have the <netinet/in.h> 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 <stddef.h> header file. */
-#undef HAVE_STDDEF_H
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#undef HAVE_STDINT_H
-
-/* Define to 1 if you have the <stdlib.h> 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 <strings.h> header file. */
-#undef HAVE_STRINGS_H
-
-/* Define to 1 if you have the <string.h> 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 <sys/param.h> header file. */
-#undef HAVE_SYS_PARAM_H
-
-/* Define to 1 if you have the <sys/socket.h> header file. */
-#undef HAVE_SYS_SOCKET_H
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#undef HAVE_SYS_STAT_H
-
-/* Define to 1 if you have the <sys/time.h> header file. */
-#undef HAVE_SYS_TIME_H
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#undef HAVE_SYS_TYPES_H
-
-/* Define to 1 if you have the <time.h> header file. */
-#undef HAVE_TIME_H
-
-/* Define to 1 if you have the <unistd.h> 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 <sys/types.h> 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_hal.h b/extlibs/tinydtls/dtls_hal.h
deleted file mode 100644 (file)
index c2ea91f..0000000
+++ /dev/null
@@ -1,211 +0,0 @@
-/* 
-Copyright (c) 2015 Atmel Corporation. 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 Atmel nor the names of its contributors may be used to 
-endorse or promote products derived from this software without specific 
-prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
-IN NO EVENT SHALL THE COPYRIGHT 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.
- */
-
-/**
- * @file dtls_hal.h
- * @brief DTLS Hardware Abstraction Layer API and visible structures. 
- */
-
-#ifndef _DTLS_DTLS_HAL_H_
-#define _DTLS_DTLS_HAL_H_
-
-#include <stdint.h>
-#include <stdbool.h>
-
-// Define return values for HAL
-#define HAL_SUCCESS (1)
-#define HAL_FAILURE (0)
-#define ENC_KEY_SIZE (32)
-
-/**
- * This structure contains callback functions used by tinydtls to
- * provide a hardware abstraction layer for secure storage . 
- */
-typedef struct {
-
-  /**
-   * Call this function during application initialization to create HAL related resources.
-   *
-   * @param[in] ctx  The current DTLS context.
-   * @return HAL_SUCCESS or HAL_FAILURE
-   */
-  int (*HAL_init)(struct dtls_context_t *ctx);
-
-  /**
-   * Call this function during application shut down to clean up any HAL related resources.
-   *
-   * @param[in] ctx  The current DTLS context.
-   * @return HAL_SUCCESS or HAL_FAILURE
-   */
-  int (*HAL_finish)(struct dtls_context_t *ctx);
-
-  /**
-   * Call this function to store unsecured data on hardware.
-   *
-   * @param[in] ctx  The current DTLS context.
-   * @param[in] p_location_handle  The handle to the hardware location to store p_data.
-   * @param[in] p_data  The data to store.
-   * @param[in] data_size  The size of the data to store.
-   * @return HAL_SUCCESS or HAL_FAILURE
-   */
-  int (*HAL_write_mem)(struct dtls_context_t *ctx,
-                       const uint8_t* p_location,
-                       const uint8_t* p_data,
-                       size_t data_size);
-
-  /**
-   * Call this function to read data from unsecured storage from hardware.
-   *
-   * @param[in] ctx  The current DTLS context.
-   * @param[in] p_location_handle  The handle to the hardware location to read p_data.
-   * @param[in] p_data  The data to read.
-   * @param[inout] data_size  IN: The size of the buffer to receive data.  OUT: The actual number of bytes read.
-   * @return HAL_SUCCESS or HAL_FAILURE
-   */
-  int (*HAL_read_mem)(struct dtls_context_t *ctx,
-                      const uint8_t* p_location,
-                      uint8_t* p_data,
-                      size_t* dataSize);
-
-  /**
-   * Call this function to store sensitive data in secure hardware.
-   * Data will be securely stored and encrypted on the wire
-   *
-   * @param[in] ctx  The current DTLS context.
-   * @param[in] p_location_handle  The handle to the hardware location to store p_data.
-   * @param[in] p_data  The data to store securely.
-   * @param[in] data_size  The size of the data to store securely.
-   * @return HAL_SUCCESS or HAL_FAILURE
-   */
-  int (*HAL_write_mem_enc)(struct dtls_context_t *ctx,
-                           const uint8_t* p_location,
-                           const uint8_t* p_data,
-                           size_t data_size);
-
-  /**
-   * Call this function to read sensitive data from secure hardware.
-   * Data will be read from secure storage and encrypted on the wire
-   *
-   * @param[in] ctx  The current DTLS context.
-   * @param[in] p_location_handle  The handle to the hardware location to read p_data.
-   * @param[in] p_data  The data to read securely.
-   * @param[inout] data_size  IN: The size of the buffer to receive data.  OUT: The actual number of bytes read.
-   * @return HAL_SUCCESS or HAL_FAILURE
-   */
-  int (*HAL_read_mem_enc)(struct dtls_context_t *ctx,
-                          const uint8_t* p_location,
-                          uint8_t* p_data,
-                          size_t* dataSize);
-
-  /**
-   * Call this function to generate a unique encryption key that will be used for secure storage.
-   * This encryption key should be stored as a platform resource
-   *
-   * @param[in] ctx  The current DTLS context.
-   * @param[out] p_enc_key_out  The internally generated unique encryption key that will be used for secure storage.
-   *    This key needs to be stored on the platform.
-   * @return HAL_SUCCESS or HAL_FAILURE
-   */
-  int (*HAL_init_enckey)(struct dtls_context_t *ctx,
-                         uint8_t p_enc_key_out[ENC_KEY_SIZE]);
-
-  /**
-   * Call this function to set a unique encryption key that will be used for secure storage.
-   * This encryption key should be stored as a platform resource
-   *
-   * @param[in] ctx  The current DTLS context.
-   * @param[in] p_enc_key_in  The encryption key that will be used for secure storage.
-   *    This key needs to be stored on the platform.
-   * @return HAL_SUCCESS or HAL_FAILURE
-   */
-  int (*HAL_set_enckey)(struct dtls_context_t *ctx,
-                        const uint8_t p_enc_key_in[ENC_KEY_SIZE]);
-
-  /**
-   * This function is called internally from HAL_read_mem_enc and HAL_write_mem_enc.
-   * The platform must implement this function to return the encryption key that was
-   *   returned by HAL_init_enckey or HAL_set_enckey.
-   *
-   * @param[in] ctx  The current DTLS context.
-   * @param[out] p_enc_key_out  The encryption key that is used for secure storage.
-   *    Retrieve from platform in this function.
-   * @return HAL_SUCCESS or HAL_FAILURE
-   */
-  int (*HAL_get_enckey)(struct dtls_context_t *ctx,
-                        uint8_t p_enc_key_out[ENC_KEY_SIZE]);
-
-  /**
-   * Call this function to use the hardware to calculate a SHA256
-   *
-   * @param[in] ctx  The current DTLS context.
-   * @param[in] p_msg  The message to calculate the SHA256.
-   * @param[in] msg_size  The size of the message to hash.
-   * @param[out] p_hash  The hash of p_msg.
-   * @return HAL_SUCCESS or HAL_FAILURE
-   */
-  int (*HAL_sha2_calc)(struct dtls_context_t *ctx,
-                       uint8_t *p_msg,
-                       size_t msg_size,
-                       uint8_t p_hash[SHA256_DIGEST_LENGTH]);
-
-  /**
-   * Call this function to use the hardware key derivation function (KDF)
-   *
-   * @param[in] ctx  The current DTLS context.
-   * @param[in] p_seed  The seed used to produce the key.
-   * @param[in] seed_size  The size of the message to hash.
-   * @param[out] p_keyout  The key produced by the KDF.
-   * @param[in] key_size  The size of the key to be returned.
-   * @return HAL_SUCCESS or HAL_FAILURE
-   */
-  int (*HAL_kdf_calc)(struct dtls_context_t *ctx,
-                      const uint8_t* p_seed,
-                      const size_t seed_size,
-                      uint8_t* p_keyout,
-                      const size_t key_size);
-
-  /**
-   * Call this function to retrieve the specified certificate from hardware
-   *
-   * @param[in] ctx  The current DTLS context.
-   * @param[in] cert_id  An index into the certificate to returned.
-   * @param[inout] cert  The certificate to be returned.
-   * @param[inout] cert_size  The size of the certificate.
-   * @return HAL_SUCCESS or HAL_FAILURE
-   */
-  int (*HAL_get_x509_cert)(struct dtls_context_t *ctx,
-                           uint32_t cert_ref,
-                           uint8_t **cert,
-                           size_t *cert_size);
-
-} dtls_hal_handler_t;
-
-
-#endif /* _DTLS_DTLS_HAL_H_ */
-
diff --git a/extlibs/tinydtls/dtls_time.c b/extlibs/tinydtls/dtls_time.c
deleted file mode 100644 (file)
index 39a1c8d..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/* dtls -- a very basic DTLS implementation
- *
- * Copyright (C) 2011--2013 Olaf Bergmann <bergmann@tzi.org>
- *
- * 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 */
-#ifdef _WIN32
-#include <windows.h>
-#endif
-
-time_t dtls_clock_offset;
-
-void
-dtls_clock_init(void) {
-#ifdef _WIN32
-  /* Use clock offset in milliseconds */
-  dtls_clock_offset = GetTickCount64();
-#else
-#ifdef HAVE_TIME_H
-  /* Use clock offset in seconds */
-  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
-#endif
-}
-
-void dtls_ticks(dtls_tick_t *t) {
-#ifdef _WIN32
-  *t = ((GetTickCount64() - dtls_clock_offset) * DTLS_TICKS_PER_SECOND / 1000);
-#else
-#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
-}
-
-#endif /* WITH_CONTIKI */
-
-
diff --git a/extlibs/tinydtls/dtls_time.h b/extlibs/tinydtls/dtls_time.h
deleted file mode 100644 (file)
index 6541b1c..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/* dtls -- a very basic DTLS implementation
- *
- * Copyright (C) 2011--2013 Olaf Bergmann <bergmann@tzi.org>
- *
- * 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 <stdint.h>
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-
-#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 <time.h>
-
-#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
deleted file mode 100644 (file)
index ab099ae..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-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
deleted file mode 100755 (executable)
index 7787d2d..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-CONTIKI=../../..
-
-APPS += ecc
-
-CFLAGS += -DTEST_INCLUDE
-
-include $(CONTIKI)/Makefile.include
diff --git a/extlibs/tinydtls/ecc/Makefile.ecc b/extlibs/tinydtls/ecc/Makefile.ecc
deleted file mode 100755 (executable)
index 382e48f..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# 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
deleted file mode 100644 (file)
index 2a38603..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-# Makefile for tinydtls
-#
-# Copyright (C) 2011 Olaf Bergmann <bergmann@tzi.org>
-# Copyright (C) 2013 Hauke Mehrtens <hauke@hauke-m.de>
-#
-# 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
deleted file mode 100644 (file)
index 24f1231..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-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\_&lt;arch&gt;\_.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.
-
-<table>
-       <tr>
-               <th></th>
-               <th>secp160r1</th>
-               <th>secp192r1</th>
-               <th>secp256r1</th>
-               <th>secp256k1</th>
-       </tr>
-       <tr>
-               <td><em>ECDH:</em></td>
-               <td>2.3</td>
-               <td>2.7</td>
-               <td>7.9</td>
-               <td>6.5</td>
-       </tr>
-       <tr>
-               <td><em>ECDSA sign:</em></td>
-               <td>2.8</td>
-               <td>3.1</td>
-               <td>8.6</td>
-               <td>7.2</td>
-       </tr>
-       <tr>
-               <td><em>ECDSA verify:</em></td>
-               <td>2.7</td>
-               <td>3.2</td>
-               <td>9.2</td>
-               <td>7.0</td>
-       </tr>
-</table>
-
-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.
-
-<table>
-       <tr>
-               <th></th>
-               <th>secp160r1</th>
-               <th>secp192r1</th>
-               <th>secp256r1</th>
-               <th>secp256k1</th>
-       </tr>
-       <tr>
-               <td><em>ECDH time (ms):</em></td>
-               <td>470</td>
-               <td>810</td>
-               <td>2220</td>
-               <td>1615</td>
-       </tr>
-       <tr>
-               <td><em>Code size (bytes):</em></td>
-               <td>10768</td>
-               <td>13112</td>
-               <td>20886</td>
-               <td>21126</td>
-       </tr>
-</table>
-
-#### ECDH (small) ####
-
-In these tests, `uECC_ASM` was defined to `uECC_asm_small` and `ECC_SQUARE_FUNC` was defined to `0` in all cases.
-
-<table>
-       <tr>
-               <th></th>
-               <th>secp160r1</th>
-               <th>secp192r1</th>
-               <th>secp256r1</th>
-               <th>secp256k1</th>
-       </tr>
-       <tr>
-               <td><em>ECDH time (ms):</em></td>
-               <td>1250</td>
-               <td>1810</td>
-               <td>4790</td>
-               <td>4700</td>
-       </tr>
-       <tr>
-               <td><em>Code size (bytes):</em></td>
-               <td>3244</td>
-               <td>3400</td>
-               <td>5274</td>
-               <td>3426</td>
-       </tr>
-</table>
-
-#### ECDSA (fast) ####
-
-In these tests, `uECC_ASM` was defined to `uECC_asm_fast` and `ECC_SQUARE_FUNC` was defined to `1` in all cases.
-
-<table>
-       <tr>
-               <th></th>
-               <th>secp160r1</th>
-               <th>secp192r1</th>
-               <th>secp256r1</th>
-               <th>secp256k1</th>
-       </tr>
-       <tr>
-               <td><em>ECDSA sign time (ms):</em></td>
-               <td>555</td>
-               <td>902</td>
-               <td>2386</td>
-               <td>1773</td>
-       </tr>
-       <tr>
-               <td><em>ECDSA verify time (ms):</em></td>
-               <td>590</td>
-               <td>990</td>
-               <td>2650</td>
-               <td>1800</td>
-       </tr>
-       <tr>
-               <td><em>Code size (bytes):</em></td>
-               <td>13246</td>
-               <td>14798</td>
-               <td>22594</td>
-               <td>22826</td>
-       </tr>
-</table>
-
-#### ECDSA (small) ####
-
-In these tests, `uECC_ASM` was defined to `uECC_asm_small` and `ECC_SQUARE_FUNC` was defined to `0` in all cases.
-
-<table>
-       <tr>
-               <th></th>
-               <th>secp160r1</th>
-               <th>secp192r1</th>
-               <th>secp256r1</th>
-               <th>secp256k1</th>
-       </tr>
-       <tr>
-               <td><em>ECDSA sign time (ms):</em></td>
-               <td>1359</td>
-               <td>1931</td>
-               <td>4998</td>
-               <td>4904</td>
-       </tr>
-       <tr>
-               <td><em>ECDSA verify time (ms):</em></td>
-               <td>1515</td>
-               <td>2160</td>
-               <td>5700</td>
-               <td>5220</td>
-       </tr>
-       <tr>
-               <td><em>Code size (bytes):</em></td>
-               <td>5690</td>
-               <td>5054</td>
-               <td>6980</td>
-               <td>5080</td>
-       </tr>
-</table>
diff --git a/extlibs/tinydtls/ecc/asm_arm.inc b/extlibs/tinydtls/ecc/asm_arm.inc
deleted file mode 100755 (executable)
index f181b17..0000000
+++ /dev/null
@@ -1,1905 +0,0 @@
-#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
deleted file mode 100755 (executable)
index a945e52..0000000
+++ /dev/null
@@ -1,16276 +0,0 @@
-#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
deleted file mode 100644 (file)
index 4c2b532..0000000
+++ /dev/null
@@ -1,2474 +0,0 @@
-/* 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
-// Function declarations to support the HAL shims
-int uECC_make_key_impl(uint8_t p_publicKey[uECC_BYTES*2], uint8_t p_privateKey[uECC_BYTES]);
-int uECC_shared_secret_impl(const uint8_t p_publicKey[uECC_BYTES*2], const uint8_t p_privateKey[uECC_BYTES], uint8_t p_secret[uECC_BYTES]);
-int uECC_sign_impl(const uint8_t p_privateKey[uECC_BYTES], const uint8_t p_hash[uECC_BYTES], uint8_t p_signature[uECC_BYTES*2]);
-int uECC_verify_impl(const uint8_t p_publicKey[uECC_BYTES*2], const uint8_t p_hash[uECC_BYTES], const uint8_t p_signature[uECC_BYTES*2]);
-int uECC_ecdhe_impl(const uint8_t p_public_key_in[uECC_BYTES*2], uint8_t p_public_key_out[uECC_BYTES*2], uint8_t p_secret[uECC_BYTES]);
-int uECC_get_pubkey_impl(const uint8_t p_key_handle[uECC_BYTES], uint8_t p_public_key[uECC_BYTES*2]);
-
-#if (defined(_WIN32) || defined(_WIN64))
-/* Windows */
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <bcrypt.h>
-
-static int default_RNG(uint8_t *p_dest, unsigned p_size)
-{
-    if (!BCRYPT_SUCCESS(BCryptGenRandom(NULL, (PUCHAR)p_dest, p_size, BCRYPT_USE_SYSTEM_PREFERRED_RNG)))
-    {
-        return 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 <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#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
-
-///////////////////////////////////////////////////////
-// Functions to set the callbacks for crypto operations
-static uECC_RNG_Function g_rng = &default_RNG;
-
-void uECC_set_rng(uECC_RNG_Function p_rng)
-{
-    g_rng = p_rng;
-}
-
-static uECC_make_key_Function g_make_key_cb = &uECC_make_key_impl;
-
-void uECC_set_make_key_cb(uECC_make_key_Function p_make_key_cb)
-{
-    g_make_key_cb = p_make_key_cb;
-}
-
-static uECC_shared_secret_Function g_shared_secret_cb = &uECC_shared_secret_impl;
-
-void uECC_set_shared_secret_cb(uECC_shared_secret_Function p_shared_secret_cb)
-{
-    g_shared_secret_cb = p_shared_secret_cb;
-}
-
-static uECC_sign_Function g_sign_cb = &uECC_sign_impl;
-
-void uECC_set_sign_cb(uECC_sign_Function p_sign_cb)
-{
-    g_sign_cb = p_sign_cb;
-}
-
-static uECC_verify_Function g_verify_cb = &uECC_verify_impl;
-
-void uECC_set_verify_cb(uECC_verify_Function p_verify_cb)
-{
-       g_verify_cb = p_verify_cb;
-}
-
-static uECC_ecdhe_Function g_ecdhe_cb = &uECC_ecdhe_impl;
-
-void uECC_set_ecdhe_cb(uECC_ecdhe_Function p_ecdhe_cb)
-{
-       g_ecdhe_cb = p_ecdhe_cb;
-}
-
-static uECC_get_pubkey_Function g_get_pubkey_cb = &uECC_get_pubkey_impl;
-
-void uECC_set_get_pubkey_cb(uECC_get_pubkey_Function p_get_pubkey_cb)
-{
-       g_get_pubkey_cb = p_get_pubkey_cb;
-}
-
-///////////////////////////////////////////////////////
-
-
-#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<uECC_WORDS; ++i)
-    {
-        p_dest[i] = p_src[i];
-    }
-}
-#endif
-
-/* Returns sign of p_left - p_right. */
-#if !asm_cmp
-static cmpresult_t vli_cmp(uECC_word_t *p_left, uECC_word_t *p_right)
-{
-    swordcount_t i;
-    for(i = uECC_WORDS-1; 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<uECC_WORDS; ++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_WORDS*2 - 1] = r0;
-}
-#endif
-
-#if uECC_SQUARE_FUNC
-
-#if !asm_square
-static void mul2add(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);
-
-    *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<uECC_BYTES; ++i)
-    {
-        p_dest[i] = p_src[(uECC_BYTES - 1) - i];
-    }
-}
-
-#define vli_bytesToNative(dest, src) vli_nativeToBytes((dest), (src))
-
-#elif uECC_WORD_SIZE == 4
-
-static void vli_nativeToBytes(uint8_t *p_bytes, const uint32_t *p_native)
-{
-    unsigned i;
-    for(i=0; i<uECC_WORDS; ++i)
-    {
-        uint8_t *p_digit = p_bytes + 4 * (uECC_WORDS - 1 - i);
-        p_digit[0] = p_native[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<uECC_WORDS; ++i)
-    {
-        const uint8_t *p_digit = p_bytes + 4 * (uECC_WORDS - 1 - i);
-        p_native[i] = ((uint32_t)p_digit[0] << 24) | ((uint32_t)p_digit[1] << 16) | ((uint32_t)p_digit[2] << 8) | (uint32_t)p_digit[3];
-    }
-}
-
-#else
-
-static void vli_nativeToBytes(uint8_t *p_bytes, const uint64_t *p_native)
-{
-    unsigned i;
-    for(i=0; i<uECC_WORDS; ++i)
-    {
-        uint8_t *p_digit = p_bytes + 8 * (uECC_WORDS - 1 - i);
-        p_digit[0] = p_native[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<uECC_WORDS; ++i)
-    {
-        const uint8_t *p_digit = p_bytes + 8 * (uECC_WORDS - 1 - i);
-        p_native[i] = ((uint64_t)p_digit[0] << 56) | ((uint64_t)p_digit[1] << 48) | ((uint64_t)p_digit[2] << 40) | ((uint64_t)p_digit[3] << 32) |
-            ((uint64_t)p_digit[4] << 24) | ((uint64_t)p_digit[5] << 16) | ((uint64_t)p_digit[6] << 8) | (uint64_t)p_digit[7];
-    }
-}
-
-#endif /* uECC_WORD_SIZE */
-
-// Safe calls to the callback functions
-int uECC_make_key(uint8_t p_publicKey[uECC_BYTES*2], uint8_t p_privateKey[uECC_BYTES])
-{
-    // Check for a valid function pointer
-    if (g_make_key_cb != NULL)
-    {
-        return g_make_key_cb(p_publicKey, p_privateKey);
-    }
-    else
-    {
-        return uECC_make_key_impl(p_publicKey, p_privateKey);
-    }
-}
-
-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])
-{
-    // Check for a valid function pointer
-    if (g_shared_secret_cb != NULL)
-    {
-        return g_shared_secret_cb(p_publicKey, p_privateKey, p_secret);
-    }
-    else
-    {
-        return uECC_shared_secret_impl(p_publicKey, p_privateKey, p_secret);
-    }
-}
-
-int uECC_sign(const uint8_t p_privateKey[uECC_BYTES], const uint8_t p_hash[uECC_BYTES], uint8_t p_signature[uECC_BYTES*2])
-{
-    // Check for a valid function pointer
-    if (g_sign_cb != NULL)
-    {
-        return g_sign_cb(p_privateKey, p_hash, p_signature);
-    }
-    else
-    {
-        return uECC_sign_impl(p_privateKey, p_hash, p_signature);
-    }
-}
-
-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])
-{
-       // Check for a valid function pointer
-       if (g_verify_cb != NULL)
-       {
-               return g_verify_cb(p_publicKey, p_hash, p_signature);
-       }
-       else
-       {
-               return uECC_verify_impl(p_publicKey, p_hash, p_signature);
-       }
-}
-
-int uECC_ecdhe(const uint8_t p_public_key_in[uECC_BYTES*2], uint8_t p_public_key_out[uECC_BYTES*2], uint8_t p_secret[uECC_BYTES])
-{
-       // Check for a valid function pointer
-       if (g_ecdhe_cb != NULL)
-       {
-               return g_ecdhe_cb(p_public_key_in, p_public_key_out, p_secret);
-       }
-       else
-       {
-               return uECC_ecdhe_impl(p_public_key_in, p_public_key_out, p_secret);
-       }
-}
-
-int uECC_get_pubkey(const uint8_t p_key_handle[uECC_BYTES], uint8_t p_public_key[uECC_BYTES*2])
-{
-       // Check for a valid function pointer
-       if (g_get_pubkey_cb != NULL)
-       {
-               return g_get_pubkey_cb(p_key_handle, p_public_key);
-       }
-       else
-       {
-               return uECC_get_pubkey_impl(p_key_handle, p_public_key);
-       }
-}
-
-int uECC_ecdhe_impl(const uint8_t p_public_key_in[uECC_BYTES*2], uint8_t p_public_key_out[uECC_BYTES*2], uint8_t p_secret[uECC_BYTES])
-{
-       return 0;
-}
-
-int uECC_get_pubkey_impl(const uint8_t p_key_handle[uECC_BYTES], uint8_t p_public_key[uECC_BYTES*2])
-{
-       return 0;
-}
-
-int uECC_make_key_impl(uint8_t p_publicKey[uECC_BYTES*2], uint8_t p_privateKey[uECC_BYTES])
-{
-    EccPoint l_public;
-    uECC_word_t l_private[uECC_WORDS];
-    uECC_word_t l_tries = 0;
-
-    do
-    {
-    repeat:
-        if(!g_rng((uint8_t *)l_private, sizeof(l_private)) || (l_tries++ >= 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_impl(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<uECC_BYTES; ++i)
-    {
-        p_compressed[i+1] = p_publicKey[i];
-    }
-    p_compressed[0] = 2 + (p_publicKey[uECC_BYTES * 2 - 1] & 0x01);
-}
-
-void uECC_decompress(const uint8_t p_compressed[uECC_BYTES+1], uint8_t p_publicKey[uECC_BYTES*2])
-{
-    EccPoint l_point;
-    vli_bytesToNative(l_point.x, p_compressed + 1);
-
-#if (uECC_CURVE == uECC_secp256k1)
-    vli_modSquare_fast(l_point.y, l_point.x); /* r = x^2 */
-    vli_modMult_fast(l_point.y, l_point.y, l_point.x); /* r = x^3 */
-    vli_modAdd(l_point.y, l_point.y, curve_b, curve_p); /* r = x^3 + b */
-#else
-    uECC_word_t _3[uECC_WORDS] = {3}; /* -a = 3 */
-
-    vli_modSquare_fast(l_point.y, l_point.x); /* y = x^2 */
-    vli_modSub_fast(l_point.y, l_point.y, _3); /* y = x^2 - 3 */
-    vli_modMult_fast(l_point.y, l_point.y, l_point.x); /* y = x^3 - 3x */
-    vli_modAdd(l_point.y, l_point.y, curve_b, curve_p); /* y = x^3 - 3x + b */
-#endif
-
-    mod_sqrt(l_point.y);
-
-    if((l_point.y[0] & 0x01) != (p_compressed[0] & 0x01))
-    {
-        vli_sub(l_point.y, curve_p, l_point.y);
-    }
-
-    vli_nativeToBytes(p_publicKey, l_point.x);
-    vli_nativeToBytes(p_publicKey + uECC_BYTES, l_point.y);
-}
-
-/* -------- ECDSA code -------- */
-
-#if (uECC_CURVE == uECC_secp160r1)
-static void vli_clear_n(uECC_word_t *p_vli)
-{
-    vli_clear(p_vli);
-    p_vli[uECC_N_WORDS - 1] = 0;
-}
-
-static uECC_word_t vli_isZero_n(const uECC_word_t *p_vli)
-{
-    if(p_vli[uECC_N_WORDS - 1])
-    {
-        return 0;
-    }
-    return vli_isZero(p_vli);
-}
-
-static void vli_set_n(uECC_word_t *p_dest, const uECC_word_t *p_src)
-{
-    vli_set(p_dest, p_src);
-    p_dest[uECC_N_WORDS-1] = p_src[uECC_N_WORDS-1];
-}
-
-static cmpresult_t vli_cmp_n(uECC_word_t *p_left, uECC_word_t *p_right)
-{
-    if(p_left[uECC_N_WORDS-1] > 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<uECC_N_WORDS*2; ++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;
-}
-
-/* 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<uECC_WORDS*2; ++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;
-}
-
-/* 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_impl(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_impl(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
deleted file mode 100644 (file)
index dd09ce6..0000000
+++ /dev/null
@@ -1,311 +0,0 @@
-/* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */
-
-#ifndef _MICRO_ECC_H_
-#define _MICRO_ECC_H_
-
-#include <stdint.h>
-
-/* 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);
-
-//////////////////////////////////////////
-// DTLS_CRYPTO_HAL
-/**
-* Call this function to create a unique public-private key pair in secure hardware
-*
-* @param[out] p_publicKey  The public key that is associated with the private key that was just created.
-* @param[out] p_privateKeyHandle  A handle that is used to point to the private key stored in hardware.
-* @return 1 upon success, 0 if an error occurred.
-*/
-typedef int (*uECC_make_key_Function)(uint8_t p_publicKey[uECC_BYTES*2], uint8_t p_privateKeyHandle[uECC_BYTES]);
-
-/**
-* Set the callback function that will be used to generate a public-private key pair.
-* This function will replace uECC_make_key.
-*
-* @param[in] p_make_key_cb  The function that will be used to generate a public-private key pair.
-*/
-void uECC_set_make_key_cb(uECC_make_key_Function p_make_key_cb);
-
-/**
-* Call this function to sign a hash using a hardware protected private key.
-*
-* @param[in] p_privateKeyHandle  A handle that is used to point to the private key stored in hardware.
-* @param[in] p_hash  The hash to sign.
-* @param[out] p_signature  The signature that is produced in hardware by the private key..
-* @return 1 upon success, 0 if an error occurred.
-*/
-typedef int (*uECC_sign_Function)(uint8_t p_privateKeyHandle[uECC_BYTES], const uint8_t p_hash[uECC_BYTES], uint8_t p_signature[uECC_BYTES*2]);
-
-/**
-* Set the callback function that will be used to sign.
-* This function will replace uECC_sign.
-*
-* @param[in] p_sign_cb  The function that will be used to sign.
-*/
-void uECC_set_sign_cb(uECC_sign_Function p_sign_cb);
-
-/**
-* Call this function to verify a signature using the public key and hash that was signed. 
-*
-* @param[in] p_publicKey  The public key that is associated with the private key that produced the signature.
-* @param[in] p_hash  The hash that was signed.
-* @param[in] p_signature  The signature that was produced the private key that is associated with p_public_key
-* @return 1 upon success, 0 if an error occurred.
-*/
-typedef int (*uECC_verify_Function)(const uint8_t p_publicKey[uECC_BYTES*2], const uint8_t p_hash[uECC_BYTES], const uint8_t p_signature[uECC_BYTES*2]);
-
-/**
-* Set the callback function that will be used to verify.
-* This function will replace uECC_verify.
-*
-* @param[in] p_verify_cb  The function that will be used to verify.
-*/
-void uECC_set_verify_cb(uECC_verify_Function p_verify_cb);
-
-/**
-* Call this function to produce an ECDH shared key using the public key of the other node.
-* A hardware protected private key will be used for the point multiply
-*
-* @param[in] p_publicKey  The public key from the other node used for communication.
-* @param[in] p_privateKeyHandle  A handle that is used to point to the private key stored in hardware.
-* @param[out] p_secret  The pre-master key that is produced by the point multiply with p_public_key and our private key
-* @return 1 upon success, 0 if an error occurred.
-*/
-typedef int (*uECC_shared_secret_Function)(const uint8_t p_publicKey[uECC_BYTES*2], const uint8_t p_privateKeyHandle[uECC_BYTES], uint8_t p_secret[uECC_BYTES]);
-
-/**
-* Set the callback function that will be used to produce a shared secret.
-* This function will replace uECC_shared_secret.
-*
-* @param[in] p_make_key_cb  The function that will be used to generate the shared secret.
-*/
-void uECC_set_shared_secret_cb(uECC_shared_secret_Function p_shared_secret_cb);
-
-/**
-* Call this function to produce a shared key using the public key of the other node.
-* An ephemeral private key will be created in secure hardware that will be used for the point multiply
-*
-* @param[in] p_public_key  The public key from the other node used for communication.
-* @param[out] p_public_key_out  The ephemeral public key that will be used in the point multiply.
-* @param[out] p_secret  The pre-master key that is produced by the point multiply with p_public_key and our private key
-* @return 1 upon success, 0 if an error occurred.
-*/
-typedef int (*uECC_ecdhe_Function)(const uint8_t p_public_key_in[uECC_BYTES*2],
-                                   uint8_t p_public_key_out[uECC_BYTES*2],
-                                   uint8_t p_secret[uECC_BYTES]);
-
-/**
-* Set the callback function that will be used to produce a ECDHE shared secret.
-*
-* @param[in] p_ecdhe_cb  The function that will be used to generate the ECDHE shared secret.
-*/
-void uECC_set_ecdhe_cb(uECC_ecdhe_Function p_ecdhe_cb);
-
-/**
-* Call this function to return the public key for an existing private key.
-*
-* @param[out] p_key_handle  A handle that is used to point to the private key stored in hardware.
-*    The public key that is associated with this private key will be returned
-* @param[out] p_public_key  The public key that is associated with the private key that was just created.
-* @return 1 upon success, 0 if an error occurred.
-*/
-typedef int (*uECC_get_pubkey_Function)(const uint8_t p_key_handle[uECC_BYTES],
-                                        uint8_t p_public_key[uECC_BYTES*2]);
-
-/**
-* Set the callback function that will be used to return the public key for an existing private key.
-*
-* @param[in] p_get_pubkey_cb  The function that will be used to return the public key for an existing private key.
-*/
-void uECC_set_get_pubkey_cb(uECC_get_pubkey_Function p_get_pubkey_cb);
-
-
-/**
-* Call this function to produce a shared key using the public key of the other node.
-* An ephemeral private key will be created that will be used for the point multiply
-*
-* @param[in] p_public_key  The public key from the other node used for communication.
-* @param[out] p_public_key_out  The ephemeral public key that will be used in the point multiply.
-* @param[out] p_secret  The pre-master key that is produced by the point multiply with p_public_key and our private key
-* @return 1 upon success, 0 if an error occurred.
-*/
-int uECC_ecdhe(const uint8_t p_public_key_in[uECC_BYTES*2],
-               uint8_t p_public_key_out[uECC_BYTES*2],
-               uint8_t p_secret[uECC_BYTES]);
-
-/**
-* Call this function to return the public key for an existing private key.
-*
-* @param[out] p_key_handle  A handle that is used to point to the private key stored in hardware.
-*    The public key that is associated with this private key will be returned
-* @param[out] p_public_key  The public key that is associated with the private key that was just created.
-* @return 1 upon success, 0 if an error occurred.
-*/
-int uECC_get_pubkey(const uint8_t p_key_handle[uECC_BYTES],
-                    uint8_t p_public_key[uECC_BYTES*2]);
-
-//////////////////////////////////////////
-
-
-/* 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
deleted file mode 100755 (executable)
index 04c5e4a..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-#include <uECC.h>
-
-#include <j0g.h>
-#include <js0n.h>
-
-#include <lwm.h>
-
-#include <bitlash.h>
-
-#include <GS.h>
-
-#include <SPI.h>
-#include <Wire.h>
-#include <Scout.h>
-#include <Shell.h>
-
-
-#include <uECC.h>
-
-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
deleted file mode 100755 (executable)
index 956ccf5..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-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
deleted file mode 100644 (file)
index cef274d..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */
-
-#include "../ecc.h"
-
-#include <stdio.h>
-#include <string.h>
-
-#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
deleted file mode 100644 (file)
index f3983bb..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */
-
-#include "../ecc.h"
-
-#include <stdio.h>
-#include <string.h>
-
-#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/examples/contiki/Makefile.in b/extlibs/tinydtls/examples/contiki/Makefile.in
deleted file mode 100644 (file)
index 770f220..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-########################################################################
-# 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
deleted file mode 100644 (file)
index b1af669..0000000
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the 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 <string.h>
-
-#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
deleted file mode 100644 (file)
index d9269a8..0000000
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the 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 <string.h>
-
-#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
deleted file mode 100644 (file)
index 8f947e7..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-/* dtls -- a very basic DTLS implementation
- *
- * Copyright (C) 2011--2014 Olaf Bergmann <bergmann@tzi.org>
- *
- * 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 <stdlib.h>
-#include <sys/types.h>
-
-#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
-#if defined(DTLS_ECC) || defined(DTLS_X509)
-#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_ECDH_anon_WITH_AES_128_CBC_SHA_256 = 0xFF00, /**< OCF Vendor Specific Ciphersuite */
-  TLS_PSK_WITH_AES_128_CCM_8 = 0xC0A8, /**< see RFC 6655 */
-  TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256 = 0xC037, /**< see RFC 5489 */
-  TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 = 0xC0AE /**< see RFC 7251 */
-} dtls_cipher_t;
-
-typedef enum {
-    DTLS_CIPHER_DISABLE = 0,
-    DTLS_CIPHER_ENABLE = 1
-} dtls_cipher_enable_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 */
-
-/* see http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#tls-extensiontype-values-3 */
-#define TLS_CERT_TYPE_X509              0 /* see RFC 6091 */
-#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. */
-INLINE_API 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.
- */
-INLINE_API 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
-INLINE_API 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
deleted file mode 100644 (file)
index 571a59a..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-/* dtls -- a very basic DTLS implementation
- *
- * Copyright (C) 2011--2012 Olaf Bergmann <bergmann@tzi.org>
- *
- * 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "dtls_config.h"
-
-#ifdef HAVE_ASSERT_H
-#include <assert.h>
-#else
-#define assert(x)
-#endif
-
-#include "debug.h"
-#include "hmac.h"
-
-/* use malloc()/free() on platforms other than Contiki */
-#ifndef WITH_CONTIKI
-#include <stdlib.h>
-
-INLINE_API dtls_hmac_context_t *
-dtls_hmac_context_new() {
-  return (dtls_hmac_context_t *)malloc(sizeof(dtls_hmac_context_t));
-}
-
-INLINE_API 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);
-
-INLINE_API dtls_hmac_context_t *
-dtls_hmac_context_new() {
-  return (dtls_hmac_context_t *)memb_alloc(&hmac_context_storage);
-}
-
-INLINE_API 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 <stdio.h>
-
-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
deleted file mode 100644 (file)
index e4046a7..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/* dtls -- a very basic DTLS implementation
- *
- * Copyright (C) 2011--2012 Olaf Bergmann <bergmann@tzi.org>
- *
- * 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 <sys/types.h>
-
-#include "global.h"
-
-#ifdef WITH_SHA256
-/** Aaron D. Gifford's implementation of SHA256
- *  see http://www.aarongifford.com/ */
-#include "sha2/sha2.h"
-
-typedef dtls_sha256_ctx dtls_hash_ctx;
-typedef dtls_hash_ctx *dtls_hash_t;
-#define DTLS_HASH_CTX_SIZE sizeof(dtls_sha256_ctx)
-
-INLINE_API void
-dtls_hash_init(dtls_hash_t ctx) {
-  dtls_sha256_init((dtls_sha256_ctx *)ctx);
-}
-
-INLINE_API void 
-dtls_hash_update(dtls_hash_t ctx, const unsigned char *input, size_t len) {
-  dtls_sha256_update((dtls_sha256_ctx *)ctx, input, len);
-}
-
-INLINE_API size_t
-dtls_hash_finalize(unsigned char *buf, dtls_hash_t ctx) {
-  dtls_sha256_final(buf, (dtls_sha256_ctx *)ctx);
-  return DTLS_SHA256_DIGEST_LENGTH;
-}
-#endif /* WITH_SHA256 */
-
-#ifndef WITH_CONTIKI
-INLINE_API 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 
- * <a href="http://tools.ietf.org/html/rfc5246#section-7.4.1.4.1"
- * >Section 7.4.1.4.1 of RFC 5246</a>.
- */
-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
deleted file mode 100644 (file)
index 8589858..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/* netq.h -- Simple packet queue
- *
- * Copyright (C) 2010--2012 Olaf Bergmann <bergmann@tzi.org>
- *
- * 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 <assert.h>
-#else
-#ifndef assert
-#warning "assertions are disabled"
-#  define assert(x)
-#endif
-#endif
-
-#include "t_list.h"
-
-#ifndef WITH_CONTIKI
-#include <stdlib.h>
-
-INLINE_API netq_t *
-netq_malloc_node(size_t size) {
-  return (netq_t *)malloc(sizeof(netq_t) + size);
-}
-
-INLINE_API 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);
-
-INLINE_API netq_t *
-netq_malloc_node(size_t size) {
-  return (netq_t *)memb_alloc(&netq_storage);
-}
-
-INLINE_API 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
deleted file mode 100644 (file)
index c3db339..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/* netq.h -- Simple packet queue
- *
- * Copyright (C) 2010--2012 Olaf Bergmann <bergmann@tzi.org>
- *
- * 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
-#if defined(DTLS_ECC) || defined(DTLS_X509)
-#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
-INLINE_API 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
deleted file mode 100644 (file)
index 5af0c4c..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-/* dtls -- a very basic DTLS implementation
- *
- * Copyright (C) 2011 Olaf Bergmann <bergmann@tzi.org>
- *
- * 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 <stdint.h>
-
-#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... */
-INLINE_API int dtls_int_to_uint8(unsigned char *field, uint8_t value)
-{
-  field[0] = value & 0xff;
-  return 1;
-}
-
-INLINE_API int dtls_int_to_uint16(unsigned char *field, uint16_t value)
-{
-  field[0] = (value >> 8) & 0xff;
-  field[1] = value & 0xff;
-  return 2;
-}
-
-INLINE_API 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;
-}
-
-INLINE_API 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;
-}
-
-INLINE_API 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;
-}
-
-INLINE_API 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;
-}
-
-INLINE_API uint8_t dtls_uint8_to_int(const unsigned char *field)
-{
-  return (uint8_t)field[0];
-}
-
-INLINE_API uint16_t dtls_uint16_to_int(const unsigned char *field)
-{
-  return ((uint16_t)field[0] << 8)
-        | (uint16_t)field[1];
-}
-
-INLINE_API 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];
-}
-
-INLINE_API 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];
-}
-
-INLINE_API 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];
-}
-
-INLINE_API 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
deleted file mode 100644 (file)
index 109a612..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/* dtls -- a very basic DTLS implementation
- *
- * Copyright (C) 2011--2013 Olaf Bergmann <bergmann@tzi.org>
- *
- * 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()
-{
-}
-
-INLINE_API 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);
-}
-
-INLINE_API 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
deleted file mode 100644 (file)
index 41fd943..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-/* dtls -- a very basic DTLS implementation
- *
- * Copyright (C) 2011--2013 Olaf Bergmann <bergmann@tzi.org>
- *
- * 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 <sys/types.h>
-
-#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;
-
-INLINE_API 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;
-  }
-}
-
-INLINE_API dtls_security_parameters_t *dtls_security_params(dtls_peer_t *peer)
-{
-  return peer->security_params[0];
-}
-
-INLINE_API 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];
-}
-
-INLINE_API 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;
-}
-
-INLINE_API 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. */
-INLINE_API 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.
- */
-INLINE_API 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
deleted file mode 100644 (file)
index 6b30d21..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-# 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
deleted file mode 100644 (file)
index 38bc85e..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#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
deleted file mode 100644 (file)
index 38bc85e..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#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
deleted file mode 100644 (file)
index 547a1b6..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#define HAVE_ASSERT_H 1
diff --git a/extlibs/tinydtls/platform-specific/config-sky.h b/extlibs/tinydtls/platform-specific/config-sky.h
deleted file mode 100644 (file)
index f49ff3b..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#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
deleted file mode 100644 (file)
index 547a1b6..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#define HAVE_ASSERT_H 1
diff --git a/extlibs/tinydtls/prng.h b/extlibs/tinydtls/prng.h
deleted file mode 100644 (file)
index daf956b..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/* prng.h -- Pseudo Random Numbers
- *
- * Copyright (C) 2010--2012 Olaf Bergmann <bergmann@tzi.org>
- *
- * 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 <stdlib.h>
-
-/**
- * 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.
- */
-INLINE_API int
-dtls_prng(unsigned char *buf, size_t len) {
-  while (len--)
-    *buf++ = rand() & 0xFF;
-  return 1;
-}
-
-INLINE_API void
-dtls_prng_init(unsigned short seed) {
-       srand(seed);
-}
-#else /* WITH_CONTIKI */
-#include <string.h>
-#include "random.h"
-
-#ifdef HAVE_PRNG
-INLINE_API 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.
- */
-INLINE_API 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 */
-
-INLINE_API 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
deleted file mode 100644 (file)
index 6170fd1..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/* dtls -- a very basic DTLS implementation
- *
- * Copyright (C) 2011--2014 Olaf Bergmann <bergmann@tzi.org>
- *
- * 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 "debug.h"
-#include "session.h"
-
-#ifdef HAVE_ASSERT_H
-#include <assert.h>
-#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 */
-
-INLINE_API int 
-_dtls_address_equals_impl(const session_t *a,
-                         const session_t *b) {
-  if ((a == b) && (a != NULL))
-    return 1;
-  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 */
-    dtls_emerg("Could not compare dtls addresses!\n");
- }
- 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
deleted file mode 100644 (file)
index 11ce357..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/* dtls -- a very basic DTLS implementation
- *
- * Copyright (C) 2011--2014 Olaf Bergmann <bergmann@tzi.org>
- *
- * 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 <string.h>
-
-#include "dtls_config.h"
-#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 */
-
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#ifdef HAVE_WINSOCK2_H
-#include <winsock2.h>
-#endif
-#ifdef HAVE_WS2TCPIP_H
-#include <ws2tcpip.h>
-#endif
-#include <stdint.h>
-
-typedef struct {
-  socklen_t size;              /**< size of addr */
-#ifdef _MSC_VER
-  __declspec(align(8))
-#endif
-  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
deleted file mode 100644 (file)
index 85ce9ce..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-# Makefile for tinydtls
-#
-# Copyright (C) 2011 Olaf Bergmann <bergmann@tzi.org>
-#
-# 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
deleted file mode 100644 (file)
index 95e57f3..0000000
+++ /dev/null
@@ -1,272 +0,0 @@
-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 <sys/types.h> 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   <m e @ a a r o n g i f f o r d . c o m>
-
-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
deleted file mode 100644 (file)
index c42c993..0000000
+++ /dev/null
@@ -1,1101 +0,0 @@
-/*
- * 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 <string.h>    /* memcpy()/memset() or bcopy()/bzero() */
-#ifdef HAVE_ASSERT_H
-#include <assert.h>    /* 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 <sys/types.h> (which in turn includes
- * <machine/endian.h> 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 DTLS_SHA256_SHORT_BLOCK_LENGTH (DTLS_SHA256_BLOCK_LENGTH - 8)
-#define DTLS_SHA384_SHORT_BLOCK_LENGTH (DTLS_SHA384_BLOCK_LENGTH - 16)
-#define DTLS_SHA512_SHORT_BLOCK_LENGTH (DTLS_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 dtls_sha512_last(dtls_sha512_ctx*);
-void dtls_sha256_transform(dtls_sha256_ctx*, const sha2_word32*);
-void dtls_sha512_transform(dtls_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 dtls_sha256_init(dtls_sha256_ctx* context) {
-       if (context == (dtls_sha256_ctx*)0) {
-               return;
-       }
-       MEMCPY_BCOPY(context->state, sha256_initial_hash_value, DTLS_SHA256_DIGEST_LENGTH);
-       MEMSET_BZERO(context->buffer, DTLS_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 dtls_sha256_transform(dtls_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 dtls_sha256_transform(dtls_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 dtls_sha256_update(dtls_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 != (dtls_sha256_ctx*)0 && data != (sha2_byte*)0);
-
-       usedspace = (context->bitcount >> 3) % DTLS_SHA256_BLOCK_LENGTH;
-       if (usedspace > 0) {
-               /* Calculate how much free space is available in the buffer */
-               freespace = DTLS_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;
-                       dtls_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 >= DTLS_SHA256_BLOCK_LENGTH) {
-               /* Process as many complete blocks as we can */
-               dtls_sha256_transform(context, (sha2_word32*)data);
-               context->bitcount += DTLS_SHA256_BLOCK_LENGTH << 3;
-               len -= DTLS_SHA256_BLOCK_LENGTH;
-               data += DTLS_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 dtls_sha256_final(sha2_byte digest[], dtls_sha256_ctx* context) {
-       sha2_word32     *d = (sha2_word32*)digest;
-       unsigned int    usedspace;
-
-       /* Sanity check: */
-       assert(context != (dtls_sha256_ctx*)0);
-
-       /* If no digest buffer is passed, we don't bother doing this: */
-       if (digest != (sha2_byte*)0) {
-               usedspace = (context->bitcount >> 3) % DTLS_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 <= DTLS_SHA256_SHORT_BLOCK_LENGTH) {
-                               /* Set-up for the last transform: */
-                               MEMSET_BZERO(&context->buffer[usedspace], DTLS_SHA256_SHORT_BLOCK_LENGTH - usedspace);
-                       } else {
-                               if (usedspace < DTLS_SHA256_BLOCK_LENGTH) {
-                                       MEMSET_BZERO(&context->buffer[usedspace], DTLS_SHA256_BLOCK_LENGTH - usedspace);
-                               }
-                               /* Do second-to-last transform: */
-                               dtls_sha256_transform(context, (sha2_word32*)context->buffer);
-
-                               /* And set-up for the last transform: */
-                               MEMSET_BZERO(context->buffer, DTLS_SHA256_SHORT_BLOCK_LENGTH);
-                       }
-               } else {
-                       /* Set-up for the last transform: */
-                       MEMSET_BZERO(context->buffer, DTLS_SHA256_SHORT_BLOCK_LENGTH);
-
-                       /* Begin padding with a 1 bit: */
-                       *context->buffer = 0x80;
-               }
-               /* Set the bit count: */
-               *(sha2_word64*)&context->buffer[DTLS_SHA256_SHORT_BLOCK_LENGTH] = context->bitcount;
-
-               /* Final transform: */
-               dtls_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, DTLS_SHA256_DIGEST_LENGTH);
-#endif
-       }
-
-       /* Clean up state data: */
-       MEMSET_BZERO(context, sizeof(*context));
-       usedspace = 0;
-}
-
-char *dtls_sha256_end(dtls_sha256_ctx* context, char buffer[]) {
-       sha2_byte       digest[DTLS_SHA256_DIGEST_LENGTH], *d = digest;
-       int             i;
-
-       /* Sanity check: */
-       assert(context != (dtls_sha256_ctx*)0);
-
-       if (buffer != (char*)0) {
-               dtls_sha256_final(digest, context);
-
-               for (i = 0; i < DTLS_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, DTLS_SHA256_DIGEST_LENGTH);
-       return buffer;
-}
-
-char* dtls_sha256_data(const sha2_byte* data, size_t len, char digest[DTLS_SHA256_DIGEST_STRING_LENGTH]) {
-       dtls_sha256_ctx context;
-
-       dtls_sha256_init(&context);
-       dtls_sha256_update(&context, data, len);
-       return dtls_sha256_end(&context, digest);
-}
-#endif
-
-/*** SHA-512: *********************************************************/
-#ifdef WITH_SHA512
-void dtls_sha512_init(dtls_sha512_ctx* context) {
-       if (context == (dtls_sha512_ctx*)0) {
-               return;
-       }
-       MEMCPY_BCOPY(context->state, sha512_initial_hash_value, DTLS_SHA512_DIGEST_LENGTH);
-       MEMSET_BZERO(context->buffer, DTLS_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 dtls_sha512_transform(dtls_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 dtls_sha512_transform(dtls_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 dtls_sha512_update(dtls_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 != (dtls_sha512_ctx*)0 && data != (sha2_byte*)0);
-
-       usedspace = (context->bitcount[0] >> 3) % DTLS_SHA512_BLOCK_LENGTH;
-       if (usedspace > 0) {
-               /* Calculate how much free space is available in the buffer */
-               freespace = DTLS_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;
-                       dtls_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 >= DTLS_SHA512_BLOCK_LENGTH) {
-               /* Process as many complete blocks as we can */
-               dtls_sha512_transform(context, (sha2_word64*)data);
-               ADDINC128(context->bitcount, DTLS_SHA512_BLOCK_LENGTH << 3);
-               len -= DTLS_SHA512_BLOCK_LENGTH;
-               data += DTLS_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 dtls_sha512_last(dtls_sha512_ctx* context) {
-       unsigned int    usedspace;
-
-       usedspace = (context->bitcount[0] >> 3) % DTLS_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 <= DTLS_SHA512_SHORT_BLOCK_LENGTH) {
-                       /* Set-up for the last transform: */
-                       MEMSET_BZERO(&context->buffer[usedspace], DTLS_SHA512_SHORT_BLOCK_LENGTH - usedspace);
-               } else {
-                       if (usedspace < DTLS_SHA512_BLOCK_LENGTH) {
-                               MEMSET_BZERO(&context->buffer[usedspace], DTLS_SHA512_BLOCK_LENGTH - usedspace);
-                       }
-                       /* Do second-to-last transform: */
-                       dtls_sha512_transform(context, (sha2_word64*)context->buffer);
-
-                       /* And set-up for the last transform: */
-                       MEMSET_BZERO(context->buffer, DTLS_SHA512_BLOCK_LENGTH - 2);
-               }
-       } else {
-               /* Prepare for final transform: */
-               MEMSET_BZERO(context->buffer, DTLS_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[DTLS_SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1];
-       *(sha2_word64*)&context->buffer[DTLS_SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0];
-
-       /* Final transform: */
-       dtls_sha512_transform(context, (sha2_word64*)context->buffer);
-}
-
-void dtls_sha512_final(sha2_byte digest[], dtls_sha512_ctx* context) {
-       sha2_word64     *d = (sha2_word64*)digest;
-
-       /* Sanity check: */
-       assert(context != (dtls_sha512_ctx*)0);
-
-       /* If no digest buffer is passed, we don't bother doing this: */
-       if (digest != (sha2_byte*)0) {
-               dtls_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, DTLS_SHA512_DIGEST_LENGTH);
-#endif
-       }
-
-       /* Zero out state data */
-       MEMSET_BZERO(context, sizeof(context));
-}
-
-char *dtls_sha512_end(dtls_sha512_ctx* context, char buffer[]) {
-       sha2_byte       digest[DTLS_SHA512_DIGEST_LENGTH], *d = digest;
-       int             i;
-
-       /* Sanity check: */
-       assert(context != (dtls_sha512_ctx*)0);
-
-       if (buffer != (char*)0) {
-               dtls_sha512_final(digest, context);
-
-               for (i = 0; i < DTLS_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, DTLS_SHA512_DIGEST_LENGTH);
-       return buffer;
-}
-
-char* dtls_sha512_data(const sha2_byte* data, size_t len, char digest[DTLS_SHA512_DIGEST_STRING_LENGTH]) {
-       dtls_sha512_ctx context;
-
-       dtls_sha512_init(&context);
-       dtls_sha512_update(&context, data, len);
-       return dtls_sha512_end(&context, digest);
-}
-#endif
-
-/*** SHA-384: *********************************************************/
-#ifdef WITH_SHA384
-void dtls_sha384_init(dtls_sha384_ctx* context) {
-       if (context == (dtls_sha384_ctx*)0) {
-               return;
-       }
-       MEMCPY_BCOPY(context->state, sha384_initial_hash_value, DTLS_SHA512_DIGEST_LENGTH);
-       MEMSET_BZERO(context->buffer, DTLS_SHA384_BLOCK_LENGTH);
-       context->bitcount[0] = context->bitcount[1] = 0;
-}
-
-void dtls_sha384_update(dtls_sha384_ctx* context, const sha2_byte* data, size_t len) {
-       dtls_sha512_update((dtls_sha512_ctx*)context, data, len);
-}
-
-void dtls_sha384_final(sha2_byte digest[], dtls_sha384_ctx* context) {
-       sha2_word64     *d = (sha2_word64*)digest;
-
-       /* Sanity check: */
-       assert(context != (dtls_sha384_ctx*)0);
-
-       /* If no digest buffer is passed, we don't bother doing this: */
-       if (digest != (sha2_byte*)0) {
-               dtls_sha512_last((dtls_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, DTLS_SHA384_DIGEST_LENGTH);
-#endif
-       }
-
-       /* Zero out state data */
-       MEMSET_BZERO(context, sizeof(context));
-}
-
-char *dtls_sha384_end(dtls_sha384_ctx* context, char buffer[]) {
-       sha2_byte       digest[DTLS_SHA384_DIGEST_LENGTH], *d = digest;
-       int             i;
-
-       /* Sanity check: */
-       assert(context != (dtls_sha384_ctx*)0);
-
-       if (buffer != (char*)0) {
-               dtls_sha384_final(digest, context);
-
-               for (i = 0; i < DTLS_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, DTLS_SHA384_DIGEST_LENGTH);
-       return buffer;
-}
-
-char* dtls_sha384_data(const sha2_byte* data, size_t len, char digest[DTLS_SHA384_DIGEST_STRING_LENGTH]) {
-       dtls_sha384_ctx context;
-
-       dtls_sha384_init(&context);
-       dtls_sha384_update(&context, data, len);
-       return dtls_sha384_end(&context, digest);
-}
-#endif
diff --git a/extlibs/tinydtls/sha2/sha2.h b/extlibs/tinydtls/sha2/sha2.h
deleted file mode 100644 (file)
index c56b42a..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * 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 <sys/types.h>
-
-#ifdef SHA2_USE_INTTYPES_H
-
-#include <inttypes.h>
-
-#endif /* SHA2_USE_INTTYPES_H */
-
-
-/*** SHA-256/384/512 Various Length Definitions ***********************/
-#define DTLS_SHA256_BLOCK_LENGTH               64
-#define DTLS_SHA256_DIGEST_LENGTH              32
-#define DTLS_SHA256_DIGEST_STRING_LENGTH       (DTLS_SHA256_DIGEST_LENGTH * 2 + 1)
-#define DTLS_SHA384_BLOCK_LENGTH               128
-#define DTLS_SHA384_DIGEST_LENGTH              48
-#define DTLS_SHA384_DIGEST_STRING_LENGTH       (DTLS_SHA384_DIGEST_LENGTH * 2 + 1)
-#define DTLS_SHA512_BLOCK_LENGTH               128
-#define DTLS_SHA512_DIGEST_LENGTH              64
-#define DTLS_SHA512_DIGEST_STRING_LENGTH       (DTLS_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 <inttypes.h>
- *
- * If you choose to use <inttypes.h> 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 _dtls_sha256_ctx {
-       uint32_t        state[8];
-       uint64_t        bitcount;
-       uint8_t buffer[DTLS_SHA256_BLOCK_LENGTH];
-} dtls_sha256_ctx;
-typedef struct _dtls_sha512_ctx {
-       uint64_t        state[8];
-       uint64_t        bitcount[2];
-       uint8_t buffer[DTLS_SHA512_BLOCK_LENGTH];
-} dtls_sha512_ctx;
-
-#else /* SHA2_USE_INTTYPES_H */
-
-typedef struct _dtls_sha256_ctx {
-       u_int32_t       state[8];
-       u_int64_t       bitcount;
-       u_int8_t        buffer[DTLS_SHA256_BLOCK_LENGTH];
-} dtls_sha256_ctx;
-typedef struct _dtls_sha512_ctx {
-       u_int64_t       state[8];
-       u_int64_t       bitcount[2];
-       u_int8_t        buffer[DTLS_SHA512_BLOCK_LENGTH];
-} dtls_sha512_ctx;
-
-#endif /* SHA2_USE_INTTYPES_H */
-
-typedef dtls_sha512_ctx dtls_sha384_ctx;
-
-
-/*** SHA-256/384/512 Function Prototypes ******************************/
-#ifndef NOPROTO
-#ifdef SHA2_USE_INTTYPES_H
-
-#ifdef WITH_SHA256
-void dtls_sha256_init(dtls_sha256_ctx *);
-void dtls_sha256_update(dtls_sha256_ctx*, const uint8_t*, size_t);
-void dtls_sha256_final(uint8_t[DTLS_SHA256_DIGEST_LENGTH], dtls_sha256_ctx*);
-char* dtls_sha256_end(dtls_sha256_ctx*, char[DTLS_SHA256_DIGEST_STRING_LENGTH]);
-char* dtls_sha256_data(const uint8_t*, size_t, char[DTLS_SHA256_DIGEST_STRING_LENGTH]);
-#endif
-
-#ifdef WITH_SHA384
-void dtls_sha384_init(dtls_sha384_ctx*);
-void dtls_sha384_update(dtls_sha384_ctx*, const uint8_t*, size_t);
-void dtls_sha384_final(uint8_t[DTLS_SHA384_DIGEST_LENGTH], SHA384_CTX*);
-char* dtls_sha384_end(dtls_sha384_ctx*, char[DTLS_SHA384_DIGEST_STRING_LENGTH]);
-char* dtls_sha384_data(const uint8_t*, size_t, char[DTLS_SHA384_DIGEST_STRING_LENGTH]);
-#endif
-
-#ifdef WITH_SHA512
-void dtls_sha512_init(dtls_sha512_ctx*);
-void dtls_sha512_update(dtls_sha512_ctx*, const uint8_t*, size_t);
-void dtls_sha512_final(uint8_t[DTLS_SHA512_DIGEST_LENGTH], dtls_sha512_ctx*);
-char* dtls_sha512_end(dtls_sha512_ctx*, char[DTLS_SHA512_DIGEST_STRING_LENGTH]);
-char* dtls_sha512_data(const uint8_t*, size_t, char[DTLS_SHA512_DIGEST_STRING_LENGTH]);
-#endif
-
-#else /* SHA2_USE_INTTYPES_H */
-
-#ifdef WITH_SHA256
-void dtls_sha256_init(dtls_sha256_ctx *);
-void dtls_sha256_update(dtls_sha256_ctx*, const u_int8_t*, size_t);
-void dtls_sha256_final(u_int8_t[DTLS_SHA256_DIGEST_LENGTH], dtls_sha256_ctx*);
-char* dtls_sha256_end(dtls_sha256_ctx*, char[DTLS_SHA256_DIGEST_STRING_LENGTH]);
-char* dtls_sha256_data(const u_int8_t*, size_t, char[DTLS_SHA256_DIGEST_STRING_LENGTH]);
-#endif
-
-#ifdef WITH_SHA384
-void dtls_sha384_init(dtls_sha384_ctx*);
-void dtls_sha384_update(dtls_sha384_ctx*, const u_int8_t*, size_t);
-void dtls_sha384_final(u_int8_t[DTLS_SHA384_DIGEST_LENGTH], dtls_sha384_ctx*);
-char* dtls_sha384_end(dtls_sha384_ctx*, char[DTLS_SHA384_DIGEST_STRING_LENGTH]);
-char* dtls_sha384_data(const u_int8_t*, size_t, char[DTLS_SHA384_DIGEST_STRING_LENGTH]);
-#endif
-
-#ifdef WITH_SHA512
-void dtls_sha512_init(dtls_sha512_ctx*);
-void dtls_sha512_update(dtls_sha512_ctx*, const u_int8_t*, size_t);
-void dtls_sha512_final(u_int8_t[DTLS_SHA512_DIGEST_LENGTH], dtls_sha512_ctx*);
-char* dtls_sha512_end(dtls_sha512_ctx*, char[DTLS_SHA512_DIGEST_STRING_LENGTH]);
-char* dtls_sha512_data(const u_int8_t*, size_t, char[DTLS_SHA512_DIGEST_STRING_LENGTH]);
-#endif
-
-#endif /* SHA2_USE_INTTYPES_H */
-
-#else /* NOPROTO */
-
-#ifdef WITH_SHA256
-void dtls_sha256_init();
-void dtls_sha256_update();
-void dtls_sha256_final();
-char* dtls_sha256_end();
-char* dtls_sha256_data();
-#endif
-
-#ifdef WITH_SHA384
-void dtls_sha384_init();
-void dtls_sha384_update();
-void dtls_sha384_final();
-char* dtls_sha384_end();
-char* dtls_sha384_data();
-#endif
-
-#ifdef WITH_SHA512
-void dtls_sha512_init();
-void dtls_sha512_update();
-void dtls_sha512_final();
-char* dtls_sha512_end();
-char* dtls_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
deleted file mode 100644 (file)
index 6ac6796..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * 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 <stdio.h>
-#include <sysexits.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <unistd.h>
-
-#include "sha2.h"
-
-void usage(char *prog, char *msg) {
-       fprintf(stderr, "%s\nUsage:\t%s [options] [<file>]\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;
-       dtls_sha256_ctx ctx256;
-       dtls_sha384_ctx ctx384;
-       dtls_sha512_ctx ctx512;
-       unsigned char   buf[BUFLEN];
-
-       dtls_sha256_init(&ctx256);
-       dtls_sha384_init(&ctx384);
-       dtls_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;
-               dtls_sha256_update(&ctx256, (unsigned char*)buf, l);
-               dtls_sha384_update(&ctx384, (unsigned char*)buf, l);
-               dtls_sha512_update(&ctx512, (unsigned char*)buf, l);
-       }
-       if (file) {
-               fclose(IN);
-       }
-
-       if (hash & 1) {
-               dtls_sha256_end(&ctx256, buf);
-               if (!quiet)
-                       printf("SHA-256 (%s) = ", file);
-               printf("%s\n", buf);
-       }
-       if (hash & 2) {
-               dtls_sha384_end(&ctx384, buf);
-               if (!quiet)
-                       printf("SHA-384 (%s) = ", file);
-               printf("%s\n", buf);
-       }
-       if (hash & 4) {
-               dtls_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
deleted file mode 100644 (file)
index 77d17af..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/time.h>
-
-#include "sha2.h"
-
-#define BUFSIZE        16384
-
-void usage(char *prog) {
-       fprintf(stderr, "Usage:\t%s [<num-of-bytes>] [<num-of-loops>] [<fill-byte>]\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) {
-       dtls_sha256_ctx c256;
-       dtls_sha384_ctx c384;
-       dtls_sha512_ctx c512;
-       char            buf[BUFSIZE];
-       char            md[DTLS_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++) {
-               dtls_sha256_init(&c256);
-               dtls_sha384_init(&c384);
-               dtls_sha512_init(&c512);
-       
-               gettimeofday(&start, (struct timezone*)0);
-               for (j = 0; j < blocks; j++) {
-                       dtls_sha256_update(&c256, (unsigned char*)buf, BUFSIZE);
-               }
-               if (bytes % BUFSIZE) {
-                       dtls_sha256_update(&c256, (unsigned char*)buf, bytes % BUFSIZE);
-               }
-               dtls_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++) {
-                       dtls_sha384_update(&c384, (unsigned char*)buf, BUFSIZE);
-               }
-               if (bytes % BUFSIZE) {
-                       dtls_sha384_update(&c384, (unsigned char*)buf, bytes % BUFSIZE);
-               }
-               dtls_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++) {
-                       dtls_sha512_update(&c512, (unsigned char*)buf, BUFSIZE);
-               }
-               if (bytes % BUFSIZE) {
-                       dtls_sha512_update(&c512, (unsigned char*)buf, bytes % BUFSIZE);
-               }
-               dtls_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
deleted file mode 100755 (executable)
index dc884d8..0000000
+++ /dev/null
@@ -1,358 +0,0 @@
-#!/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 <<EOM;
-Error:
-       $err
-Usage:
-       $0 [<options>] [<test-vector-info-file> [<test-vector-info-file> ...]]
-
-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 <command-spec>    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 <command-spec>    Specify a command to execute to generate a
-                               SHA-384 hash.  See above.  Implies -384.
-       -c512 <command-spec>    Specify a command to execute to generate a
-                               SHA-512 hash.  See above.  Implies -512.
-       -cALL <command-spec>    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 <command-spec>.
-                               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(<FILE>) {
-               $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
deleted file mode 100644 (file)
index f2ba8f8..0000000
+++ /dev/null
@@ -1 +0,0 @@
-abc
\ No newline at end of file
diff --git a/extlibs/tinydtls/sha2/testvectors/vector001.info b/extlibs/tinydtls/sha2/testvectors/vector001.info
deleted file mode 100644 (file)
index 57b444e..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-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
deleted file mode 100644 (file)
index 199f24e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq
\ No newline at end of file
diff --git a/extlibs/tinydtls/sha2/testvectors/vector002.info b/extlibs/tinydtls/sha2/testvectors/vector002.info
deleted file mode 100644 (file)
index 0fc1ed3..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-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
deleted file mode 100644 (file)
index 4674ea4..0000000
+++ /dev/null
@@ -1 +0,0 @@
-abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu
\ No newline at end of file
diff --git a/extlibs/tinydtls/sha2/testvectors/vector003.info b/extlibs/tinydtls/sha2/testvectors/vector003.info
deleted file mode 100644 (file)
index 17a2ad8..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-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
deleted file mode 100644 (file)
index 3d71eba..0000000
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644 (file)
index eed148c..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-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/extlibs/tinydtls/sha2/testvectors/vector005.dat b/extlibs/tinydtls/sha2/testvectors/vector005.dat
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/extlibs/tinydtls/sha2/testvectors/vector005.info b/extlibs/tinydtls/sha2/testvectors/vector005.info
deleted file mode 100644 (file)
index 37602d3..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-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
deleted file mode 100644 (file)
index 7caf161..0000000
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644 (file)
index 2a0d78a..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-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
deleted file mode 100644 (file)
index 1caf01b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644 (file)
index fad860d..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-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
deleted file mode 100644 (file)
index baae226..0000000
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644 (file)
index 22cfd81..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-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
deleted file mode 100644 (file)
index 9c64af4..0000000
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644 (file)
index d5fe515..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-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
deleted file mode 100644 (file)
index f1681bc..0000000
Binary files a/extlibs/tinydtls/sha2/testvectors/vector010.dat and /dev/null differ
diff --git a/extlibs/tinydtls/sha2/testvectors/vector010.info b/extlibs/tinydtls/sha2/testvectors/vector010.info
deleted file mode 100644 (file)
index df7717d..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-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
deleted file mode 100644 (file)
index d1609a9..0000000
Binary files a/extlibs/tinydtls/sha2/testvectors/vector011.dat and /dev/null differ
diff --git a/extlibs/tinydtls/sha2/testvectors/vector011.info b/extlibs/tinydtls/sha2/testvectors/vector011.info
deleted file mode 100644 (file)
index f36988c..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-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
deleted file mode 100644 (file)
index d74f1db..0000000
Binary files a/extlibs/tinydtls/sha2/testvectors/vector012.dat and /dev/null differ
diff --git a/extlibs/tinydtls/sha2/testvectors/vector012.info b/extlibs/tinydtls/sha2/testvectors/vector012.info
deleted file mode 100644 (file)
index a1574e1..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-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
deleted file mode 100644 (file)
index cc8a8ae..0000000
Binary files a/extlibs/tinydtls/sha2/testvectors/vector013.dat and /dev/null differ
diff --git a/extlibs/tinydtls/sha2/testvectors/vector013.info b/extlibs/tinydtls/sha2/testvectors/vector013.info
deleted file mode 100644 (file)
index 4fbd4cb..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-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
deleted file mode 100644 (file)
index 6ee6629..0000000
Binary files a/extlibs/tinydtls/sha2/testvectors/vector014.dat and /dev/null differ
diff --git a/extlibs/tinydtls/sha2/testvectors/vector014.info b/extlibs/tinydtls/sha2/testvectors/vector014.info
deleted file mode 100644 (file)
index 1780afc..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-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
deleted file mode 100644 (file)
index 7d63021..0000000
+++ /dev/null
@@ -1 +0,0 @@
-qwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwertyqwerty
\ No newline at end of file
diff --git a/extlibs/tinydtls/sha2/testvectors/vector015.info b/extlibs/tinydtls/sha2/testvectors/vector015.info
deleted file mode 100644 (file)
index d035782..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-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
deleted file mode 100644 (file)
index fc00891..0000000
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644 (file)
index effb114..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-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
deleted file mode 100644 (file)
index 4272d97..0000000
Binary files a/extlibs/tinydtls/sha2/testvectors/vector017.dat and /dev/null differ
diff --git a/extlibs/tinydtls/sha2/testvectors/vector017.info b/extlibs/tinydtls/sha2/testvectors/vector017.info
deleted file mode 100644 (file)
index 5d6c632..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-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
deleted file mode 100644 (file)
index cc8a8d1..0000000
Binary files a/extlibs/tinydtls/sha2/testvectors/vector018.dat and /dev/null differ
diff --git a/extlibs/tinydtls/sha2/testvectors/vector018.info b/extlibs/tinydtls/sha2/testvectors/vector018.info
deleted file mode 100644 (file)
index 7ee3444..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-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
deleted file mode 100644 (file)
index 72df125..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/* dtls -- a very basic DTLS implementation
- *
- * Copyright (C) 2011--2013 Olaf Bergmann <bergmann@tzi.org>
- *
- * 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 <sys/types.h>
-#include <stdint.h>
-
-#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
deleted file mode 100644 (file)
index 1c3fba9..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/* t_list -- tinydtls lists
- *
- * Copyright (C) 2012 Olaf Bergmann <bergmann@tzi.org>
- *
- * 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 <adam@sics.se>
- *
- * $ 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;                      \
-  }
-
-INLINE_API void *
-list_head(list_t list) {
-  return *list;
-}
-
-INLINE_API void 
-list_remove(list_t list, void *item) {
-  LL_DELETE(*(struct list **)list, (struct list *)item);
-}
-
-INLINE_API void 
-list_add(list_t list, void *item) {
-  list_remove(list, item);
-  LL_APPEND(*(struct list **)list, (struct list *)item);
-}
-
-INLINE_API void 
-list_push(list_t list, void *item) {
-  LL_PREPEND(*(struct list **)list, (struct list *)item);
-}
-
-INLINE_API void *
-list_pop(list_t list) {
-  struct list *l;
-  l = *list;
-  if(l)
-    list_remove(list, l);
-  
-  return l;
-}
-
-INLINE_API 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;
-  } 
-}
-
-INLINE_API 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
deleted file mode 100644 (file)
index a2d8ca4..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-# Makefile for tinydtls
-#
-# Copyright (C) 2011 Olaf Bergmann <bergmann@tzi.org>
-#
-# 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
deleted file mode 100644 (file)
index 1f91920..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#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
deleted file mode 100644 (file)
index 0791679..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/* dtls -- a very basic DTLS implementation
- *
- * Copyright (C) 2011 Olaf Bergmann <bergmann@tzi.org>
- *
- * 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
deleted file mode 100644 (file)
index cbb7d2a..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#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
deleted file mode 100644 (file)
index f0da4ae..0000000
+++ /dev/null
@@ -1,395 +0,0 @@
-/* dtls -- a very basic DTLS implementation
- *
- * Copyright (C) 2011 Olaf Bergmann <bergmann@tzi.org>
- *
- * 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
deleted file mode 100644 (file)
index e7b44a9..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <netinet/in.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-
-#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
deleted file mode 100644 (file)
index 9c71254..0000000
+++ /dev/null
@@ -1,905 +0,0 @@
-#include "iotivity_config.h" 
-#include "tinydtls.h" 
-
-/* This is needed for apple */
-#define __APPLE_USE_RFC_3542
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <ctype.h>
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#include <sys/types.h>
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#include <signal.h>
-#include <getopt.h>
-
-#include "global.h"
-#include "debug.h"
-#include "dtls.h"
-
-/**
- * @struct byte_array
- *
- * General purpose byte array structure.
- *
- * Contains pointer to array of bytes and it's length.
- */
-
-typedef struct
-{
-    uint8_t *data;    /**< Pointer to the byte array */
-    size_t len;      /**< Data size */
-} byte_array;
-
-
-/**@def BYTE_ARRAY_INITIALIZER
- *
- * Initializes of existing byte array pointer to \a NULL.
- */
-#undef BYTE_ARRAY_INITIALIZER
-#define BYTE_ARRAY_INITIALIZER {NULL, 0}
-
-#define DTLS_PRIVATE_KEY_SIZE        (32)
-#define DTLS_PUBLIC_KEY_SIZE         (64)
-
-#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:"
-#define X509_OPTIONS         "x:r:u:"
-
-#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;
-
-#ifdef DTLS_X509
-#define CLIENT_CRT_LEN 293
-static const unsigned char g_client_certificate[CLIENT_CRT_LEN] = {
-        0x00, 0x01, 0x22,
-        0x30, 0x82, 0x01, 0x1e, 0x30, 0x81, 0xc4, 0xa0,
-        0x03, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x38,
-        0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
-        0x3d, 0x04, 0x03, 0x02, 0x05, 0x00, 0x30, 0x17,
-        0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04,
-        0x03, 0x0c, 0x0c, 0x4c, 0x6f, 0x63, 0x61, 0x6c,
-        0x20, 0x49, 0x53, 0x53, 0x55, 0x45, 0x52, 0x30,
-        0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x31, 0x30,
-        0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
-        0x17, 0x0d, 0x34, 0x39, 0x30, 0x31, 0x30, 0x31,
-        0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30,
-        0x17, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55,
-        0x04, 0x03, 0x0c, 0x0c, 0x4c, 0x6f, 0x63, 0x61,
-        0x6c, 0x20, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54,
-        0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
-        0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a,
-        0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
-        0x42, 0x00, 0x04, 0xe3, 0xd1, 0x67, 0x1e, 0xdc,
-        0x46, 0xf4, 0x19, 0x50, 0x15, 0x2e, 0x3a, 0x2f,
-        0xd8, 0x68, 0x6b, 0x37, 0x32, 0x84, 0x9e, 0x83,
-        0x81, 0xbf, 0x25, 0x5d, 0xbb, 0x18, 0x07, 0x3c,
-        0xbd, 0xf3, 0xab, 0xd3, 0xbf, 0x53, 0x59, 0xc9,
-        0x1e, 0xce, 0x5b, 0x39, 0x6a, 0xe5, 0x60, 0xf3,
-        0x70, 0xdb, 0x66, 0xb6, 0x80, 0xcb, 0x65, 0x0b,
-        0x35, 0x2a, 0x62, 0x44, 0x89, 0x63, 0x64, 0x6f,
-        0x6f, 0xbd, 0xf0, 0x30, 0x0c, 0x06, 0x08, 0x2a,
-        0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x05,
-        0x00, 0x03, 0x47, 0x00, 0x30, 0x44, 0x02, 0x20,
-        0x60, 0xdc, 0x45, 0x77, 0x7d, 0xcb, 0xc3, 0xb4,
-        0xba, 0x60, 0x5a, 0x2e, 0xe5, 0x4e, 0x19, 0x8b,
-        0x48, 0x8a, 0x87, 0xd4, 0x66, 0xb4, 0x1a, 0x86,
-        0x23, 0x67, 0xb8, 0xb6, 0x50, 0xfe, 0x4d, 0xde,
-        0x02, 0x20, 0x60, 0x68, 0x46, 0xff, 0x74, 0x11,
-        0xfb, 0x36, 0x13, 0xf4, 0xa7, 0x3d, 0xb7, 0x35,
-        0x79, 0x23, 0x29, 0x14, 0x6a, 0x28, 0x09, 0xff,
-        0x8c, 0x19, 0x26, 0xe3, 0x41, 0xc8, 0xe4, 0x13,
-        0xbc, 0x8e};
-//default client's key pair
-static const unsigned char x509_priv_key[] = {
-        0xf9, 0x42, 0xb4, 0x16, 0x89, 0x10, 0xf4, 0x07,
-        0x99, 0xb2, 0xe2, 0x9a, 0xed, 0xd4, 0x39, 0xb8,
-        0xca, 0xd4, 0x9d, 0x76, 0x11, 0x43, 0x3a, 0xac,
-        0x14, 0xba, 0x17, 0x9d, 0x3e, 0xbb, 0xbf, 0xbc};
-
-static const unsigned char x509_pub_key_x[] = {
-        0xe3, 0xd1, 0x67, 0x1e, 0xdc, 0x46, 0xf4, 0x19,
-        0x50, 0x15, 0x2e, 0x3a, 0x2f, 0xd8, 0x68, 0x6b,
-        0x37, 0x32, 0x84, 0x9e, 0x83, 0x81, 0xbf, 0x25,
-        0x5d, 0xbb, 0x18, 0x07, 0x3c, 0xbd, 0xf3, 0xab};
-
-static const unsigned char x509_pub_key_y[] = {
-        0xd3, 0xbf, 0x53, 0x59, 0xc9, 0x1e, 0xce, 0x5b,
-        0x39, 0x6a, 0xe5, 0x60, 0xf3, 0x70, 0xdb, 0x66,
-        0xb6, 0x80, 0xcb, 0x65, 0x0b, 0x35, 0x2a, 0x62,
-        0x44, 0x89, 0x63, 0x64, 0x6f, 0x6f, 0xbd, 0xf0};
-
-//default CA pub key
-static const unsigned char x509_ca_pub_x[] = {
-        0x57, 0x94, 0x7f, 0x98, 0x7a, 0x02, 0x67, 0x09,
-        0x25, 0xc1, 0xcb, 0x5a, 0xf5, 0x46, 0xfb, 0xad,
-        0xf7, 0x68, 0x94, 0x8c, 0xa7, 0xe3, 0xf0, 0x5b,
-        0xc3, 0x6b, 0x5c, 0x9b, 0xd3, 0x7d, 0x74, 0x12
-};
-
-static const unsigned char x509_ca_pub_y[] = {
-        0xce, 0x68, 0xbc, 0x55, 0xf5, 0xf8, 0x1b, 0x3d,
-        0xef, 0xed, 0x1f, 0x2b, 0xd2, 0x69, 0x5d, 0xcf,
-        0x79, 0x16, 0xa6, 0xbd, 0x97, 0x96, 0x27, 0x60,
-        0x5d, 0xd1, 0xb7, 0x93, 0xa2, 0x4a, 0x62, 0x4d
-};
-
-//default server's key pair
-static const unsigned char serv_pub_key_x[] = {
-        0x07, 0x88, 0x10, 0xdc, 0x62, 0xd7, 0xe6, 0x9b,
-        0x7c, 0xad, 0x6e, 0x78, 0xb0, 0x5f, 0x9a, 0x00,
-        0x11, 0x74, 0x2c, 0x8b, 0xaf, 0x09, 0x65, 0x7c,
-        0x86, 0x8e, 0x55, 0xcb, 0x39, 0x55, 0x72, 0xc6};
-
-static const unsigned char serv_pub_key_y[] = {
-        0x65, 0x71, 0xcd, 0x03, 0xdc, 0x2a, 0x4f, 0x46,
-        0x5b, 0x14, 0xc8, 0x27, 0x74, 0xab, 0xf4, 0x1f,
-        0xc1, 0x35, 0x0d, 0x42, 0xbc, 0xc2, 0x9f, 0xb5,
-        0xc1, 0x79, 0xb6, 0x8b, 0xca, 0xdb, 0xff, 0x82};
-
-
-static unsigned char x509_client_cert[DTLS_MAX_CERT_SIZE];
-static size_t x509_client_cert_len = 0;
-static unsigned char x509_client_priv[DTLS_PRIVATE_KEY_SIZE+1];
-static size_t x509_client_priv_is_set = 0;
-static unsigned char x509_ca_pub[DTLS_PUBLIC_KEY_SIZE+1];
-static size_t x509_ca_pub_is_set = 0;
-
-static int x509_info_from_file = 0;
-#endif /*DTLS_X509*/
-#ifdef DTLS_ECC
-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};
-
-#endif /*DTLS_ECC*/
-#if defined(DTLS_PSK) || defined(DTLS_X509)
-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;
-}
-#endif /*DTLS_PSK||DTLS_X509*/
-#ifdef DTLS_PSK
-/* 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_debug("PSK for unknown id requested\n");
-    }
-    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_ecc_key_t **result) {
-    (void)ctx;
-    (void)session;
-  static const dtls_ecc_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) {
-  (void)ctx;
-  (void)session;
-  (void)other_pub_x;
-  (void)other_pub_y;
-  (void)key_size;
-  return 0;
-}
-
-#endif /* DTLS_ECC */
-
-#ifdef DTLS_X509
-static int
-get_x509_key(struct dtls_context_t *ctx,
-          const session_t *session,
-          const dtls_ecc_key_t **result) {
-    (void)ctx;
-    (void)session;
-  static dtls_ecc_key_t ecdsa_key = {
-    .curve = DTLS_ECDH_CURVE_SECP256R1,
-    .priv_key = x509_priv_key,
-    .pub_key_x = x509_pub_key_x,
-    .pub_key_y = x509_pub_key_y
-  };
-  if (x509_info_from_file)
-      ecdsa_key.priv_key = x509_client_priv;
-  *result = &ecdsa_key;
-  return 0;
-}
-
-static int
-get_x509_cert(struct dtls_context_t *ctx,
-        const session_t *session,
-        const unsigned char **cert,
-        size_t *cert_size)
-{
-    (void)ctx;
-    (void)session;
-    if (x509_info_from_file)
-    {
-        *cert = x509_client_cert;
-        *cert_size = x509_client_cert_len;
-    }
-    else
-    {
-        *cert = g_client_certificate;
-        *cert_size = CLIENT_CRT_LEN;
-    }
-
-    return 0;
-}
-
-int check_certificate(byte_array cert_der_code, byte_array ca_public_key)
-{
-    (void)cert_der_code;
-    (void)ca_public_key;
-    return 0;
-}
-
-static int verify_x509_cert(struct dtls_context_t *ctx, const session_t *session,
-                                  const unsigned char *cert, size_t cert_size,
-                                  unsigned char *x,
-                                  size_t x_size,
-                                  unsigned char *y,
-                                  size_t y_size)
-{
-    int ret;
-    const unsigned char *ca_pub_x;
-    const unsigned char *ca_pub_y;
-    byte_array cert_der_code = BYTE_ARRAY_INITIALIZER;
-    byte_array ca_public_key = BYTE_ARRAY_INITIALIZER;
-    unsigned char ca_pub_key[DTLS_PUBLIC_KEY_SIZE];
-    (void)ctx;
-    (void)session;
-
-    if (x509_info_from_file)
-    {
-        ca_pub_x = x509_ca_pub;
-        ca_pub_y = x509_ca_pub + DTLS_PUBLIC_KEY_SIZE/2;
-    }
-    else
-    {
-        ca_pub_x = x509_ca_pub_x;
-        ca_pub_y = x509_ca_pub_y;
-    }
-
-    cert_der_code.data = (uint8_t *)cert;
-    cert_der_code.len = cert_size;
-
-    ca_public_key.len = DTLS_PUBLIC_KEY_SIZE;
-    ca_public_key.data = ca_pub_key;
-    memcpy(ca_public_key.data, ca_pub_x, DTLS_PUBLIC_KEY_SIZE/2);
-    memcpy(ca_public_key.data + DTLS_PUBLIC_KEY_SIZE/2, ca_pub_y, DTLS_PUBLIC_KEY_SIZE/2);
-
-    memcpy(x, serv_pub_key_x, x_size);
-    memcpy(y, serv_pub_key_y, y_size);
-
-    ret = (int) check_certificate(cert_der_code, ca_public_key);
-
-    return -ret;
-}
-
-static int is_x509_active(struct dtls_context_t *ctx)
-{
-    (void)ctx;
-    return 0;
-}
-
-#endif /* DTLS_X509 */
-
-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;
-  (void)ctx;
-  (void)session;
-  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);
-#ifdef _WIN32
-  exit(sig);
-#else
-  kill(getpid(), sig);
-#endif
-}
-
-/* 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 <bergmann@tzi.org>\n\n"
-         "usage: %s"
-#ifdef DTLS_PSK
-          " [-i file] [-s file] [-k file]"
-#endif /* DTLS_PSK */
-#ifdef DTLS_X509
-          " [-x file] [-r file] [-u file]"
-#endif /* DTLS_X509 */
-          " [-o file] [-p port] [-v num] [-c num] addr [port]\n"
-#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 */
-#ifdef DTLS_X509
-          "\t-x file\tread Client certificate from file\n"
-          "\t-r file\tread Client private key from file\n"
-          "\t-u file\tread CA public key from file\n"
-#endif /* DTLS_X509 */
-         "\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"
-          "\t-c num\t\tcipher suite (default: 1)\n"
-          "\t\t\t1: TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256 \n"
-          "\t\t\t2: TLS_PSK_WITH_AES_128_CCM_8\n"
-          "\t\t\t3: TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8\n"
-          "\t\t\t4: TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256\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 */
-#ifdef DTLS_X509
-  .get_x509_key = get_x509_key,
-  .verify_x509_cert = verify_x509_cert,
-  .get_x509_cert = get_x509_cert,
-  .is_x509_active = is_x509_active,
-#endif /* DTLS_X509 */
-
-};
-
-#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;
-  dtls_cipher_t selected_cipher = TLS_NULL_WITH_NULL_NULL;
-  dtls_cipher_enable_t ecdh_anon_enalbe = DTLS_CIPHER_ENABLE;
-  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:c:" PSK_OPTIONS X509_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 */
-#ifdef DTLS_X509
-    case 'x' :
-    {
-      ssize_t result = read_from_file(optarg, x509_client_cert, DTLS_MAX_CERT_SIZE);
-      if (result < 0)
-      {
-          dtls_warn("Cannot read Client certificate. Using default\n");
-      }
-      else
-      {
-          x509_client_cert_len = result;
-      }
-      break;
-    }
-    case 'r' :
-    {
-      ssize_t result = read_from_file(optarg, x509_client_priv, DTLS_PRIVATE_KEY_SIZE+1);
-      if (result < 0)
-      {
-          dtls_warn("Cannot read Client private key. Using default\n");
-      }
-      else
-      {
-          x509_client_priv_is_set = result;
-      }
-      break;
-    }
-    case 'u' :
-    {
-      ssize_t result = read_from_file(optarg, x509_ca_pub, DTLS_PUBLIC_KEY_SIZE+1);
-      if (result < 0)
-      {
-          dtls_warn("Cannot read CA public key. Using default\n");
-      }
-      else
-      {
-          x509_ca_pub_is_set = result;
-      }
-      break;
-    }
-#endif /* DTLS_X509 */
-    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;
-    case 'c':
-      if( strcmp(optarg, "1") == 0)
-      {
-          selected_cipher = TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256;
-          ecdh_anon_enalbe = DTLS_CIPHER_ENABLE;
-      }
-      else if( strcmp(optarg, "2") == 0)
-      {
-          selected_cipher = TLS_PSK_WITH_AES_128_CCM_8 ;
-          ecdh_anon_enalbe = DTLS_CIPHER_DISABLE;
-      }
-      else if( strcmp(optarg, "3") == 0)
-      {
-          selected_cipher = TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 ;
-          ecdh_anon_enalbe = DTLS_CIPHER_DISABLE;
-      }
-      else if( strcmp(optarg, "4") == 0)
-      {
-          selected_cipher = TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256;
-          ecdh_anon_enalbe = DTLS_CIPHER_DISABLE;
-      }
-      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);
-  }
-
-#ifdef DTLS_X509
-  if (x509_client_cert_len && x509_client_priv_is_set && x509_ca_pub_is_set)
-  {
-      x509_info_from_file = 1;
-  }
-  else if(!(x509_client_cert_len || x509_client_priv_is_set || x509_ca_pub_is_set))
-  {
-      x509_info_from_file = 0;
-  }
-  else
-  {
-      fprintf(stderr,"please set -x, -r, -u options simultaneously");
-      usage(argv[0], dtls_package_version());
-      exit(1);
-  }
-#endif /* DTLS_X509 */
-
-  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, OPTVAL_T(&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, OPTVAL_T(&on), sizeof(on) ) < 0) {
-#else /* IPV6_RECVPKTINFO */
-  if (setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, OPTVAL_T(&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);
-  }
-
-
-  /* select cipher suite */
-  dtls_select_cipher(dtls_context, selected_cipher);
-
-  /* enable/disable tls_ecdh_anon_with_aes_128_cbc_sha_256 */
-  dtls_enables_anon_ecdh(dtls_context, ecdh_anon_enalbe);
-
-  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
deleted file mode 100644 (file)
index 07acd18..0000000
+++ /dev/null
@@ -1,741 +0,0 @@
-
-/* This is needed for apple */
-#define __APPLE_USE_RFC_3542
-
-#include "iotivity_config.h"
-#include <assert.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#include <sys/types.h>
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#include <signal.h>
-#include <getopt.h>
-#include "platform_features.h"
-
-#include "tinydtls.h"
-#include "dtls.h"
-#include "debug.h"
-
-#ifdef DTLS_X509
-#define DTLS_PRIVATE_KEY_SIZE        (32)
-#define DTLS_PUBLIC_KEY_SIZE         (64)
-#endif
-
-#define DEFAULT_PORT 20220
-
-/**
- * @struct byte_array
- *
- * General purpose byte array structure.
- *
- * Contains pointer to array of bytes and it's length.
- */
-
-typedef struct
-{
-    uint8_t *data;    /**< Pointer to the byte array */
-    size_t len;      /**< Data size */
-} byte_array;
-
-
-/**@def BYTE_ARRAY_INITIALIZER
- *
- * Initializes of existing byte array pointer to \a NULL.
- */
-#undef BYTE_ARRAY_INITIALIZER
-#define BYTE_ARRAY_INITIALIZER {NULL, 0}
-
-#ifdef DTLS_X509
-#define X509_OPTIONS         "x:r:u:"
-#define SERVER_CRT_LEN 295
-static const unsigned char g_server_certificate[SERVER_CRT_LEN] = {
-        0x00, 0x01, 0x24,
-        0x30, 0x82, 0x01, 0x20, 0x30, 0x81, 0xc4, 0xa0,
-        0x03, 0x02, 0x01, 0x01, 0x02, 0x02, 0x02, 0x37,
-        0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
-        0x3d, 0x04, 0x03, 0x02, 0x05, 0x00, 0x30, 0x17,
-        0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04,
-        0x03, 0x0c, 0x0c, 0x4c, 0x6f, 0x63, 0x61, 0x6c,
-        0x20, 0x49, 0x53, 0x53, 0x55, 0x45, 0x52, 0x30,
-        0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x31, 0x30,
-        0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
-        0x17, 0x0d, 0x34, 0x39, 0x30, 0x31, 0x30, 0x31,
-        0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30,
-        0x17, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55,
-        0x04, 0x03, 0x0c, 0x0c, 0x4c, 0x6f, 0x63, 0x61,
-        0x6c, 0x20, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52,
-        0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
-        0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a,
-        0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
-        0x42, 0x00, 0x04, 0x07, 0x88, 0x10, 0xdc, 0x62,
-        0xd7, 0xe6, 0x9b, 0x7c, 0xad, 0x6e, 0x78, 0xb0,
-        0x5f, 0x9a, 0x00, 0x11, 0x74, 0x2c, 0x8b, 0xaf,
-        0x09, 0x65, 0x7c, 0x86, 0x8e, 0x55, 0xcb, 0x39,
-        0x55, 0x72, 0xc6, 0x65, 0x71, 0xcd, 0x03, 0xdc,
-        0x2a, 0x4f, 0x46, 0x5b, 0x14, 0xc8, 0x27, 0x74,
-        0xab, 0xf4, 0x1f, 0xc1, 0x35, 0x0d, 0x42, 0xbc,
-        0xc2, 0x9f, 0xb5, 0xc1, 0x79, 0xb6, 0x8b, 0xca,
-        0xdb, 0xff, 0x82, 0x30, 0x0c, 0x06, 0x08, 0x2a,
-        0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x05,
-        0x00, 0x03, 0x49, 0x00, 0x30, 0x46, 0x02, 0x21,
-        0x00, 0xb1, 0x81, 0x81, 0x92, 0x0e, 0x76, 0x7c,
-        0xeb, 0xf5, 0x37, 0xde, 0x27, 0xc4, 0x01, 0xc8,
-        0x96, 0xc3, 0xe5, 0x9f, 0x47, 0x7e, 0x25, 0x92,
-        0xa4, 0xba, 0x22, 0x25, 0xa3, 0x81, 0x19, 0xcf,
-        0x0d, 0x02, 0x21, 0x00, 0xca, 0x92, 0xbe, 0x79,
-        0xc7, 0x82, 0x84, 0x64, 0xc4, 0xc4, 0xf4, 0x3d,
-        0x69, 0x79, 0x68, 0xc0, 0xf1, 0xba, 0xaf, 0x6c,
-        0xbb, 0xdd, 0x54, 0x7d, 0x07, 0xe7, 0x53, 0x3b,
-        0xc3, 0x1b, 0x87, 0x04};
-
-//default server's key pair
-static const unsigned char x509_priv_key[] = {
-        0xaa, 0xa3, 0x46, 0xf1, 0x3c, 0x56, 0x5d, 0x08,
-        0x5e, 0x59, 0xba, 0x7f, 0xd2, 0x21, 0x62, 0xc6,
-        0xcc, 0x5d, 0xfa, 0x3f, 0xb5, 0x25, 0xa9, 0x89,
-        0x4f, 0x32, 0xe8, 0x2a, 0xe0, 0xee, 0x9b, 0x4c};
-
-static const unsigned char x509_pub_key_x[] = {
-        0x07, 0x88, 0x10, 0xdc, 0x62, 0xd7, 0xe6, 0x9b,
-        0x7c, 0xad, 0x6e, 0x78, 0xb0, 0x5f, 0x9a, 0x00,
-        0x11, 0x74, 0x2c, 0x8b, 0xaf, 0x09, 0x65, 0x7c,
-        0x86, 0x8e, 0x55, 0xcb, 0x39, 0x55, 0x72, 0xc6};
-
-static const unsigned char x509_pub_key_y[] = {
-        0x65, 0x71, 0xcd, 0x03, 0xdc, 0x2a, 0x4f, 0x46,
-        0x5b, 0x14, 0xc8, 0x27, 0x74, 0xab, 0xf4, 0x1f,
-        0xc1, 0x35, 0x0d, 0x42, 0xbc, 0xc2, 0x9f, 0xb5,
-        0xc1, 0x79, 0xb6, 0x8b, 0xca, 0xdb, 0xff, 0x82};
-
-//default CA pub key
-static const unsigned char x509_ca_pub_x[] = {
-        0x57, 0x94, 0x7f, 0x98, 0x7a, 0x02, 0x67, 0x09,
-        0x25, 0xc1, 0xcb, 0x5a, 0xf5, 0x46, 0xfb, 0xad,
-        0xf7, 0x68, 0x94, 0x8c, 0xa7, 0xe3, 0xf0, 0x5b,
-        0xc3, 0x6b, 0x5c, 0x9b, 0xd3, 0x7d, 0x74, 0x12
-};
-
-static const unsigned char x509_ca_pub_y[] = {
-        0xce, 0x68, 0xbc, 0x55, 0xf5, 0xf8, 0x1b, 0x3d,
-        0xef, 0xed, 0x1f, 0x2b, 0xd2, 0x69, 0x5d, 0xcf,
-        0x79, 0x16, 0xa6, 0xbd, 0x97, 0x96, 0x27, 0x60,
-        0x5d, 0xd1, 0xb7, 0x93, 0xa2, 0x4a, 0x62, 0x4d
-};
-
-static const unsigned char client_pub_key_x[] = {
-        0xe3, 0xd1, 0x67, 0x1e, 0xdc, 0x46, 0xf4, 0x19,
-        0x50, 0x15, 0x2e, 0x3a, 0x2f, 0xd8, 0x68, 0x6b,
-        0x37, 0x32, 0x84, 0x9e, 0x83, 0x81, 0xbf, 0x25,
-        0x5d, 0xbb, 0x18, 0x07, 0x3c, 0xbd, 0xf3, 0xab};
-
-static const unsigned char client_pub_key_y[] = {
-        0xd3, 0xbf, 0x53, 0x59, 0xc9, 0x1e, 0xce, 0x5b,
-        0x39, 0x6a, 0xe5, 0x60, 0xf3, 0x70, 0xdb, 0x66,
-        0xb6, 0x80, 0xcb, 0x65, 0x0b, 0x35, 0x2a, 0x62,
-        0x44, 0x89, 0x63, 0x64, 0x6f, 0x6f, 0xbd, 0xf0};
-
-static unsigned char x509_server_cert[DTLS_MAX_CERT_SIZE];
-static size_t x509_server_cert_len = 0;
-static unsigned char x509_server_priv[DTLS_PRIVATE_KEY_SIZE+1];
-static size_t x509_server_priv_is_set = 0;
-static unsigned char x509_ca_pub[DTLS_PUBLIC_KEY_SIZE+1];
-static size_t x509_ca_pub_is_set = 0;
-
-static int x509_info_from_file = 0;
-#endif /*DTLS_X509*/
-#ifdef DTLS_ECC
-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};
-#endif /*DTLS_ECC*/
-#if 0
-/* SIGINT handler: set quit to 1 for graceful termination */
-void
-handle_sigint(int signum) {
-  dsrv_stop(dsrv_get_context());
-}
-#endif
-
-#ifdef DTLS_X509
-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;
-}
-#endif /*DTLS_X509*/
-
-#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) {
-
-  (void)ctx;
-  (void)session;
-  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 < (int)(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_ecc_key_t **result) {
-    (void)ctx;
-    (void)session;
-  static const dtls_ecc_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) {
-  (void)ctx;
-  (void)session;
-  (void)other_pub_x;
-  (void)other_pub_y;
-  (void)key_size;
-  return 0;
-}
-#endif /* DTLS_ECC */
-
-#ifdef DTLS_X509
-static int
-get_x509_key(struct dtls_context_t *ctx,
-          const session_t *session,
-          const dtls_ecc_key_t **result) {
-    (void)ctx;
-    (void)session;
-  static dtls_ecc_key_t ecdsa_key = {
-    .curve = DTLS_ECDH_CURVE_SECP256R1,
-    .priv_key = x509_priv_key,
-    .pub_key_x = x509_pub_key_x,
-    .pub_key_y = x509_pub_key_y
-  };
-  if (x509_info_from_file)
-      ecdsa_key.priv_key = x509_server_priv;
-
-  *result = &ecdsa_key;
-  return 0;
-}
-
-static int
-get_x509_cert(struct dtls_context_t *ctx,
-               const session_t *session,
-               const unsigned char **cert,
-               size_t *cert_size)
-{
-    (void)ctx;
-    (void)session;
-    if (x509_info_from_file)
-    {
-        *cert = x509_server_cert;
-        *cert_size = x509_server_cert_len;
-    }
-    else
-    {
-        *cert = g_server_certificate;
-        *cert_size = SERVER_CRT_LEN;
-    }
-
-    return 0;
-}
-
-static int check_certificate(byte_array cert_der_code, byte_array ca_public_key)
-{
-    (void)cert_der_code;
-    (void)ca_public_key;
-    return 0;
-}
-
-static int verify_x509_cert(struct dtls_context_t *ctx, const session_t *session,
-                                  const unsigned char *cert, size_t cert_size,
-                                  unsigned char *x,
-                                  size_t x_size,
-                                  unsigned char *y,
-                                  size_t y_size)
-{
-    int ret;
-    const unsigned char *ca_pub_x;
-    const unsigned char *ca_pub_y;
-    byte_array cert_der_code = BYTE_ARRAY_INITIALIZER;
-    byte_array ca_public_key = BYTE_ARRAY_INITIALIZER;
-    unsigned char ca_pub_key[DTLS_PUBLIC_KEY_SIZE];
-    (void)ctx;
-    (void)session;
-
-    if (x509_info_from_file)
-    {
-        ca_pub_x = x509_ca_pub;
-        ca_pub_y = x509_ca_pub + DTLS_PUBLIC_KEY_SIZE/2;
-    }
-    else
-    {
-        ca_pub_x = x509_ca_pub_x;
-        ca_pub_y = x509_ca_pub_y;
-    }
-
-    cert_der_code.data = (uint8_t *)cert;
-    cert_der_code.len = cert_size;
-
-    ca_public_key.len = DTLS_PUBLIC_KEY_SIZE;
-    ca_public_key.data = ca_pub_key;
-    memcpy(ca_public_key.data, ca_pub_x, DTLS_PUBLIC_KEY_SIZE/2);
-    memcpy(ca_public_key.data + DTLS_PUBLIC_KEY_SIZE/2, ca_pub_y, DTLS_PUBLIC_KEY_SIZE/2);
-
-    memcpy(x, client_pub_key_x, x_size);
-    memcpy(y, client_pub_key_y, y_size);
-
-    ret = (int) check_certificate(cert_der_code, ca_public_key);
-
-  return -ret;
-}
-
-static int is_x509_active(struct dtls_context_t *ctx)
-{
-    (void)ctx;
-    return 0;
-}
-#endif /* DTLS_X509 */
-
-
-#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 ((int)(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 <bergmann@tzi.org>\n\n"
-         "usage: %s [-A address] [-p port] [-v num] [-a enable|disable]\n"
-#ifdef DTLS_X509
-      " [-x file] [-r file] [-u file]"
-#endif /* DTLS_X509 */
-         "\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"
-         "\t-a enable|disable\t(default: disable)\n"
-         "\t\t\t\tenable:enable TLS_ECDH_anon_with_AES_128_CBC_SHA_256\n"
-         "\t\t\t\tdisable:disable TLS_ECDH_anon_with_AES_128_CBC_SHA_256\n"
-#ifdef DTLS_X509
-      "\t-x file\tread Server certificate from file\n"
-      "\t-r file\tread Server private key from file\n"
-      "\t-u file\tread CA public key from file\n"
-#endif /* DTLS_X509 */
-      ,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 */
-#ifdef DTLS_X509
-  .get_x509_key = get_x509_key,
-  .verify_x509_cert = verify_x509_cert,
-  .get_x509_cert = get_x509_cert,
-  .is_x509_active = is_x509_active,
-#endif
-
-};
-
-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;
-  dtls_cipher_enable_t ecdh_anon_enalbe = DTLS_CIPHER_DISABLE;
-  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:a:")) != -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;
-    case 'a':
-      if( strcmp(optarg, "enable") == 0)
-          ecdh_anon_enalbe = DTLS_CIPHER_ENABLE;
-      break;
-#ifdef DTLS_X509
-    case 'x' :
-    {
-      ssize_t result = read_from_file(optarg, x509_server_cert, DTLS_MAX_CERT_SIZE);
-      if (result < 0)
-      {
-          dtls_warn("Cannot read Server certificate. Using default\n");
-      }
-      else
-      {
-          x509_server_cert_len = result;
-      }
-      break;
-    }
-    case 'r' :
-    {
-      ssize_t result = read_from_file(optarg, x509_server_priv, DTLS_PRIVATE_KEY_SIZE+1);
-      if (result < 0)
-      {
-          dtls_warn("Cannot read Server private key. Using default\n");
-      }
-      else
-      {
-          x509_server_priv_is_set = result;
-      }
-      break;
-    }
-    case 'u' :
-    {
-      ssize_t result = read_from_file(optarg, x509_ca_pub, DTLS_PUBLIC_KEY_SIZE+1);
-      if (result < 0)
-      {
-          dtls_warn("Cannot read CA public key. Using default\n");
-      }
-      else
-      {
-          x509_ca_pub_is_set = result;
-      }
-      break;
-    }
-#endif /* DTLS_X509 */
-    default:
-      usage(argv[0], dtls_package_version());
-      exit(1);
-    }
-  }
-
-  dtls_set_log_level(log_level);
-
-#ifdef DTLS_X509
-  if (x509_server_cert_len && x509_server_priv_is_set && x509_ca_pub_is_set)
-  {
-      x509_info_from_file = 1;
-  }
-  else if(!(x509_server_cert_len || x509_server_priv_is_set || x509_ca_pub_is_set))
-  {
-      x509_info_from_file = 0;
-  }
-  else
-  {
-      fprintf(stderr,"please set -x, -r, -u options simultaneously");
-      usage(argv[0], dtls_package_version());
-      exit(1);
-  }
-#endif /* DTLS_X509 */
-
-  /* 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, OPTVAL_T(&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, OPTVAL_T(&on), sizeof(on) ) < 0) {
-#else /* IPV6_RECVPKTINFO */
-  if (setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, OPTVAL_T(&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);
-
-  /* enable/disable tls_ecdh_anon_with_aes_128_cbc_sha_256 */
-  dtls_enables_anon_ecdh(the_context, ecdh_anon_enalbe);
-
-  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
deleted file mode 100644 (file)
index d0dc66f..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-#include <string.h>
-#include <netinet/in.h>
-
-#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
deleted file mode 100644 (file)
index b53dc8c..0000000
+++ /dev/null
@@ -1,478 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <getopt.h>
-#include <pcap/pcap.h>
-
-#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(dtls_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[DTLS_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
deleted file mode 100644 (file)
index d8d83d9..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-#include <stdio.h>
-
-#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
deleted file mode 100644 (file)
index 6ba5258..0000000
+++ /dev/null
@@ -1,862 +0,0 @@
-/* secure-server -- A (broken) DTLS server example
- *
- * Copyright (C) 2011 Olaf Bergmann <bergmann@tzi.org>
- *
- * 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 <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <sys/select.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <signal.h>
-
-#include <openssl/ssl.h>
-#include <openssl/bio.h>
-#include <openssl/err.h>
-#include <openssl/rand.h>
-
-#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 <assert.h>
-#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<len; i++)
-      printf("%c",buf[i]);
-  } if (len == 0) {            /* session closed? */
-#ifdef WITH_DTLS
-    if (check_close(ssl) <= 0) {
-      fprintf(stderr, "not closed\n");
-    }
-#endif
-  } else {
-#ifdef WITH_DTLS
-    err = SSL_get_error(ssl,len);
-    switch (err) {
-    case SSL_ERROR_WANT_READ:
-      fprintf(stderr, "SSL_ERROR_WANT_READ\n");
-      return 0;
-    case SSL_ERROR_WANT_WRITE:
-      fprintf(stderr, "SSL_ERROR_WANT_WRITE\n");
-      return 0;
-    default:
-      fprintf(stderr, "read: SSL error %d: %s\n", err,
-             ERR_error_string(err, NULL));
-      return 0;
-    }
-#else
-    perror("recv");
-#endif
-  }
-
-  return len;
-}
-
-int 
-_write(SSL_CTX *ctx, int sockfd) {
-  int res = 0;
-#ifdef WITH_DTLS
-  SSL *ssl;
-  int err;
-
-  ssl = get_ssl(ctx, sockfd, NULL, 1);
-  if (!ssl) {
-    fprintf(stderr, "no SSL object for writing");
-    return 0;
-  }
-  res = SSL_write(ssl, NULL, 0);
-  if (res < 0) {
-    /*
-    if (SSL_want_write(ssl))
-      return 0;
-    */
-    /* FIXME: check SSL_want_read(ssl) */
-
-    err = SSL_get_error(ssl,res);
-    fprintf(stderr,"SSL_write returned %d (%s)\n", err, ERR_error_string(err, NULL));
-  } else {
-    printf("SSL_write successful\n");
-  }
-#else
-#endif
-  
-  return res;
-}
-
-
-int 
-generate_cookie(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len) {
-  /* FIXME: generate secure client-specific cookie */
-#define DUMMYSTR "ABCDEFGHIJKLMNOP"
-  *cookie_len = strlen(DUMMYSTR);
-  memcpy(cookie, DUMMYSTR, *cookie_len);
-
-  return 1;
-}
-
-int 
-verify_cookie(SSL *ssl, unsigned char *cookie, unsigned int cookie_len) {
-  /* FIXME */
-  return 1;
-}
-
-enum { READ, WRITE };
-
-int
-main(int argc, char **argv) {
-  int sockfd = 0;
-  int on = 1;
-  struct sockaddr_in6 listen_addr = { AF_INET6, htons(20220), 0, IN6ADDR_ANY_INIT, 0 };
-  size_t addr_size = sizeof(struct sockaddr_in6);
-  fd_set fds[2];
-  int result, flags;
-  int idx, res = 0;
-  struct timeval timeout;
-  struct sigaction act, oact;
-  
-#ifdef WITH_DTLS
-  SSL_CTX *ctx;
-
-  memset(ssl_peer_storage, 0, sizeof(ssl_peer_storage));
-
-  SSL_load_error_strings();
-  SSL_library_init();
-  ctx = SSL_CTX_new(DTLSv1_server_method());
-
-  SSL_CTX_set_cipher_list(ctx, "ALL");
-  SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
-
-  res = SSL_CTX_use_certificate_file(ctx, SERVER_CERT_PEM, SSL_FILETYPE_PEM);
-  if (res != 1) {
-    fprintf(stderr, "cannot read server certificate from file '%s' (%s)\n", 
-           SERVER_CERT_PEM, ERR_error_string(res,NULL));
-    goto end;
-  }
-
-  res = SSL_CTX_use_PrivateKey_file(ctx, SERVER_KEY_PEM, SSL_FILETYPE_PEM);
-  if (res != 1) {
-    fprintf(stderr, "cannot read server key from file '%s' (%s)\n", 
-           SERVER_KEY_PEM, ERR_error_string(res,NULL));
-    goto end;
-  }
-
-  res = SSL_CTX_check_private_key (ctx);
-  if (res != 1) {
-    fprintf(stderr, "invalid private key\n");
-    goto end;
-  }
-
-  res = SSL_CTX_load_verify_locations(ctx, CA_CERT_PEM, NULL);
-  if (res != 1) {
-    fprintf(stderr, "cannot read ca file '%s'\n", CA_CERT_PEM);
-    goto end;
-  }
-
-  /* Client has to authenticate */
-
-  /* Client has to authenticate */
-  SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, NULL);
-
-  SSL_CTX_set_read_ahead(ctx, 1); /* disable read-ahead */
-  SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie);
-  SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie);
-
-  SSL_CTX_use_psk_identity_hint(ctx, "Enter password for CoAP-Gateway");
-  SSL_CTX_set_psk_server_callback(ctx, psk_server_callback);
-
-  SSL_CTX_set_info_callback(ctx, info_callback);
-#endif
-
-  sockfd = socket(listen_addr.sin6_family, SOCK_DGRAM, 0);
-  if ( sockfd < 0 ) {
-    perror("socket");
-    return -1;
-  }
-
-  if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) ) < 0)
-    perror("setsockopt SO_REUSEADDR");
-
-  flags = fcntl(sockfd, F_GETFL, 0);
-  if (flags < 0 || fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) < 0) {
-    perror("fcntl");
-    return -1;
-  }
-
-  on = 1;
-  if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on) ) < 0) {
-    perror("setsockopt IPV6_PKTINFO");
-  }
-
-  if (bind (sockfd, (const struct sockaddr *)&listen_addr, addr_size) < 0) {
-    perror("bind");
-    res = -2;
-    goto end;
-  }
-
-  act.sa_handler = handle_sigint;
-  sigemptyset(&act.sa_mask);
-  act.sa_flags = 0;
-  sigaction(SIGINT, &act, &oact);
-
-  while (!quit) {
-    FD_ZERO(&fds[READ]);
-    FD_ZERO(&fds[WRITE]);
-    FD_SET(sockfd, &fds[READ]);
-
-    timeout.tv_sec = 1;
-    timeout.tv_usec = 0;
-    result = select( FD_SETSIZE, &fds[READ], &fds[WRITE], 0, &timeout);
-
-    if (result < 0) {          /* error */
-      if (errno != EINTR)
-       perror("select");
-    } else if (result > 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
deleted file mode 100644 (file)
index 7921b08..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/* tinydtls.h.  Generated from tinydtls.h.in by configure.  */
-/* tinydtls -- a very basic DTLS implementation
- *
- * Copyright (C) 2011--2014 Olaf Bergmann <bergmann@tzi.org>
- * Copyright (C) 2013 Hauke Mehrtens <hauke@hauke-m.de>
- *
- * 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 */
-#define DTLS_ECC 1
-
-/** 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 */
-
-/** Define to 1 if building with X.509 support */
-#define DTLS_X509 1
-
-/** Define to 1 if building with Hardware Abstraction Layer */
-#define DTLS_CRYPTO_HAL 0
-
-#ifndef INLINE_API
-#  if defined(__cplusplus)
-#    define INLINE_API inline
-#  else
-#    ifdef _MSC_VER
-#      define INLINE_API static __inline
-#    else
-#      define INLINE_API static inline
-#    endif
-#  endif
-#endif
-
-#endif /* _DTLS_TINYDTLS_H_ */
diff --git a/extlibs/tinydtls/tinydtls.h.in b/extlibs/tinydtls/tinydtls.h.in
deleted file mode 100644 (file)
index a267ad6..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/* tinydtls -- a very basic DTLS implementation
- *
- * Copyright (C) 2011--2014 Olaf Bergmann <bergmann@tzi.org>
- * Copyright (C) 2013 Hauke Mehrtens <hauke@hauke-m.de>
- *
- * 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
-
-/** Define to 1 if building with X.509 support */
-#undef DTLS_X509
-
-/** Define to 1 if building with crypto hardware abstraction support */
-#undef DTLS_CRYPTO_HAL
-
-#endif /* _DTLS_TINYDTLS_H_ */
diff --git a/extlibs/tinydtls/uthash.h b/extlibs/tinydtls/uthash.h
deleted file mode 100644 (file)
index 5125cc6..0000000
+++ /dev/null
@@ -1,972 +0,0 @@
-/*
-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 UTHASH_H
-#define UTHASH_H
-
-#include <string.h>   /* memcmp,strlen */
-#include <stddef.h>   /* 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 <inttypes.h>   /* 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 <unistd.h> 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
deleted file mode 100644 (file)
index dd72b7d..0000000
+++ /dev/null
@@ -1,490 +0,0 @@
-/*
-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 UTLIST_H
-#define 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 */
-
index c90d7b3..9532294 100755 (executable)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash -e
 
 spec=`ls tools/tizen/*.spec`
 version=`rpm --query --queryformat '%{version}\n' --specfile $spec`
@@ -32,7 +32,6 @@ rm -rf $sourcedir/tmp/extlibs/tinycbor/tinycbor/.git
 cp -R ./extlibs/cjson $sourcedir/tmp/extlibs
 cp -R ./extlibs/mbedtls $sourcedir/tmp/extlibs
 cp -R ./extlibs/gtest $sourcedir/tmp/extlibs
-cp -R ./extlibs/tinydtls $sourcedir/tmp/extlibs
 cp -LR ./extlibs/sqlite3 $sourcedir/tmp/extlibs
 cp -R ./extlibs/timer $sourcedir/tmp/extlibs
 cp -R ./extlibs/rapidxml $sourcedir/tmp/extlibs
@@ -55,40 +54,28 @@ cp -R $sourcedir/iotivity.pc.in $sourcedir/tmp
 
 cd $sourcedir/tmp
 
-withtcp=0
-withcloud=0
-withproxy=0
-withmq=OFF
-rdmode=CLIENT
-secured=0
+secured=1
+gbscommand="gbs build -A armv7l "
+
 for ARGUMENT_VALUE in $*
 do
    echo $ARGUMENT_VALUE
-   if [ "WITH_TCP" = $ARGUMENT_VALUE ];then
-       withtcp=1
-   fi
-
-   if [ "WITH_CLOUD" = $ARGUMENT_VALUE ];then
-       withcloud=1
-   fi
-
-   if [ "WITH_PROXY" = $ARGUMENT_VALUE ];then
-       withproxy=1
-   fi
-
-   if [ "WITH_MQ" = $ARGUMENT_VALUE ];then
-       withmq=PUB,SUB,BROKER
-   fi
-
-   if [ "RD_MODE" = $ARGUMENT_VALUE ];then
-       rdmode=CLIENT,SERVER
-   fi
-
-   if [ "SECURED" = $ARGUMENT_VALUE ];then
-       secured=1
+   if [[ "$ARGUMENT_VALUE" = *"="* ]]; then
+      optionname=$(echo $ARGUMENT_VALUE | cut -f1 -d=)
+      optionvalue=$(echo $ARGUMENT_VALUE | cut -f2 -d=)
+      echo -- "# $optionname $optionvalue"
+      gbscommand=${gbscommand}" --define '$optionname $optionvalue'"
+
+      if [ "SECURED" = "$optionname" ]; then
+         secured=$optionvalue
+      fi
+   else
+      echo "'$ARGUMENT_VALUE' does not contain '='";
    fi
 done
 
+gbscommand="${gbscommand} -B ~/GBS-ROOT-OIC --include-all --repository ./"
+
 if [ $secured -eq 1 ];then
   echo `pwd`
   # Prepare mbedTLS dependency
@@ -108,7 +95,6 @@ if [ ! -d .git ]; then
 fi
 
 echo "Calling core gbs build command"
-gbscommand="gbs build -A armv7l --define 'WITH_TCP $withtcp' --define 'WITH_CLOUD $withcloud' --define 'WITH_PROXY $withproxy' --define 'WITH_MQ $withmq' --define 'RD_MODE $rdmode' --define 'SECURED $secured' -B ~/GBS-ROOT-OIC --include-all --repository ./"
 echo $gbscommand
 if eval $gbscommand; then
     echo "Build is successful"
index ccd2cfe..e7ae88d 100644 (file)
@@ -11,7 +11,7 @@ Description: IoTivity is an open source reference implementation of the OIC stan
 Version: @VERSION@
 URL: https://www.iotivity.org
 Requires:
-Libs: -L${libdir} -loc -loc_logger -loc_logger_core -loctbstack -lconnectivity_abstraction @LIBS@
+Libs: -L${libdir} -loc -loc_logger -loc_logger_core -loctbstack -lconnectivity_abstraction -lresource_directory @LIBS@
 Cflags: -I${includedir}/resource \
                        -I${includedir}/c_common \
                        -I${svcincludedir}/easy-setup \
diff --git a/packaging/iotivity.pc.in b/packaging/iotivity.pc.in
new file mode 100644 (file)
index 0000000..017cf86
--- /dev/null
@@ -0,0 +1,24 @@
+# Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=${prefix}
+libdir=@LIB_INSTALL_DIR@
+includedir=${prefix}/include
+svcincludedir=${includedir}/service
+
+Name: iotivity
+Description: IoTivity is an open source reference implementation of the OIC standard specifications. This includes the libs for resource c and c++ sdk apis.
+Version: @VERSION@
+URL: https://www.iotivity.org
+Requires:
+Libs: -L${libdir} -loc -loc_logger -loc_logger_core -loctbstack -lconnectivity_abstraction -lresource_directory -locpmapi -locprovision @LIBS@
+Cflags: -I${includedir}/resource \
+                       -I${includedir}/c_common \
+                       -I${svcincludedir}/easy-setup \
+                       -I${svcincludedir}/notification \
+                       -I${svcincludedir}/resource-encapsulation \
+                       -I${svcincludedir}/resource-container \
+                       -I${svcincludedir}/resource-hosting \
+                       -I${svcincludedir}/resource-directory \
+                       -I${svcincludedir}/things-manager \
+                       @DEFINES@
old mode 100644 (file)
new mode 100755 (executable)
index ce1866b..e7aa8bf
@@ -1,7 +1,7 @@
 Name: iotivity
 Version: 1.2.1
 Release: 0
-Summary: IoT Connectivity sponsored by the OCF
+Summary: Samsung IoT Connectivity
 Group: Network & Connectivity / IoT Connectivity
 License: Apache-2.0
 URL: https://www.iotivity.org/
@@ -9,13 +9,31 @@ Source0: http://mirrors.kernel.org/%{name}/%{version}/%{name}-%{version}.tar.gz
 Source1001: %{name}.manifest
 Source1002: %{name}-test.manifest
 
-# Use the official macros that are defined in Project Config (build.tizen.org).
-# https://build.tizen.org/project/prjconf?project=<project_name>
-#  - tizen_version_major 4
-#  - tizen_version_minor 0
-# For backward compatibility. Not needed (always true) in unified environment.
-#  - unified (undefined)
+%if 0%{?tizen:1}
+%define TARGET_OS tizen
+%else
+%define TARGET_OS linux
+%endif
+
+%if "%{tizen}" == "2.3"
+%define TARGET_TRANSPORT IP
+%endif
+
+%if "%{profile}" == "ivi"
 %define TARGET_TRANSPORT IP
+%endif
+
+%if "%{TARGET_OS}" == "linux"
+%define TARGET_TRANSPORT IP
+%endif
+
+%define JOB "-j4"
+%if 0%{?speedpython}
+%define JOB %{?_smp_mflags}
+%endif
+%if 0%{?speedpython:1} && 0%{?en_speedpython:1}
+%en_speedpython
+%endif
 
 # default is RELEASE mode.
 # If DEBUG mode is needed, please use tizen_build_devel_mode
@@ -28,11 +46,9 @@ Source1002: %{name}-test.manifest
 %endif
 
 %ifarch armv7l armv7hl armv7nhl armv7tnhl armv7thl
-BuildRequires: python-accel-armv7l-cross-arm
 %define TARGET_ARCH "armeabi-v7a"
 %endif
 %ifarch aarch64
-BuildRequires: python-accel-aarch64-cross-aarch64
 %define TARGET_ARCH "arm64"
 %endif
 %ifarch x86_64
@@ -44,6 +60,16 @@ BuildRequires: python-accel-aarch64-cross-aarch64
 
 %define ex_install_dir %{buildroot}%{_bindir}
 
+%if 0%{?tizen_version_major} < 3
+%if ! 0%{?license:0}
+%define license %doc
+%endif
+
+%if ! 0%{?manifest:0}
+%define manifest %doc
+%endif
+%endif
+
 # Default values to be eventually overiden BEFORE or as gbs params:
 %{!?ES_TARGET_ENROLLEE: %define ES_TARGET_ENROLLEE tizen}
 %{!?LOGGING: %define LOGGING 1}
@@ -53,12 +79,17 @@ BuildRequires: python-accel-aarch64-cross-aarch64
 %{!?SECURED: %define SECURED 1}
 %{!?TARGET_ARCH: %define TARGET_ARCH %{_arch}}
 %{!?TARGET_OS: %define TARGET_OS tizen}
-%{!?TARGET_TRANSPORT: %define TARGET_TRANSPORT IP,BT}
+%{!?TARGET_TRANSPORT: %define TARGET_TRANSPORT IP,BLE}
 %{!?VERBOSE: %define VERBOSE 1}
 %{!?WITH_CLOUD: %define WITH_CLOUD 1}
 %{!?WITH_MQ: %define WITH_MQ OFF}
 %{!?WITH_PROXY: %define WITH_PROXY 0}
 %{!?WITH_TCP: %define WITH_TCP 1}
+%{!?RD_MODE: %define RD_MODE CLIENT}
+%{!?BLE_CUSTOM_ADV: %define BLE_CUSTOM_ADV False}
+%{!?BLE_DIVISION: %define BLE_DIVISION VD}
+%{!?BLE_TIZEN_30: %define BLE_TIZEN_30 True}
+%{!?MULTIPLE_OWNER: %define MULTIPLE_OWNER 0}
 
 BuildRequires:  expat-devel
 BuildRequires:  python, libcurl-devel
@@ -75,6 +106,7 @@ BuildRequires:  pkgconfig(sqlite3)
 BuildRequires:  gettext-tools
 BuildRequires:  pkgconfig(dlog)
 BuildRequires:  pkgconfig(capi-network-connection)
+BuildRequires:  pkgconfig(capi-network-wifi)
 BuildRequires:  pkgconfig(capi-network-bluetooth) >= 0.1.52
 %else
 %if 0%{?fedora:1}
@@ -132,7 +164,7 @@ cp %{SOURCE1001} ./%{name}-test.manifest
 %endif
 
 %build
-scons %{?_smp_mflags} --prefix=%{_prefix} \
+scons %{JOB} --prefix=%{_prefix} \
     ES_TARGET_ENROLLEE=%{ES_TARGET_ENROLLEE} \
     LIB_INSTALL_DIR=%{_libdir} \
     LOGGING=%{LOGGING} \
@@ -148,11 +180,20 @@ scons %{?_smp_mflags} --prefix=%{_prefix} \
     WITH_MQ=%{WITH_MQ} \
     WITH_PROXY=%{WITH_PROXY} \
     WITH_TCP=%{WITH_TCP} \
+    RD_MODE=%{RD_MODE} \
+    BLE_CUSTOM_ADV=%{BLE_CUSTOM_ADV} \
+    BLE_DIVISION=%{BLE_DIVISION} \
+    BLE_TIZEN_30=%{BLE_TIZEN_30} \
+    MULTIPLE_OWNER=%{MULTIPLE_OWNER} \
     #eol
 
 
 
 %install
+%if 0%{?tizen_version_major} < 3
+mkdir -p %{buildroot}/%{_datadir}/license
+cp LICENSE %{buildroot}/%{_datadir}/license/%{name}
+%endif
 rm -rf %{buildroot}
 CFLAGS="${CFLAGS:-%optflags}" ; export CFLAGS ;
 scons install --install-sandbox=%{buildroot} --prefix=%{_prefix} \
@@ -171,32 +212,38 @@ scons install --install-sandbox=%{buildroot} --prefix=%{_prefix} \
     WITH_MQ=%{WITH_MQ} \
     WITH_PROXY=%{WITH_PROXY} \
     WITH_TCP=%{WITH_TCP} \
+    RD_MODE=%{RD_MODE} \
+    BLE_CUSTOM_ADV=%{BLE_CUSTOM_ADV} \
+    BLE_DIVISION=%{BLE_DIVISION} \
+    BLE_TIZEN_30=%{BLE_TIZEN_30} \
+    MULTIPLE_OWNER=%{MULTIPLE_OWNER} \
     #eol
 
 mkdir -p %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/examples/OICMiddle/OICMiddle %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/devicediscoveryclient %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/devicediscoveryserver %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/fridgeclient %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/fridgeserver %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/garageclient %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/garageserver %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/groupclient %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/groupserver %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/lightserver %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/presenceclient %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/presenceserver %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/roomclient %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/roomserver %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/simpleclient %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/simpleclientHQ %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/simpleclientserver %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/simpleserver %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/simpleserverHQ %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/threadingsample %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/oic_svr_db_server.dat %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/oic_svr_db_client.dat %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/libcoap.a %{buildroot}%{_libdir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/examples/OICMiddle/OICMiddle %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/devicediscoveryclient %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/devicediscoveryserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/fridgeclient %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/fridgeserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/garageclient %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/garageserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/groupclient %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/groupserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/lightserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/presenceclient %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/presenceserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/roomclient %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/roomserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/simpleclient %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/simpleclientHQ %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/simpleclientserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/simpleserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/simpleserverHQ %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/threadingsample %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/oic_svr_db_server.dat %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/oic_svr_db_client.dat %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/libcoap.a %{buildroot}%{_libdir}
+cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/lib*.a  %{buildroot}%{_libdir}
 
 %if 0%{?WITH_PROXY} == 1
 mkdir -p %{ex_install_dir}/proxy-sample
@@ -207,7 +254,7 @@ cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/service/coap-http-proxy/samples
 mkdir -p %{ex_install_dir}/provisioning
 mkdir -p %{ex_install_dir}/provision-sample
 
-
+cp -R ./extlibs/mbedtls/mbedtls/include/mbedtls/ %{buildroot}%{_includedir}/mbedtls
 cp ./resource/csdk/security/include/*.h %{buildroot}%{_includedir}
 cp ./resource/csdk/connectivity/api/*.h %{buildroot}%{_includedir}/
 cp ./resource/csdk/security/include/internal/*.h %{buildroot}%{_includedir}/
@@ -219,12 +266,21 @@ cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/csdk/security/provisio
 cp ./resource/csdk/security/provisioning/sample/oic_svr_db_server_justworks.dat %{ex_install_dir}/provision-sample/
 cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/csdk/security/provisioning/sample/sampleserver_randompin %{ex_install_dir}/provision-sample/
 cp ./resource/csdk/security/provisioning/sample/oic_svr_db_server_randompin.dat %{ex_install_dir}/provision-sample/
+
 %endif
 
 cp resource/c_common/*.h %{buildroot}%{_includedir}
+cp resource/c_common/ocrandom/include/*.h %{buildroot}%{_includedir}
+cp resource/c_common/oic_string/include/*.h %{buildroot}%{_includedir}
+cp resource/c_common/oic_malloc/include/*.h %{buildroot}%{_includedir}
 cp resource/csdk/stack/include/*.h %{buildroot}%{_includedir}
 cp resource/csdk/logger/include/*.h %{buildroot}%{_includedir}
 
+cp service/easy-setup/inc/*.h %{buildroot}%{_includedir}
+cp service/easy-setup/enrollee/inc/*.h %{buildroot}%{_includedir}
+cp service/easy-setup/mediator/richsdk/inc/*.h %{buildroot}%{_includedir}
+cp service/easy-setup/enrollee/inc/samsung/*.h %{buildroot}%{_includedir}
+
 install -d %{buildroot}%{_includedir}/iotivity
 ln -fs ../resource %{buildroot}%{_includedir}/iotivity/
 ln -fs ../service %{buildroot}%{_includedir}/iotivity/
@@ -240,13 +296,18 @@ rm -rfv out %{buildroot}/out %{buildroot}/${HOME} ||:
 %files
 %manifest %{name}.manifest
 %defattr(-,root,root,-)
+%if 0%{?tizen_version_major} < 3
+%{_datadir}/license/%{name}
+%else
 %license LICENSE
+%endif
 %{_libdir}/liboc.so
 %{_libdir}/liboc_logger.so
 %{_libdir}/liboc_logger_core.so
 %{_libdir}/liboctbstack.so
 %{_libdir}/libconnectivity_abstraction.so
 %if 0%{?SECURED} == 1
+%{_libdir}/libmbedtls.so
 %{_libdir}/libocpmapi.so
 %{_libdir}/libocprovision.so
 %{_libdir}/oic_svr_db_server.dat
@@ -255,13 +316,17 @@ rm -rfv out %{buildroot}/out %{buildroot}/${HOME} ||:
 %files service
 %manifest %{name}.manifest
 %defattr(-,root,root,-)
+%if 0%{?tizen_version_major} < 3
+%{_datadir}/license/%{name}
+%else
 %license LICENSE
-%{_libdir}/libBMISensorBundle.so
-%{_libdir}/libDISensorBundle.so
-%{_libdir}/libHueBundle.so
+%endif
+#%{_libdir}/libBMISensorBundle.so
+#%{_libdir}/libDISensorBundle.so
+#%{_libdir}/libHueBundle.so
 %{_libdir}/librcs_client.so
 %{_libdir}/librcs_common.so
-%{_libdir}/librcs_container.so
+#%{_libdir}/librcs_container.so
 %{_libdir}/librcs_server.so
 %{_libdir}/libresource_directory.so
 %{_libdir}/libESEnrolleeSDK.so
@@ -277,12 +342,23 @@ rm -rfv out %{buildroot}/out %{buildroot}/${HOME} ||:
 %files test
 %manifest %{name}-test.manifest
 %defattr(-,root,root,-)
+%if 0%{?tizen_version_major} < 3
+%{_datadir}/license/%{name}
+%else
 %license LICENSE
+%endif
 %{_bindir}/*
 
 %files devel
 %defattr(-,root,root,-)
+%if 0%{?tizen_version_major} < 3
+%{_datadir}/license/%{name}
+%else
 %license LICENSE
-%{_libdir}/lib*.a
+%endif
+%if 0%{?SECURED} == 1
+%{_libdir}/libmbedtls.so
+%endif
+%{_libdir}/*.a
 %{_libdir}/pkgconfig/%{name}.pc
 %{_includedir}/*
diff --git a/packaging/snapshot_history.txt b/packaging/snapshot_history.txt
new file mode 100755 (executable)
index 0000000..32b684b
--- /dev/null
@@ -0,0 +1,2901 @@
+http://suprem.sec.samsung.net/jira/browse/CONPRO-1098
+
+commit_info_2017-09-27-rev1.txt
+
+commit_id: c5a00fbacec687068f446f44c076e6c27eb23357
+
+cherrypick_cmd_id: 77aabf1039177545fc1aa822e6ef5e8347d6a0e8
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-1088
+
+commit_info_2017-09-20.txt
+
+commit_id: 4328750e7e469bcee4d1f762c0e0d5d53cfadf35
+
+cherrypick_cmd_id: e3232d8f70b61d90c1158c441b3a9142c21300c0
+cherrypick_cmd_id: b5f7b82e60fb89e389d3568da0ba1fc563c596cd
+cherrypick_cmd_id: 600c47968e1bfa66f24dddc3b109064e619e3136
+cherrypick_cmd_id: c5aa01bea3faa9cd766dddca2fba82819a8abe17
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-1082
+
+commit_info_2017-09-13.txt
+
+commit_id: b16a3d33bfd0affdecdd65e0bf0365b617ba0f7a
+
+cherrypick_cmd_id: e3232d8f70b61d90c1158c441b3a9142c21300c0
+cherrypick_cmd_id: b5f7b82e60fb89e389d3568da0ba1fc563c596cd
+cherrypick_cmd_id: 600c47968e1bfa66f24dddc3b109064e619e3136
+cherrypick_cmd_id: c5aa01bea3faa9cd766dddca2fba82819a8abe17
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-1076
+
+commit_info_2017-09-06.txt
+
+commit_id: e6ec6fb1e64f582c8011d84a1419f5e8728364d1
+
+cherrypick_cmd_id: e3232d8f70b61d90c1158c441b3a9142c21300c0
+cherrypick_cmd_id: b5f7b82e60fb89e389d3568da0ba1fc563c596cd
+cherrypick_cmd_id: 600c47968e1bfa66f24dddc3b109064e619e3136
+cherrypick_cmd_id: c5aa01bea3faa9cd766dddca2fba82819a8abe17
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-1069
+
+commit_info_2017-08-30_rev1.txt
+
+commit_id: e6ec6fb1e64f582c8011d84a1419f5e8728364d1
+
+cherrypick_cmd_id: e3232d8f70b61d90c1158c441b3a9142c21300c0
+cherrypick_cmd_id: b5f7b82e60fb89e389d3568da0ba1fc563c596cd
+cherrypick_cmd_id: 600c47968e1bfa66f24dddc3b109064e619e3136
+cherrypick_cmd_id: c5aa01bea3faa9cd766dddca2fba82819a8abe17
+----------------------------------------------------------------------------------------------------------------------------------
+
+http://suprem.sec.samsung.net/jira/browse/CONPRO-1063
+
+commit_info_2017-08-23_rev1.txt
+
+commit_id: 0ed11c039b711fa056065f75f2bedb775039a954
+
+cherrypick_cmd_id: e3232d8f70b61d90c1158c441b3a9142c21300c0
+cherrypick_cmd_id: b5f7b82e60fb89e389d3568da0ba1fc563c596cd
+cherrypick_cmd_id: 600c47968e1bfa66f24dddc3b109064e619e3136
+cherrypick_cmd_id: c5aa01bea3faa9cd766dddca2fba82819a8abe17
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-1059
+
+commit_info_2017-08-16_rev1.txt
+
+commit_id: 7c5cca3016e5e59b7a87d3a9500d3b3807015183
+
+cherrypick_cmd_id: e3232d8f70b61d90c1158c441b3a9142c21300c0
+cherrypick_cmd_id: b5f7b82e60fb89e389d3568da0ba1fc563c596cd
+cherrypick_cmd_id: 600c47968e1bfa66f24dddc3b109064e619e3136
+cherrypick_cmd_id: c5aa01bea3faa9cd766dddca2fba82819a8abe17
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-1053
+
+commit_info_2017-08-09_rev1.txt
+
+commit_id: f58313fba7e09873fc32adadc6d991cfbaa83440
+
+cherrypick_cmd_id: e3232d8f70b61d90c1158c441b3a9142c21300c0
+cherrypick_cmd_id: b5f7b82e60fb89e389d3568da0ba1fc563c596cd
+cherrypick_cmd_id: 600c47968e1bfa66f24dddc3b109064e619e3136
+cherrypick_cmd_id: c5aa01bea3faa9cd766dddca2fba82819a8abe17
+----------------------------------------------------------------------------------------------------------------------------------
+Rollback to snapshot(2017-07-19)
+http://suprem.sec.samsung.net/jira/browse/CONPRO-1034
+
+commit_info_2017-07-19_rev1.txt
+----------------------------------------------------------------------------------------------------------------------------------
+
+http://suprem.sec.samsung.net/jira/browse/CONPRO-1047
+
+commit_info_2017-08-02_rev1.txt
+
+commit_id: b57dea28907435ec97a8be8ce5692794a2792db6
+
+cherrypick_cmd_id: e3232d8f70b61d90c1158c441b3a9142c21300c0
+cherrypick_cmd_id: b5f7b82e60fb89e389d3568da0ba1fc563c596cd
+cherrypick_cmd_id: 600c47968e1bfa66f24dddc3b109064e619e3136
+cherrypick_cmd_id: c5aa01bea3faa9cd766dddca2fba82819a8abe17
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-1040
+
+commit_info_2017-07-26_rev1.txt
+
+commit_id: 7ed9ad2e7e080d26ca9654f3c333ec003a00cadf
+
+cherrypick_cmd_id: e3232d8f70b61d90c1158c441b3a9142c21300c0
+cherrypick_cmd_id: b5f7b82e60fb89e389d3568da0ba1fc563c596cd
+cherrypick_cmd_id: 600c47968e1bfa66f24dddc3b109064e619e3136
+cherrypick_cmd_id: c5aa01bea3faa9cd766dddca2fba82819a8abe17
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-1034
+
+commit_info_2017-07-19_rev1.txt
+
+commit_id: 78570f8488bbf239edbdc40e0ab8d6601ca11a95
+
+cherrypick_cmd_id: e3232d8f70b61d90c1158c441b3a9142c21300c0
+cherrypick_cmd_id: b5f7b82e60fb89e389d3568da0ba1fc563c596cd
+cherrypick_cmd_id: 600c47968e1bfa66f24dddc3b109064e619e3136
+cherrypick_cmd_id: c5aa01bea3faa9cd766dddca2fba82819a8abe17
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-1030
+
+commit_info_2017-07-12_rev1.txt 
+
+commit_id: 4cde94f242ab1e9fcdd5ee1f14387e5007390cc5
+
+cherrypick_cmd_id: e3232d8f70b61d90c1158c441b3a9142c21300c0
+cherrypick_cmd_id: b5f7b82e60fb89e389d3568da0ba1fc563c596cd
+cherrypick_cmd_id: 600c47968e1bfa66f24dddc3b109064e619e3136
+cherrypick_cmd_id: c5aa01bea3faa9cd766dddca2fba82819a8abe17
+
+----------------------------------------------------------------------------------------------------------------------------------
+
+http://suprem.sec.samsung.net/jira/browse/CONPRO-1024
+
+commit_info_2017-07-05_rev1.txt
+
+commit_id: fc53dac7398fdb133a983bba4f97523946557c8a
+
+cherrypick_cmd_id: e3232d8f70b61d90c1158c441b3a9142c21300c0
+cherrypick_cmd_id: b5f7b82e60fb89e389d3568da0ba1fc563c596cd
+cherrypick_cmd_id: 600c47968e1bfa66f24dddc3b109064e619e3136
+cherrypick_cmd_id: c5aa01bea3faa9cd766dddca2fba82819a8abe17
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-1020
+
+commit_info_2017-06-28_rev2.txt
+
+commit_id: 8cc6f017b9917d423af006be856ac8c8fe34c40f
+
+cherrypick_cmd_id: e3232d8f70b61d90c1158c441b3a9142c21300c0
+cherrypick_cmd_id: b5f7b82e60fb89e389d3568da0ba1fc563c596cd
+cherrypick_cmd_id: 600c47968e1bfa66f24dddc3b109064e619e3136
+cherrypick_cmd_id: c5aa01bea3faa9cd766dddca2fba82819a8abe17
+cherrypick_cmd_id: 873bef7216f1d84580fcf4ba50d22b11b4e0cdc1
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-1004
+
+commit_info_2017-06-21.txt
+
+commit_id: 862669776b11d359f1f45af30a110f5f785efa64
+
+cherrypick_cmd_id: e3232d8f70b61d90c1158c441b3a9142c21300c0
+cherrypick_cmd_id: b5f7b82e60fb89e389d3568da0ba1fc563c596cd
+cherrypick_cmd_id: 600c47968e1bfa66f24dddc3b109064e619e3136
+cherrypick_cmd_id: c5aa01bea3faa9cd766dddca2fba82819a8abe17
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-998
+
+commit_info_2017-06-14_rev1.txt
+
+commit_id: 8855cc4b03c72a447bd1b4dc24035ec3a8afaab6
+
+cherrypick_cmd_id: e3232d8f70b61d90c1158c441b3a9142c21300c0
+cherrypick_cmd_id: b5f7b82e60fb89e389d3568da0ba1fc563c596cd
+cherrypick_cmd_id: 600c47968e1bfa66f24dddc3b109064e619e3136
+cherrypick_cmd_id: c5aa01bea3faa9cd766dddca2fba82819a8abe17
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-995
+
+commit_info_2017-06-07_rev1.txt
+
+commit_id: ef565cb617b7f18a47d301b4b2fbf0cc629c9853
+
+cherrypick_cmd_id: e3232d8f70b61d90c1158c441b3a9142c21300c0
+cherrypick_cmd_id: b5f7b82e60fb89e389d3568da0ba1fc563c596cd
+cherrypick_cmd_id: 600c47968e1bfa66f24dddc3b109064e619e3136
+cherrypick_cmd_id: c5aa01bea3faa9cd766dddca2fba82819a8abe17
+cherrypick_cmd_id: 14eca13063fbac470942a2b5168691b51b559e97
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-987
+
+commit_info_2017-05-31_rev2.txt
+
+commit_id: 569fd47d478292837e32d2d2d06527cca8dac7e3
+
+cherrypick_cmd_id: e3232d8f70b61d90c1158c441b3a9142c21300c0
+cherrypick_cmd_id: b5f7b82e60fb89e389d3568da0ba1fc563c596cd
+cherrypick_cmd_id: 600c47968e1bfa66f24dddc3b109064e619e3136
+cherrypick_cmd_id: c5aa01bea3faa9cd766dddca2fba82819a8abe17
+cherrypick_cmd_id: 171e4ec999b8a2eebd09f694b720bebb17cc9bad
+cherrypick_cmd_id: 14eca13063fbac470942a2b5168691b51b559e97
+cherrypick_cmd_id: 0ebc8e209ae8d5429b9ab1b5ac34c2c452cc86fe
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-982
+
+commit_info_2017-05-24_rev2.txt
+
+commit_id: 3d998bf37d7e978706d6b02d4f9332e4508ee3c3
+
+cherrypick_cmd_id: e3232d8f70b61d90c1158c441b3a9142c21300c0
+cherrypick_cmd_id: b5f7b82e60fb89e389d3568da0ba1fc563c596cd
+cherrypick_cmd_id: 600c47968e1bfa66f24dddc3b109064e619e3136
+cherrypick_cmd_id: c5aa01bea3faa9cd766dddca2fba82819a8abe17
+cherrypick_cmd_id: 171e4ec999b8a2eebd09f694b720bebb17cc9bad
+cherrypick_cmd_id: 14eca13063fbac470942a2b5168691b51b559e97
+cherrypick_cmd_id: 4db562a5e5e60bd63d0c68c171727d8664cf8741
+cherrypick_cmd_id: 5a13f47f7ac87014ea9700998c04a875d216ea54
+cherrypick_cmd_id: 9a70eb7489e77628f24e964c9043f3ff178387b0
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-976
+
+commit_info_2017-05-17_rev6.txt
+
+commit_id: a90cea54ea2ab138144643d705f24ed6861ec492
+
+cherrypick_cmd_id: e3232d8f70b61d90c1158c441b3a9142c21300c0
+cherrypick_cmd_id: b5f7b82e60fb89e389d3568da0ba1fc563c596cd
+cherrypick_cmd_id: 600c47968e1bfa66f24dddc3b109064e619e3136
+cherrypick_cmd_id: c5aa01bea3faa9cd766dddca2fba82819a8abe17
+cherrypick_cmd_id: 171e4ec999b8a2eebd09f694b720bebb17cc9bad
+
+----------------------------------------------------------------------------------------------------------------------------------
+[CONPRO-960] Manage the max connection counts to limit the connection
+
+git cherry-pick 11858d67a21ebb3aae40c0db44c73320eb90631f
+
+----------------------------------------------------------------------------------------------------------------------------------
+Arrange License for Tizen
+
+cherrypick_cmd_id: 171e4ec999b8a2eebd09f694b720bebb17cc9bad
+----------------------------------------------------------------------------------------------------------------------------------
+
+Remove Test folder which is not being released
+
+cherrypick_cmd_id: 26d93148d72600d0da47251ebd1104a7896e50c0
+----------------------------------------------------------------------------------------------------------------------------------
+
+http://suprem.sec.samsung.net/jira/browse/CONPRO-959
+
+commit_info_2017-05-10.txt
+
+commit_id: dee065f3bf813261ad20ee2412d3f90cb460e544
+
+cherrypick_cmd_id: 3cd74277793fea3861ee64f0349e3c5b1a9d3dc9
+cherrypick_cmd_id: 0211af585ae8a46b235ca6e077c64ebf7e3a1aec
+cherrypick_cmd_id: 6cbacba58132f973f1990b162bf7f29b996bc7a5
+cherrypick_cmd_id: c5aa01bea3faa9cd766dddca2fba82819a8abe17
+
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-943
+
+commit_info_2017-04-25_rev1.txt
+
+commit_id: 24e13856a6f9a774487f2ef1bf217c2864c0ad46
+
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/10 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/05/106905/12 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/34/113034/2 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/31/115231/5 && git cherry-pick FETCH_HEAD
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-933
+
+commit_info_2017-04-19_rev2.txt
+
+commit_id: 73af64330083b1ab39bd24847da5e90edca263de
+
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/10 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/05/106905/12 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/34/113034/2 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/08/114808/1 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/08/114808/2 && git cherry-pick FETCH_HEAD
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-913
+
+commit_info_2017-04-12_rev5.txt
+
+commit_id: 0e063c1c4ec6856b659d8025a02c200e3a896ce0
+
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/10 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/05/106905/12 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/34/113034/2 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/48/114248/3 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/81/111081/35 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/29/113729/18 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/64/114364/1 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/87/114287/4 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/24/114424/2 && git cherry-pick FETCH_HEAD
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-886
+
+commit_info_2017-04-04_rev4.txt
+
+commit_id: 8097da2ebdcb67ec66ea0ba21924730db8ff4372
+
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/10 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/05/106905/12 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/34/113034/2 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/64/113464/3 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/59/113759/1 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/61/113761/2 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/14/113414/3 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/84/113884/1 && git cherry-pick FETCH_HEAD
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-868
+
+commit_info_2017-03-29_rev4.txt
+
+commit_id: 30dbca27ce8d7ce04176548abb50dcd9fe5e86fe
+
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/10 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/05/106905/12 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/34/113034/2 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/52/112652/4 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/39/113239/4 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/40/113240/3 && git cherry-pick FETCH_HEAD
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-868
+
+commit_info_2017-03-29_rev3.txt
+
+commit_id: 30dbca27ce8d7ce04176548abb50dcd9fe5e86fe
+
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/10 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/05/106905/12 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/34/113034/2 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/65/113165/4 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/52/112652/4 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/39/113239/4 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/40/113240/3 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/89/113289/1 && git cherry-pick FETCH_HEAD
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-859
+
+commit_info_2017-03-27_rev2.txt
+
+commit_id: a2097190130c6f8d4a56098510ede82c57656e6b
+
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/10 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/05/106905/12 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/70/112270/1 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/25/112925/1 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/35/113035/1 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/34/113034/2 && git cherry-pick FETCH_HEAD
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-850
+
+commit_info_2017-03-23_rev2.txt
+
+commit_id: 6205eb34033b9cd694c7d5bd7d47fd8c41592d83
+
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/10 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/05/106905/12 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/22/107322/4 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/77/112777/1 && git cherry-pick FETCH_HEAD
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-835
+
+commit_info_2017-03-21_rev2.txt
+
+commit_id: 6c9b5bc0a60b1cd44cb63efcabc8f98483670ddd
+
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/10 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/05/106905/12 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/22/107322/4 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/25/109025/17 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/08/112608/1 && git cherry-pick FETCH_HEAD
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-827
+
+commit_info_2017-03-20_rev2.txt
+
+commit_id: 853572b65722efc8d2c76b7c91065b0c66ddb3f0
+
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/10 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/05/106905/12 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/22/107322/4 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/86/111986/2 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/25/109025/17 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/55/112255/2 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/32/112332/1 && git cherry-pick FETCH_HEAD
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-819
+
+commit_info_2017-03-16_rev2.txt
+
+commit_id: c103e665941c961314736057e0eb5e54e3b8698e
+
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/10 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/05/106905/12 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/22/107322/4 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/86/111986/2 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/25/109025/17 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/52/112152/1 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/95/112095/2 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/91/111991/2 && git cherry-pick FETCH_HEAD
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-809
+
+commit_info_2017-03-15_rev3.txt
+
+commit_id: 2c0cac592851e97ea530b3e3512ef57110976980
+
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/10 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/05/106905/12 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/22/107322/4 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/45/111845/7 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/86/111986/1 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/98/111998/1 && git cherry-pick FETCH_HEAD
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-800
+
+commit_info_2017-03-10_rev3.txt 
+
+commit_id: 9b4fe8ebc3aa1bfde2f49a073e1523fb721ed044
+
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/10 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/05/106905/12 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/22/107322/4 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/38/111238/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/22/111122/3 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/71/111471/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/51/111351/2 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/07/111507/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/10/111510/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/06/111506/1 && git cherry-pick FETCH_HEAD
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-786
+
+commit_info_2017-03-08_rev4.txt
+
+commit_id: 9039946c9e3f4029584d0c8b95f04e426bd240eb
+
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/10 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/05/106905/12 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/22/107322/4 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/38/111238/1 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/77/111277/1 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/02/111302/2 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/22/111122/3 && git cherry-pick FETCH_HEAD
+----------------------------------------------------------------------------------------------------------------------------------
+
+http://suprem.sec.samsung.net/jira/browse/CONPRO-775
+
+commit_info_2017-03-06_rev1.txt
+
+commit_id: 63e64a47a49b70c533f9826394127e2303bc9372
+
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/10 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/05/106905/12 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/22/107322/4 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/07/110507/2 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/64/110464/1 && git cherry-pick FETCH_HEAD
+----------------------------------------------------------------------------------------------------------------------------------
+
+http://suprem.sec.samsung.net/jira/browse/CONPRO-765
+
+commit_info_2017-02-28_rev2.txt 
+
+commit_id: f53a371b56aea31a80f02a84aeba0f6a4e6b0754
+
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/9 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/05/106905/11 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/22/107322/3 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/07/110507/1 && git cherry-pick FETCH_HEAD
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-753
+
+commit_info_2017-02-24_rev2.txt
+
+commit_id: 7cd3cd0f125be6ec8a3550a017c3d2a15fce00db
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/8 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/05/106905/10 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/22/107322/2 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/07/110507/1 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/15/110515/2 && git cherry-pick FETCH_HEAD
+
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-743
+
+commit_info_2017-02-22_rev1.txt
+
+commit_id: 2df5bc8a5e32364132ac14b731cb6940ac8e1753
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/8 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/05/106905/10 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/22/107322/2 && git cherry-pick FETCH_HEAD
+----------------------------------------------------------------------------------------------------------------------------------
+Fix a maximum size of wifi mode in easy setup
+
+The maximum number of supported WiFi mode is increased to 10, sufficiently.
+
+http://suprem.sec.samsung.net/gerrit/#/c/110335/
+( manually merged for VD request, not cherry-picked )
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-733
+commit_info_2017-02-17_rev6.txt
+
+commit_id: da7d2ea8a3bd9aea8718a901664d0590c7b2bcb1
+
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/110299/1 && git cherry-pick FETCH_HEAD
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-733
+commit_info_2017-02-17_rev5.txt
+
+commit_id: da7d2ea8a3bd9aea8718a901664d0590c7b2bcb1
+
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/7 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/05/106905/9 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/22/107322/2 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/37/109437/1 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/74/110074/1 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/75/110075/2 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/95/110095/1 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/40/110140/1 && git cherry-pick FETCH_HEAD
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-724
+
+commit_id: a5ccb864bd75587dcd91bf6f48a6f08319df65cf
+
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/7 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/05/106905/8 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/22/107322/2 && git cherry-pick FETCH_HEAD
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-713
+
+commit_id: 353f2986ab916f89e0f5e2fa805c8920aa2cde14
+
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/7 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/05/106905/6 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/22/107322/2 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/11/109311/2 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/04/109304/2 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/08/109308/2 && git cherry-pick FETCH_HEAD
+----------------------------------------------------------------------------------------------------------------------------------
+set only IP transport for vd request (2017-02-09)
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-700
+
+commit_info_2017-02-08_rev2.txt
+commit_id: d7e99e853046ed56a922c01e57732669a7234ead
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/7 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/05/106905/4 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/22/107322/2 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/109099/2 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/35/109135/1 && git cherry-pick FETCH_HEAD
+----------------------------------------------------------------------------------------------------------------------------------
+set only IP transport for vd request (2017-02-06)
+
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-687
+
+commit_info_2017-02-03_rev2.txt
+
+commit_id: af77c0e8ece5da571b0e52efd60a1b04c5f19c9e
+
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/6 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/05/106905/4 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/22/107322/2 && git cherry-pick FETCH_HEAD
+git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/68/108768/1 && git cherry-pick FETCH_HEAD
+
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-674
+
+commit_info_2017-01-31_rev3.txt 
+
+commit_id: 197da96f03e5edb412f7fb07af7554ff703dcd54
+
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/6 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/05/106905/4 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/22/107322/2 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/38/107538/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/26/107926/2 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/36/108436/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/19/107919/10 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/18/107918/8 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/23/107923/3 && git cherry-pick FETCH_HEAD
+----------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-665
+
+commit_info_2017-01-24_rev3.txt
+
+commit_id: 038ef6c8afd5fa0b58d70d21528223976012a5ed
+
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/6 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/05/106905/4 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/90/106990/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/91/106991/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/92/106992/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/93/106993/2 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/94/106994/2 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/95/106995/3 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/22/107322/2 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/38/107538/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/26/107926/2 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/83/108083/2 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/61/108161/1 && git cherry-pick FETCH_HEAD
+
+----------------------------------------------------------------------------------------------------------------------------------
+
+http://suprem.sec.samsung.net/jira/browse/CONPRO-659
+
+commit_info_2017-01-23_rev5.txt
+
+commit_id: 5a2dad10bc8af7e1229f4a8718234cbe3478b60b
+
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/6 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/05/106905/4 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/90/106990/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/91/106991/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/92/106992/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/93/106993/2 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/94/106994/2 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/95/106995/3 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/22/107322/2 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/38/107538/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/26/107926/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/54/107954/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/15/108015/1 && git cherry-pick FETCH_HEAD
+
+----------------------------------------------------------------------------------------------------------------------------------
+
+http://suprem.sec.samsung.net/jira/browse/CONPRO-652
+
+commit_info_2017-01-19_rev6.txt
+
+commit_id: bec493c861e151e4cd0c30051b3f308bcffce0ed
+
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/4 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/05/106905/3 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/90/106990/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/91/106991/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/92/106992/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/93/106993/2 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/94/106994/2 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/95/106995/3 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/22/107322/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/38/107538/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/42/107642/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/88/107688/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/22/107722/2 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/03/107803/1 && git cherry-pick FETCH_HEAD
+
+----------------------------------------------------------------------------------------------------------------------------------
+
+disable BLE feature
+
+ - requested by IoTLab
+
+----------------------------------------------------------------------------------------------------------------------------------
+
+http://suprem.sec.samsung.net/jira/browse/CONPRO-635
+
+commit_info_2017-01-16_rev2.txt
+
+commit_id: 0dbfa732f613c2d9fa23034d0e9c35c6508b8071
+
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/4 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/05/106905/3 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/90/106990/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/91/106991/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/92/106992/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/93/106993/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/94/106994/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/95/106995/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/22/107322/1 && git cherry-pick FETCH_HEAD
+
+----------------------------------------------------------------------------------------------------------------------------------
+
+http://suprem.sec.samsung.net/jira/browse/CONPRO-617
+
+commit_info_2017-01-12_rev5.txt
+
+commit_id: a0fa1b90b075ee3e5c500d3ce0f0f5572e35e429
+
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/4 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/94/105794/29 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/22/106322/3 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/05/106905/3 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/11/106911/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/90/106990/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/91/106991/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/92/106992/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/93/106993/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/94/106994/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/95/106995/1 && git cherry-pick FETCH_HEAD
+
+----------------------------------------------------------------------------------------------------------------------------------
+
+http://suprem.sec.samsung.net/jira/browse/CONPRO-584
+commit_info_2017-01-09_rev12.txt
+commit_id: dc1f37ac0b54dade9f8bc1b5c9fe345729b8a4e4
+
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/4 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/94/105794/23 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/69/106269/3 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/22/106322/3 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/55/106355/5 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/73/106373/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/95/106395/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/28/106428/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/47/106447/2 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/52/106452/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/81/106581/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/82/106582/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/90/106590/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/91/106591/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/93/106593/2 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/15/106615/2 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/26/106626/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/84/106684/1 && git cherry-pick FETCH_HEAD
+
+----------------------------------------------------------------------------------------------------------------------------------
+
+http://suprem.sec.samsung.net/jira/browse/CONPRO-462
+
+commit_info_2016-12-16_rev2.txt
+
+commit_id: dc1f37ac0b54dade9f8bc1b5c9fe345729b8a4e4
+
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/4 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/94/105794/23 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/69/106269/3 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/22/106322/3 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http:/commit_id: dc1f37ac0b54dade9f8bc1b5c9fe345729b8a4e4
+
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/99/104899/4 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/94/105794/23 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/69/106269/3 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/22/106322/3 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/55/106355/5 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/73/106373/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/95/106395/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/28/106428/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/47/106447/2 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/52/106452/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/81/106581/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/82/106582/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/90/106590/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/91/106591/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/93/106593/2 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/15/106615/2 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/26/106626/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/84/106684/1 && git cherry-pick FETCH_HEAD
+
+change_set: (from commit fee573ad11f3e4f3addfe2a43fc1a8a3b2f32668)
+--------------------------------------------------------------------------------
+Revision:       dc1f37ac0b54dade9f8bc1b5c9fe345729b8a4e4
+User:           jihwan.seo
+Date:           Mon Jan 09 12:45:04 KST 2017
+Comment:        
+[SAMSUNG] stop BLE advertising for disconnection status.(tizen MCD, VD)
+
+since advertising can be caused a big problem related battery consumption.
+it should be stopped when it is not used.
+
+Change-Id: Ibc92743fce56694f05af79d0a47ce06325c3237a
+Signed-off-by: jihwan.seo <jihwan.seo@samsung.com>
+Modifications:  
+  MODIFY       resource/csdk/connectivity/src/bt_le_adapter/tizen/caleserver_mcd.c     dc1f37ac0b54dade9f8bc1b5c9fe345729b8a4e4:fcb6143f3b28766f89c332b323159eb33a913116       null
+  MODIFY       resource/csdk/connectivity/src/bt_le_adapter/tizen/caleserver_vd.c      dc1f37ac0b54dade9f8bc1b5c9fe345729b8a4e4:fcb6143f3b28766f89c332b323159eb33a913116       null
+--------------------------------------------------------------------------------
+Revision:       fcb6143f3b28766f89c332b323159eb33a913116
+User:           Chul Lee
+Date:           Mon Jan 09 10:52:46 KST 2017
+Comment:        
+Update to include mbedtls library in stack's sample build
+
+Change-Id: Ia94116ab121b4d04038cd3b4ded03b325378511f
+Signed-off-by: Chul Lee <chuls.lee@samsung.com>
+Modifications:  
+  MODIFY       resource/csdk/stack/test/linux/SConscript       fcb6143f3b28766f89c332b323159eb33a913116:c4f6d85cdabcab328e5f94d055eb36011939b52a       null
+--------------------------------------------------------------------------------
+Revision:       c4f6d85cdabcab328e5f94d055eb36011939b52a
+User:           h_w park
+Date:           Mon Jan 09 10:29:00 KST 2017
+Comment:        
+Merge "Update to include mbedtls library in Secure build" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       891c5af03e821cb1f0aebf726a855d13dac17938
+User:           Jihun Ha
+Date:           Mon Jan 09 10:26:21 KST 2017
+Comment:        
+Update to include mbedtls library in Secure build
+
+Change-Id: I68daba29795455f2b03dafa91fc1137984feb25d
+Signed-off-by: Jihun Ha <jihun.ha@samsung.com>
+Modifications:  
+  MODIFY       service/easy-setup/sampleapp/enrollee/linux-samsung/SConscript  891c5af03e821cb1f0aebf726a855d13dac17938:7b6122f4c53f7172ede14163740e293092171ec9       null
+  MODIFY       service/easy-setup/sampleapp/enrollee/linux/SConscript  891c5af03e821cb1f0aebf726a855d13dac17938:7b6122f4c53f7172ede14163740e293092171ec9       null
+--------------------------------------------------------------------------------
+Revision:       7497d53650f47b36d803d526bbb281810c0834cc
+User:           jihwan seo
+Date:           Mon Jan 09 10:16:02 KST 2017
+Comment:        
+Merge "Send error response in case request msg type is unicast" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       3bfb0a407a1e9cb7270176d27dbf7a1bf216ce38
+User:           Jongmin Choi
+Date:           Mon Jan 09 09:31:16 KST 2017
+Comment:        
+Modify CreateResetProfile() to preserve the original profile
+
+CreateResetProfile() modified to preserve the original profile
+created at first
+
+Patch #1: Initial upload
+
+Change-Id: I3420d83a8c8a8b17f947dd244bb03ce7926159bb
+Signed-off-by: Jongmin Choi <jminl.choi@samsung.com>
+Modifications:  
+  MODIFY       resource/csdk/security/src/psinterface.c        3bfb0a407a1e9cb7270176d27dbf7a1bf216ce38:7b6122f4c53f7172ede14163740e293092171ec9       null
+--------------------------------------------------------------------------------
+Revision:       7b6122f4c53f7172ede14163740e293092171ec9
+User:           jaehong jo
+Date:           Mon Jan 09 08:12:47 KST 2017
+Comment:        
+Merge "Revert "[IOT-1714]Add wifi.p2p connection status changed intent receiver"" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       2df361249fca0230c55473d2b430416ff5cb5836
+User:           jaehong jo
+Date:           Mon Jan 09 08:12:19 KST 2017
+Comment:        
+Revert "[IOT-1714]Add wifi.p2p connection status changed intent receiver"
+
+This reverts commit 58a3604b455ea16982e6f6de2b04118ff633edc8.
+
+Change-Id: I926baf6e7113f77b6fb803de4492e99605855feb
+Modifications:  
+  MODIFY       android/android_api/base/src/main/java/org/iotivity/ca/CaIpInterface.java       2df361249fca0230c55473d2b430416ff5cb5836:58a3604b455ea16982e6f6de2b04118ff633edc8       null
+--------------------------------------------------------------------------------
+Revision:       ed2ea1917298987eb384c6239b0e0724e2fa490b
+User:           jaehong jo
+Date:           Sat Jan 07 15:52:09 KST 2017
+Comment:        
+Merge "To support start/stop LE advertising API for android" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       4a560587b670f95d594b2386f0768c9cb448f9c5
+User:           jihwan seo
+Date:           Sat Jan 07 15:28:50 KST 2017
+Comment:        
+Merge "Revert "[SAMSUNG] temp pathc : replace MTU size with 514 byte"" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       872c8a18f8a2900aa3ddcda3e75a6dcdc9c1a917
+User:           jihwan seo
+Date:           Sat Jan 07 15:28:46 KST 2017
+Comment:        
+Revert "[SAMSUNG] temp pathc : replace MTU size with 514 byte"
+
+This reverts commit d00c6fec635e3cd3d1360ca48a0e097a47230cf9.
+
+Change-Id: Id307b7550794c6c29c3931c409ff935be40b5281
+Modifications:  
+  MODIFY       resource/csdk/connectivity/inc/cafragmentation.h        872c8a18f8a2900aa3ddcda3e75a6dcdc9c1a917:d00c6fec635e3cd3d1360ca48a0e097a47230cf9       null
+--------------------------------------------------------------------------------
+Revision:       951558a269828159a1c6e1d3e74a752960fc7dae
+User:           jihwan.seo
+Date:           Sat Jan 07 15:20:26 KST 2017
+Comment:        
+To support start/stop LE advertising API for android
+
+Change-Id: I3201e563cdd07bb84c38639f9a2b6743122b2385
+Signed-off-by: jihwan.seo <jihwan.seo@samsung.com>
+Modifications:  
+  MODIFY       android/android_api/base/jni/JniCaInterface.c   951558a269828159a1c6e1d3e74a752960fc7dae:3d2bee77cf604c3aa82d99367f50ee1ee1c7b7e3       null
+  MODIFY       android/android_api/base/src/main/java/org/iotivity/ca/CaInterface.java 951558a269828159a1c6e1d3e74a752960fc7dae:3d2bee77cf604c3aa82d99367f50ee1ee1c7b7e3       null
+  MODIFY       resource/csdk/connectivity/api/cautilinterface.h        951558a269828159a1c6e1d3e74a752960fc7dae:3d2bee77cf604c3aa82d99367f50ee1ee1c7b7e3       null
+  MODIFY       resource/csdk/connectivity/util/inc/camanagerleinterface.h      951558a269828159a1c6e1d3e74a752960fc7dae:3d2bee77cf604c3aa82d99367f50ee1ee1c7b7e3       null
+  MODIFY       resource/csdk/connectivity/util/src/camanager/bt_le_manager/android/caleconnectionmanager.c     951558a269828159a1c6e1d3e74a752960fc7dae:3d2bee77cf604c3aa82d99367f50ee1ee1c7b7e3       null
+  MODIFY       resource/csdk/connectivity/util/src/cautilinterface.c   951558a269828159a1c6e1d3e74a752960fc7dae:3d2bee77cf604c3aa82d99367f50ee1ee1c7b7e3       null
+--------------------------------------------------------------------------------
+Revision:       3d2bee77cf604c3aa82d99367f50ee1ee1c7b7e3
+User:           jihwan seo
+Date:           Sat Jan 07 12:44:17 KST 2017
+Comment:        
+Merge "Updates for VD BLE support (Tizen TV) - Added calenwmonitor_vd.c" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       d4611ef24f131302fa08fe8a55ee6199a78d9bc9
+User:           js126 lee
+Date:           Fri Jan 06 18:46:14 KST 2017
+Comment:        
+Merge "Modify SetupCipher() to support multiple ciphersuites" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       715f88dde7acc4878c6b1f30e5af0adba2aa6189
+User:           chuls lee
+Date:           Fri Jan 06 18:27:28 KST 2017
+Comment:        
+Merge "Removed compiler warnings for security modules." into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       b261d0d7c4483a6eb57d8cdb0336ed6b31fcbbfe
+User:           Jongmin Choi
+Date:           Fri Jan 06 18:25:24 KST 2017
+Comment:        
+Modify SetupCipher() to support multiple ciphersuites
+
+SetupCipher() modified to support multiple ciphersuites
+
+Patch #1: initial upload
+
+Change-Id: Ie61b4116e41c0845082eda9ca8ab9c859a1fc5b0
+Signed-off-by: Jongmin Choi <jminl.choi@samsung.com>
+Modifications:  
+  MODIFY       resource/csdk/connectivity/src/adapter_util/ca_adapter_net_ssl.c        b261d0d7c4483a6eb57d8cdb0336ed6b31fcbbfe:54b3ab75572776e83c013765c3771749c6f22389       null
+--------------------------------------------------------------------------------
+Revision:       279da96989d40545fcf687835b03b8d49756944a
+User:           Jihun Ha
+Date:           Fri Jan 06 18:24:05 KST 2017
+Comment:        
+Merge "Static Analysis(SVACE) issue fixes on Notification consumer." into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       54b3ab75572776e83c013765c3771749c6f22389
+User:           jihwan seo
+Date:           Fri Jan 06 17:59:24 KST 2017
+Comment:        
+Merge "Added #ifdef preprocessor about CASetMulticastTTL() API" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       b1c33772fa0caf3124d965c511d54ea5e219d5b6
+User:           js126 lee
+Date:           Fri Jan 06 17:37:44 KST 2017
+Comment:        
+Merge "TLS suites" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       bc6e5fb39d4f665a67b3d3ccba70ecbfa729d4f7
+User:           yw1201 kim
+Date:           Fri Jan 06 17:29:34 KST 2017
+Comment:        
+Merge "1. iOS BLE connectivity added 2. Style update and fixes" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       9c9310b2e44d1f0d3a3b7ca356399bdcd741e79a
+User:           hyuna0213.jo
+Date:           Fri Jan 06 16:51:13 KST 2017
+Comment:        
+Added #ifdef preprocessor about CASetMulticastTTL() API
+
+Change-Id: Ib6f35958f155c45de630c02b3864de366efaaccd
+Signed-off-by: hyuna0213.jo <hyuna0213.jo@samsung.com>
+Modifications:  
+  MODIFY       resource/csdk/connectivity/inc/cainterfacecontroller.h  9c9310b2e44d1f0d3a3b7ca356399bdcd741e79a:547adc192af77e436c1f0f16164d2c1b44fbba6a       null
+  MODIFY       resource/csdk/connectivity/src/cainterfacecontroller.c  9c9310b2e44d1f0d3a3b7ca356399bdcd741e79a:547adc192af77e436c1f0f16164d2c1b44fbba6a       null
+--------------------------------------------------------------------------------
+Revision:       547adc192af77e436c1f0f16164d2c1b44fbba6a
+User:           Parkhi
+Date:           Fri Jan 06 14:56:26 KST 2017
+Comment:        
+[CONPRO-553] Changed all of easysetup-callback-function to static member
+function. This change can protect from crash when class instance is removed.
+
+Change-Id: I0db76ee443a88ac15d11d62a44af0b92b754d697
+Signed-off-by: Parkhi <h_w.park@samsung.com>
+Reviewed-on: https://gerrit.iotivity.org/gerrit/16037
+Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
+Reviewed-by: Jihun Ha <jihun.ha@samsung.com>
+Reviewed-by: Uze Choi <uzchoi@samsung.com>
+Signed-off-by: Parkhi <h_w.park@samsung.com>
+Modifications:  
+  MODIFY       service/easy-setup/mediator/richsdk/inc/RemoteEnrollee.h        547adc192af77e436c1f0f16164d2c1b44fbba6a:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       service/easy-setup/mediator/richsdk/src/CloudResource.cpp       547adc192af77e436c1f0f16164d2c1b44fbba6a:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       service/easy-setup/mediator/richsdk/src/CloudResource.h 547adc192af77e436c1f0f16164d2c1b44fbba6a:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       service/easy-setup/mediator/richsdk/src/EnrolleeResource.cpp    547adc192af77e436c1f0f16164d2c1b44fbba6a:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       service/easy-setup/mediator/richsdk/src/EnrolleeResource.h      547adc192af77e436c1f0f16164d2c1b44fbba6a:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       service/easy-setup/mediator/richsdk/src/EnrolleeSecurity.cpp    547adc192af77e436c1f0f16164d2c1b44fbba6a:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       service/easy-setup/mediator/richsdk/src/EnrolleeSecurity.h      547adc192af77e436c1f0f16164d2c1b44fbba6a:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       service/easy-setup/mediator/richsdk/src/RemoteEnrollee.cpp      547adc192af77e436c1f0f16164d2c1b44fbba6a:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+--------------------------------------------------------------------------------
+Revision:       82fecb62dfd44d4b261502edf0b28264c34201a0
+User:           Jongmin Choi
+Date:           Fri Jan 06 13:33:40 KST 2017
+Comment:        
+TLS suites
+
+1. Added:
+   TLS_RSA_WITH_AES_256_CBC_SHA256          0x3D
+   TLS_RSA_WITH_AES_128_GCM_SHA256          0x009C
+   TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256  0xC02B
+   TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384  0xC024
+   TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384  0xC02C
+   TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_256   0xC027
+2. Removed:
+   TLS_RSA_WITH_AES_256_CBC_SHA             0x35
+   TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA     0xC009
+3. SSL code refactored
+4. Added unit tests for new cipher suites
+5. CAsslGenerateOwnerPsk modified to support all suites
+
+Change-Id: I33cbf2713a7b4e41d44d4bd97c3dc982d86df403
+Signed-off-by: Oleksii Beketov <ol.beketov@samsung.com>
+Signed-off-by: Dmitriy Zhuravlev <d.zhuravlev@samsung.com>
+Signed-off-by: Oleksii Beketov <ol.beketov@samsung.com>
+Signed-off-by: Jongmin Choi <jminl.choi@samsung.com>
+Reviewed-on: https://gerrit.iotivity.org/gerrit/15443
+Reviewed-by: Jongsung Lee <js126.lee@samsung.com>
+Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
+Reviewed-by: Greg Zaverucha <gregz@microsoft.com>
+Reviewed-by: Randeep Singh <randeep.s@samsung.com>
+Modifications:  
+  MODIFY       android/android_api/base/src/main/java/org/iotivity/ca/OicCipher.java   82fecb62dfd44d4b261502edf0b28264c34201a0:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       resource/csdk/connectivity/api/casecurityinterface.h    82fecb62dfd44d4b261502edf0b28264c34201a0:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       resource/csdk/connectivity/inc/ca_adapter_net_ssl.h     82fecb62dfd44d4b261502edf0b28264c34201a0:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       resource/csdk/connectivity/src/adapter_util/ca_adapter_net_ssl.c        82fecb62dfd44d4b261502edf0b28264c34201a0:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       resource/csdk/connectivity/src/caconnectivitymanager.c  82fecb62dfd44d4b261502edf0b28264c34201a0:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       resource/csdk/connectivity/test/ssladapter_test.cpp     82fecb62dfd44d4b261502edf0b28264c34201a0:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       resource/csdk/security/provisioning/sample/cloud/cloudCommon.c  82fecb62dfd44d4b261502edf0b28264c34201a0:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       resource/csdk/security/provisioning/src/ownershiptransfermanager.c      82fecb62dfd44d4b261502edf0b28264c34201a0:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       resource/csdk/security/provisioning/src/oxmmanufacturercert.c   82fecb62dfd44d4b261502edf0b28264c34201a0:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       resource/csdk/security/src/credresource.c       82fecb62dfd44d4b261502edf0b28264c34201a0:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       resource/include/CAManager.h    82fecb62dfd44d4b261502edf0b28264c34201a0:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+--------------------------------------------------------------------------------
+Revision:       db348f74888b03f7aa82db5682b5dd57c137e43d
+User:           jminl choi
+Date:           Fri Jan 06 12:59:04 KST 2017
+Comment:        
+Merge "Fix for patchset 15853" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       c30a318f97d8a5c2ae7c85311f4141018bdf072a
+User:           jminl choi
+Date:           Fri Jan 06 12:58:23 KST 2017
+Comment:        
+Merge "Send alert after bad client hello" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       f8a4e7eb5ee3cbb2e0d83211774fccafdc7624ad
+User:           js126.lee
+Date:           Fri Jan 06 12:44:59 KST 2017
+Comment:        
+Send alert after bad client hello
+
+Fix the following situation:
+1. client tries OTM to server
+2. OTM completed
+3. network of server goes down and up => DTLS session has been removed
+4. client tries to send a request to secure resource(e.g., /oic/sec/acl)
+5. server prints bad client error(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO), and then ignore this
+6. client never gets a response of it even if re-tries to sent same message
+
+Change-Id: Ie2cd3eaa49fc8782522126799994a5cd47cfaf4e
+Signed-off-by: Dmitriy Zhuravlev <d.zhuravlev@samsung.com>
+Signed-off-by: Oleksii Beketov <ol.beketov@samsung.com>
+Signed-off-by: Joonghwan Lee <jh05.lee@samsung.com>
+Signed-off-by: Jongsung Lee <js126.lee@samsung.com>
+Reviewed-on: https://gerrit.iotivity.org/gerrit/15853
+Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
+Reviewed-by: Randeep Singh <randeep.s@samsung.com>
+Modifications:  
+  MODIFY       resource/csdk/connectivity/src/adapter_util/ca_adapter_net_ssl.c        f8a4e7eb5ee3cbb2e0d83211774fccafdc7624ad:2cdfd5beff66b88ec15422b3f1197053ccb9fb2b       null
+--------------------------------------------------------------------------------
+Revision:       2cdfd5beff66b88ec15422b3f1197053ccb9fb2b
+User:           hyuna0213 jo
+Date:           Fri Jan 06 11:17:36 KST 2017
+Comment:        
+Merge "[SAMSUNG] temp pathc : replace MTU size with 514 byte" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       f29333f26eaaa25ee786cb5a294039dcafc90e84
+User:           js126 lee
+Date:           Thu Jan 05 20:40:50 KST 2017
+Comment:        
+Merge "Handshake Changed to One-Way Authentication" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       9ecc1f73df08a75143277c6487d24bba07d6f6c1
+User:           jaehong jo
+Date:           Thu Jan 05 20:24:26 KST 2017
+Comment:        
+Merge "stop BLE advertising for disconnection status.(android/tizen)" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       e17d70666df4195fe88dc00a576ef1eb2fa21aa1
+User:           Chul Lee
+Date:           Thu Jan 05 17:58:21 KST 2017
+Comment:        
+Removed compiler warnings for security modules.
+
+Patch #1 : initial upload.
+Patch #2 : retrigger.
+Patch #3~4 : update according to comments.
+Patch #5 : rebase
+
+Change-Id: Ie5009c484f50d40c8a2e2f9ac7c361cd9a712d93
+Signed-off-by: Chul Lee <chuls.lee@samsung.com>
+Reviewed-on: https://gerrit.iotivity.org/gerrit/15045
+Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
+Reviewed-by: Randeep Singh <randeep.s@samsung.com>
+Modifications:  
+  MODIFY       resource/csdk/security/include/internal/crlresource.h   e17d70666df4195fe88dc00a576ef1eb2fa21aa1:af9a7ecdba7de7b683e6677e9468cde72b014444       null
+  MODIFY       resource/csdk/security/provisioning/include/internal/otmcontextlist.h   e17d70666df4195fe88dc00a576ef1eb2fa21aa1:af9a7ecdba7de7b683e6677e9468cde72b014444       null
+  MODIFY       resource/csdk/security/provisioning/sample/provisioningclient.c e17d70666df4195fe88dc00a576ef1eb2fa21aa1:af9a7ecdba7de7b683e6677e9468cde72b014444       null
+  MODIFY       resource/csdk/security/provisioning/src/credentialgenerator.c   e17d70666df4195fe88dc00a576ef1eb2fa21aa1:af9a7ecdba7de7b683e6677e9468cde72b014444       null
+  MODIFY       resource/csdk/security/provisioning/src/otmcontextlist.c        e17d70666df4195fe88dc00a576ef1eb2fa21aa1:af9a7ecdba7de7b683e6677e9468cde72b014444       null
+  MODIFY       resource/csdk/security/provisioning/src/ownershiptransfermanager.c      e17d70666df4195fe88dc00a576ef1eb2fa21aa1:af9a7ecdba7de7b683e6677e9468cde72b014444       null
+  MODIFY       resource/csdk/security/provisioning/src/pmutility.c     e17d70666df4195fe88dc00a576ef1eb2fa21aa1:af9a7ecdba7de7b683e6677e9468cde72b014444       null
+  MODIFY       resource/csdk/security/provisioning/src/secureresourceprovider.c        e17d70666df4195fe88dc00a576ef1eb2fa21aa1:af9a7ecdba7de7b683e6677e9468cde72b014444       null
+  MODIFY       resource/csdk/security/src/credresource.c       e17d70666df4195fe88dc00a576ef1eb2fa21aa1:af9a7ecdba7de7b683e6677e9468cde72b014444       null
+  MODIFY       resource/csdk/security/src/crlresource.c        e17d70666df4195fe88dc00a576ef1eb2fa21aa1:af9a7ecdba7de7b683e6677e9468cde72b014444       null
+  MODIFY       resource/csdk/security/src/oxmpincommon.c       e17d70666df4195fe88dc00a576ef1eb2fa21aa1:af9a7ecdba7de7b683e6677e9468cde72b014444       null
+  MODIFY       resource/csdk/security/src/pbkdf2.c     e17d70666df4195fe88dc00a576ef1eb2fa21aa1:af9a7ecdba7de7b683e6677e9468cde72b014444       null
+--------------------------------------------------------------------------------
+Revision:       7bfdbb3856c23779d37c81627c4679d6facd150f
+User:           Senthil Kumar G S
+Date:           Thu Jan 05 15:02:23 KST 2017
+Comment:        
+Static Analysis(SVACE) issue fixes on Notification consumer.
+
+Change-Id: Ic7e10fcd7764098151c55684c6c6fa0ad9ac557e
+Signed-off-by: Senthil Kumar G S <senthil.gs@samsung.com>
+Modifications:  
+  MODIFY       service/notification/android/notification-service/src/main/jni/consumer/JniNotificationConsumer.cpp     7bfdbb3856c23779d37c81627c4679d6facd150f:fee573ad11f3e4f3addfe2a43fc1a8a3b2f32668       null
+--------------------------------------------------------------------------------
+Revision:       5a30dc184d68318357c4cb3c8fe1003d90e497f8
+User:           jihwan.seo
+Date:           Thu Jan 05 12:27:17 KST 2017
+Comment:        
+stop BLE advertising for disconnection status.(android/tizen)
+
+since advertising can be caused a big problem related battery.
+it should be stopped when it is not used.
+
+Change-Id: Ib645dafe9cba3218972b655cfa0f5b067ad971eb
+Signed-off-by: jihwan.seo <jihwan.seo@samsung.com>
+Modifications:  
+  MODIFY       resource/csdk/connectivity/src/bt_le_adapter/android/caleserver.c       5a30dc184d68318357c4cb3c8fe1003d90e497f8:31dd40f8572b86096bfd1055ecc145cfa66c47d0       null
+  MODIFY       resource/csdk/connectivity/src/bt_le_adapter/android/caleserver.h       5a30dc184d68318357c4cb3c8fe1003d90e497f8:31dd40f8572b86096bfd1055ecc145cfa66c47d0       null
+  MODIFY       resource/csdk/connectivity/src/bt_le_adapter/tizen/caleserver.c 5a30dc184d68318357c4cb3c8fe1003d90e497f8:31dd40f8572b86096bfd1055ecc145cfa66c47d0       null
+--------------------------------------------------------------------------------
+Revision:       d4b5830d7e10d9cf36dc8133d31ed8e380f3c1f1
+User:           Jongmin Choi
+Date:           Wed Jan 04 18:26:56 KST 2017
+Comment:        
+Handshake Changed to One-Way Authentication
+
+Handshake changed so that only client will verify server certificate
+
+Patch #1: Initial upload
+
+Change-Id: I8faa755022ec2f0f2eab5a4f9037c3fd1243aeb8
+Signed-off-by: Jongmin Choi <jminl.choi@samsung.com>
+Modifications:  
+  MODIFY       resource/csdk/connectivity/src/adapter_util/ca_adapter_net_ssl.c        d4b5830d7e10d9cf36dc8133d31ed8e380f3c1f1:5833fc1fa5af6cfc12c7cd7be762bf6f4711d2a0       null
+--------------------------------------------------------------------------------
+Revision:       fb88a108fbfe6201a3da403b88c2444f3d104c20
+User:           Md. Kamrujjaman Akon
+Date:           Wed Jan 04 17:47:54 KST 2017
+Comment:        
+1. iOS BLE connectivity added
+2. Style update and fixes
+
+Change-Id: Ic18998028410c842c3ada7604508dfcbdc03a73e
+Signed-off-by: Md. Kamrujjaman Akon <mdk.akon@samsung.com>
+Modifications:  
+  MODIFY       resource/csdk/connectivity/api/cautilinterface.h        fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  MODIFY       resource/csdk/connectivity/src/bt_le_adapter/caleadapter.c      fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  ADD  resource/csdk/connectivity/src/bt_le_adapter/ios/SConscript     fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  ADD  resource/csdk/connectivity/src/bt_le_adapter/ios/caleclient.h   fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  ADD  resource/csdk/connectivity/src/bt_le_adapter/ios/caleclient.m   fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  ADD  resource/csdk/connectivity/src/bt_le_adapter/ios/calenwmonitor.h        fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  ADD  resource/csdk/connectivity/src/bt_le_adapter/ios/calenwmonitor.m        fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  ADD  resource/csdk/connectivity/src/bt_le_adapter/ios/caleserver.h   fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  ADD  resource/csdk/connectivity/src/bt_le_adapter/ios/caleserver.m   fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  ADD  resource/csdk/connectivity/src/bt_le_adapter/ios/caleutils.h    fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  MODIFY       resource/csdk/connectivity/util/SConscript      fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  MODIFY       resource/csdk/connectivity/util/inc/camanagerleinterface.h      fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  ADD  resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/caleautoconnector.h     fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  ADD  resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/caleautoconnector.m     fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  ADD  resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/caleconnectionmanager.m fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  ADD  resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/camanagerdevice.h       fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  ADD  resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/camanagerdevice.m       fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  ADD  resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/camanagerleutil.h       fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  ADD  resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/camanagerleutil.m       fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  MODIFY       resource/csdk/connectivity/util/src/cautilinterface.c   fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+--------------------------------------------------------------------------------
+Revision:       af9a7ecdba7de7b683e6677e9468cde72b014444
+User:           Jongmin Choi
+Date:           Tue Jan 03 19:05:00 KST 2017
+Comment:        
+Modify Reset Profile to include cred resource
+
+Reset Profile modified to include cred resource
+https://gerrit.iotivity.org/gerrit/#/c/16111/
+
+Patch #1: Initial upload
+Patch #2: ResetSecureResourceInPS() modified
+
+Change-Id: I5ed286ac43b32f3e04d33a9d0f1428a7443d7c08
+Signed-off-by: Jongmin Choi <jminl.choi@samsung.com>
+Reviewed-on: https://gerrit.iotivity.org/gerrit/16111
+Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
+Reviewed-by: Chul Lee <chuls.lee@samsung.com>
+Reviewed-by: Randeep Singh <randeep.s@samsung.com>
+Modifications:  
+  MODIFY       resource/csdk/security/src/psinterface.c        af9a7ecdba7de7b683e6677e9468cde72b014444:fee573ad11f3e4f3addfe2a43fc1a8a3b2f32668       null
+--------------------------------------------------------------------------------
+Revision:       e7449c4a6b1297359c21410d20f88a40e5b90f0b
+User:           Dmitriy Zhuravlev
+Date:           Fri Dec 30 16:28:14 KST 2016
+Comment:        
+Fix for patchset 15853
+
+Fixed OTM error caused by patchset 15853.
+Added close notify alert sending to DeletePeerList()
+
+Change-Id: Ib5363f8d16358a388df0f003e9111f1d56ccca62
+Signed-off-by: Oleksii Beketov <ol.beketov@samsung.com>
+Signed-off-by: Dmitriy Zhuravlev <d.zhuravlev@samsung.com>
+Signed-off-by: Jongsung Lee <js126.lee@samsung.com>
+Reviewed-on: https://gerrit.iotivity.org/gerrit/16001
+Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
+Reviewed-by: Chul Lee <chuls.lee@samsung.com>
+Reviewed-by: Jongsung Lee <js126.lee@samsung.com>
+Reviewed-by: Randeep Singh <randeep.s@samsung.com>
+Modifications:  
+  MODIFY       resource/csdk/connectivity/src/adapter_util/ca_adapter_net_ssl.c        e7449c4a6b1297359c21410d20f88a40e5b90f0b:f8a4e7eb5ee3cbb2e0d83211774fccafdc7624ad       null
+--------------------------------------------------------------------------------
+Revision:       4f01a28f4039959e481a14331489f5dc13debc8e
+User:           MSK
+Date:           Fri Dec 30 12:42:48 KST 2016
+Comment:        
+Updates for VD BLE support (Tizen TV)
+- Added calenwmonitor_vd.c
+
+Change-Id: I986dda7d72862988b17f4d0644715f6e6c83ae97
+Modifications:  
+  MODIFY       resource/csdk/connectivity/src/bt_le_adapter/tizen/SConscript   4f01a28f4039959e481a14331489f5dc13debc8e:ac2a56d8f2b8a8397b83b13be43b4e6564e75982       null
+  ADD  resource/csdk/connectivity/src/bt_le_adapter/tizen/calenwmonitor_vd.c   4f01a28f4039959e481a14331489f5dc13debc8e:ac2a56d8f2b8a8397b83b13be43b4e6564e75982       null
+  MODIFY       resource/csdk/connectivity/src/bt_le_adapter/tizen/caleserver_vd.c      4f01a28f4039959e481a14331489f5dc13debc8e:ac2a56d8f2b8a8397b83b13be43b4e6564e75982       null
+--------------------------------------------------------------------------------
+Revision:       f7688681728e25094273934d7ef79395a2ef1f30
+User:           hyuna0213.jo
+Date:           Wed Dec 28 08:56:11 KST 2016
+Comment:        
+Send error response in case request msg type is unicast
+
+It is unnecessary to respond to a multicast request
+
+Change-Id: I071300b21e8d56459bee4f29b9c031ceed973067
+Signed-off-by: hyuna0213.jo <hyuna0213.jo@samsung.com>
+Modifications:  
+  MODIFY       resource/csdk/stack/src/ocstack.c       f7688681728e25094273934d7ef79395a2ef1f30:e775ce68b215d8cf6a7e3f43595de81605b9aa4d       null
+--------------------------------------------------------------------------------
+Revision:       34fc43e4e36fc21097e6ca52176d0766158b3ecf
+User:           js126.lee
+Date:           Tue Dec 27 17:15:28 KST 2016
+Comment:        
+Add revstat into optdata of Cred according to OCF spec
+
+Accoding to ocf security spec, revstat is mandatory property.
+"revstat": {
+  "type": "boolean",
+  "description": "Revocation status flag
+                - true = revoked, false = not revoked"
+
+Patch 1: upload patch.
+Patch 2: update json2cbor.c to convert revstat
+
+Change-Id: Ifbb7743f8321cb8afbf69cfa307694598e24ea6e
+Signed-off-by: js126.lee <js126.lee@samsung.com>
+Reviewed-on: https://gerrit.iotivity.org/gerrit/15951
+Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
+Reviewed-by: Chul Lee <chuls.lee@samsung.com>
+Reviewed-by: Randeep Singh <randeep.s@samsung.com>
+Modifications:  
+  MODIFY       resource/csdk/security/include/internal/srmresourcestrings.h    34fc43e4e36fc21097e6ca52176d0766158b3ecf:2cdfd5beff66b88ec15422b3f1197053ccb9fb2b       null
+  MODIFY       resource/csdk/security/include/securevirtualresourcetypes.h     34fc43e4e36fc21097e6ca52176d0766158b3ecf:2cdfd5beff66b88ec15422b3f1197053ccb9fb2b       null
+  MODIFY       resource/csdk/security/provisioning/src/secureresourceprovider.c        34fc43e4e36fc21097e6ca52176d0766158b3ecf:2cdfd5beff66b88ec15422b3f1197053ccb9fb2b       null
+  MODIFY       resource/csdk/security/src/credresource.c       34fc43e4e36fc21097e6ca52176d0766158b3ecf:2cdfd5beff66b88ec15422b3f1197053ccb9fb2b       null
+  MODIFY       resource/csdk/security/src/srmresourcestrings.c 34fc43e4e36fc21097e6ca52176d0766158b3ecf:2cdfd5beff66b88ec15422b3f1197053ccb9fb2b       null
+  MODIFY       resource/csdk/security/tool/json2cbor.c 34fc43e4e36fc21097e6ca52176d0766158b3ecf:2cdfd5beff66b88ec15422b3f1197053ccb9fb2b       null
+--------------------------------------------------------------------------------
+Revision:       d00c6fec635e3cd3d1360ca48a0e097a47230cf9
+User:           jihwan.seo
+Date:           Tue Dec 27 14:15:01 KST 2016
+Comment:        
+[SAMSUNG] temp pathc : replace MTU size with 514 byte
+
+Change-Id: I41336dffb9c42019da7c0a676fb5fa63f8627003
+Signed-off-by: jihwan.seo <jihwan.seo@samsung.com>
+Modifications:  
+  MODIFY       resource/csdk/connectivity/inc/cafragmentation.h        d00c6fec635e3cd3d1360ca48a0e097a47230cf9:65ed3e6ea7f36d86e83c369e202a4712d2b79f65       null
+/suprem.sec.samsung.net/gerrit/IoTivity refs/changes/55/106355/5 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/73/106373/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/95/106395/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/28/106428/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/47/106447/2 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/52/106452/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/81/106581/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/82/106582/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/90/106590/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/91/106591/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/93/106593/2 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/15/106615/2 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/26/106626/1 && git cherry-pick FETCH_HEAD
+cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/84/106684/1 && git cherry-pick FETCH_HEAD
+
+change_set: (from commit fee573ad11f3e4f3addfe2a43fc1a8a3b2f32668)
+--------------------------------------------------------------------------------
+Revision:       dc1f37ac0b54dade9f8bc1b5c9fe345729b8a4e4
+User:           jihwan.seo
+Date:           Mon Jan 09 12:45:04 KST 2017
+Comment:        
+[SAMSUNG] stop BLE advertising for disconnection status.(tizen MCD, VD)
+
+since advertising can be caused a big problem related battery consumption.
+it should be stopped when it is not used.
+
+Change-Id: Ibc92743fce56694f05af79d0a47ce06325c3237a
+Signed-off-by: jihwan.seo <jihwan.seo@samsung.com>
+Modifications:  
+  MODIFY       resource/csdk/connectivity/src/bt_le_adapter/tizen/caleserver_mcd.c     dc1f37ac0b54dade9f8bc1b5c9fe345729b8a4e4:fcb6143f3b28766f89c332b323159eb33a913116       null
+  MODIFY       resource/csdk/connectivity/src/bt_le_adapter/tizen/caleserver_vd.c      dc1f37ac0b54dade9f8bc1b5c9fe345729b8a4e4:fcb6143f3b28766f89c332b323159eb33a913116       null
+--------------------------------------------------------------------------------
+Revision:       fcb6143f3b28766f89c332b323159eb33a913116
+User:           Chul Lee
+Date:           Mon Jan 09 10:52:46 KST 2017
+Comment:        
+Update to include mbedtls library in stack's sample build
+
+Change-Id: Ia94116ab121b4d04038cd3b4ded03b325378511f
+Signed-off-by: Chul Lee <chuls.lee@samsung.com>
+Modifications:  
+  MODIFY       resource/csdk/stack/test/linux/SConscript       fcb6143f3b28766f89c332b323159eb33a913116:c4f6d85cdabcab328e5f94d055eb36011939b52a       null
+--------------------------------------------------------------------------------
+Revision:       c4f6d85cdabcab328e5f94d055eb36011939b52a
+User:           h_w park
+Date:           Mon Jan 09 10:29:00 KST 2017
+Comment:        
+Merge "Update to include mbedtls library in Secure build" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       891c5af03e821cb1f0aebf726a855d13dac17938
+User:           Jihun Ha
+Date:           Mon Jan 09 10:26:21 KST 2017
+Comment:        
+Update to include mbedtls library in Secure build
+
+Change-Id: I68daba29795455f2b03dafa91fc1137984feb25d
+Signed-off-by: Jihun Ha <jihun.ha@samsung.com>
+Modifications:  
+  MODIFY       service/easy-setup/sampleapp/enrollee/linux-samsung/SConscript  891c5af03e821cb1f0aebf726a855d13dac17938:7b6122f4c53f7172ede14163740e293092171ec9       null
+  MODIFY       service/easy-setup/sampleapp/enrollee/linux/SConscript  891c5af03e821cb1f0aebf726a855d13dac17938:7b6122f4c53f7172ede14163740e293092171ec9       null
+--------------------------------------------------------------------------------
+Revision:       7497d53650f47b36d803d526bbb281810c0834cc
+User:           jihwan seo
+Date:           Mon Jan 09 10:16:02 KST 2017
+Comment:        
+Merge "Send error response in case request msg type is unicast" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       3bfb0a407a1e9cb7270176d27dbf7a1bf216ce38
+User:           Jongmin Choi
+Date:           Mon Jan 09 09:31:16 KST 2017
+Comment:        
+Modify CreateResetProfile() to preserve the original profile
+
+CreateResetProfile() modified to preserve the original profile
+created at first
+
+Patch #1: Initial upload
+
+Change-Id: I3420d83a8c8a8b17f947dd244bb03ce7926159bb
+Signed-off-by: Jongmin Choi <jminl.choi@samsung.com>
+Modifications:  
+  MODIFY       resource/csdk/security/src/psinterface.c        3bfb0a407a1e9cb7270176d27dbf7a1bf216ce38:7b6122f4c53f7172ede14163740e293092171ec9       null
+--------------------------------------------------------------------------------
+Revision:       7b6122f4c53f7172ede14163740e293092171ec9
+User:           jaehong jo
+Date:           Mon Jan 09 08:12:47 KST 2017
+Comment:        
+Merge "Revert "[IOT-1714]Add wifi.p2p connection status changed intent receiver"" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       2df361249fca0230c55473d2b430416ff5cb5836
+User:           jaehong jo
+Date:           Mon Jan 09 08:12:19 KST 2017
+Comment:        
+Revert "[IOT-1714]Add wifi.p2p connection status changed intent receiver"
+
+This reverts commit 58a3604b455ea16982e6f6de2b04118ff633edc8.
+
+Change-Id: I926baf6e7113f77b6fb803de4492e99605855feb
+Modifications:  
+  MODIFY       android/android_api/base/src/main/java/org/iotivity/ca/CaIpInterface.java       2df361249fca0230c55473d2b430416ff5cb5836:58a3604b455ea16982e6f6de2b04118ff633edc8       null
+--------------------------------------------------------------------------------
+Revision:       ed2ea1917298987eb384c6239b0e0724e2fa490b
+User:           jaehong jo
+Date:           Sat Jan 07 15:52:09 KST 2017
+Comment:        
+Merge "To support start/stop LE advertising API for android" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       4a560587b670f95d594b2386f0768c9cb448f9c5
+User:           jihwan seo
+Date:           Sat Jan 07 15:28:50 KST 2017
+Comment:        
+Merge "Revert "[SAMSUNG] temp pathc : replace MTU size with 514 byte"" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       872c8a18f8a2900aa3ddcda3e75a6dcdc9c1a917
+User:           jihwan seo
+Date:           Sat Jan 07 15:28:46 KST 2017
+Comment:        
+Revert "[SAMSUNG] temp pathc : replace MTU size with 514 byte"
+
+This reverts commit d00c6fec635e3cd3d1360ca48a0e097a47230cf9.
+
+Change-Id: Id307b7550794c6c29c3931c409ff935be40b5281
+Modifications:  
+  MODIFY       resource/csdk/connectivity/inc/cafragmentation.h        872c8a18f8a2900aa3ddcda3e75a6dcdc9c1a917:d00c6fec635e3cd3d1360ca48a0e097a47230cf9       null
+--------------------------------------------------------------------------------
+Revision:       951558a269828159a1c6e1d3e74a752960fc7dae
+User:           jihwan.seo
+Date:           Sat Jan 07 15:20:26 KST 2017
+Comment:        
+To support start/stop LE advertising API for android
+
+Change-Id: I3201e563cdd07bb84c38639f9a2b6743122b2385
+Signed-off-by: jihwan.seo <jihwan.seo@samsung.com>
+Modifications:  
+  MODIFY       android/android_api/base/jni/JniCaInterface.c   951558a269828159a1c6e1d3e74a752960fc7dae:3d2bee77cf604c3aa82d99367f50ee1ee1c7b7e3       null
+  MODIFY       android/android_api/base/src/main/java/org/iotivity/ca/CaInterface.java 951558a269828159a1c6e1d3e74a752960fc7dae:3d2bee77cf604c3aa82d99367f50ee1ee1c7b7e3       null
+  MODIFY       resource/csdk/connectivity/api/cautilinterface.h        951558a269828159a1c6e1d3e74a752960fc7dae:3d2bee77cf604c3aa82d99367f50ee1ee1c7b7e3       null
+  MODIFY       resource/csdk/connectivity/util/inc/camanagerleinterface.h      951558a269828159a1c6e1d3e74a752960fc7dae:3d2bee77cf604c3aa82d99367f50ee1ee1c7b7e3       null
+  MODIFY       resource/csdk/connectivity/util/src/camanager/bt_le_manager/android/caleconnectionmanager.c     951558a269828159a1c6e1d3e74a752960fc7dae:3d2bee77cf604c3aa82d99367f50ee1ee1c7b7e3       null
+  MODIFY       resource/csdk/connectivity/util/src/cautilinterface.c   951558a269828159a1c6e1d3e74a752960fc7dae:3d2bee77cf604c3aa82d99367f50ee1ee1c7b7e3       null
+--------------------------------------------------------------------------------
+Revision:       3d2bee77cf604c3aa82d99367f50ee1ee1c7b7e3
+User:           jihwan seo
+Date:           Sat Jan 07 12:44:17 KST 2017
+Comment:        
+Merge "Updates for VD BLE support (Tizen TV) - Added calenwmonitor_vd.c" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       d4611ef24f131302fa08fe8a55ee6199a78d9bc9
+User:           js126 lee
+Date:           Fri Jan 06 18:46:14 KST 2017
+Comment:        
+Merge "Modify SetupCipher() to support multiple ciphersuites" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       715f88dde7acc4878c6b1f30e5af0adba2aa6189
+User:           chuls lee
+Date:           Fri Jan 06 18:27:28 KST 2017
+Comment:        
+Merge "Removed compiler warnings for security modules." into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       b261d0d7c4483a6eb57d8cdb0336ed6b31fcbbfe
+User:           Jongmin Choi
+Date:           Fri Jan 06 18:25:24 KST 2017
+Comment:        
+Modify SetupCipher() to support multiple ciphersuites
+
+SetupCipher() modified to support multiple ciphersuites
+
+Patch #1: initial upload
+
+Change-Id: Ie61b4116e41c0845082eda9ca8ab9c859a1fc5b0
+Signed-off-by: Jongmin Choi <jminl.choi@samsung.com>
+Modifications:  
+  MODIFY       resource/csdk/connectivity/src/adapter_util/ca_adapter_net_ssl.c        b261d0d7c4483a6eb57d8cdb0336ed6b31fcbbfe:54b3ab75572776e83c013765c3771749c6f22389       null
+--------------------------------------------------------------------------------
+Revision:       279da96989d40545fcf687835b03b8d49756944a
+User:           Jihun Ha
+Date:           Fri Jan 06 18:24:05 KST 2017
+Comment:        
+Merge "Static Analysis(SVACE) issue fixes on Notification consumer." into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       54b3ab75572776e83c013765c3771749c6f22389
+User:           jihwan seo
+Date:           Fri Jan 06 17:59:24 KST 2017
+Comment:        
+Merge "Added #ifdef preprocessor about CASetMulticastTTL() API" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       b1c33772fa0caf3124d965c511d54ea5e219d5b6
+User:           js126 lee
+Date:           Fri Jan 06 17:37:44 KST 2017
+Comment:        
+Merge "TLS suites" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       bc6e5fb39d4f665a67b3d3ccba70ecbfa729d4f7
+User:           yw1201 kim
+Date:           Fri Jan 06 17:29:34 KST 2017
+Comment:        
+Merge "1. iOS BLE connectivity added 2. Style update and fixes" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       9c9310b2e44d1f0d3a3b7ca356399bdcd741e79a
+User:           hyuna0213.jo
+Date:           Fri Jan 06 16:51:13 KST 2017
+Comment:        
+Added #ifdef preprocessor about CASetMulticastTTL() API
+
+Change-Id: Ib6f35958f155c45de630c02b3864de366efaaccd
+Signed-off-by: hyuna0213.jo <hyuna0213.jo@samsung.com>
+Modifications:  
+  MODIFY       resource/csdk/connectivity/inc/cainterfacecontroller.h  9c9310b2e44d1f0d3a3b7ca356399bdcd741e79a:547adc192af77e436c1f0f16164d2c1b44fbba6a       null
+  MODIFY       resource/csdk/connectivity/src/cainterfacecontroller.c  9c9310b2e44d1f0d3a3b7ca356399bdcd741e79a:547adc192af77e436c1f0f16164d2c1b44fbba6a       null
+--------------------------------------------------------------------------------
+Revision:       547adc192af77e436c1f0f16164d2c1b44fbba6a
+User:           Parkhi
+Date:           Fri Jan 06 14:56:26 KST 2017
+Comment:        
+[CONPRO-553] Changed all of easysetup-callback-function to static member
+function. This change can protect from crash when class instance is removed.
+
+Change-Id: I0db76ee443a88ac15d11d62a44af0b92b754d697
+Signed-off-by: Parkhi <h_w.park@samsung.com>
+Reviewed-on: https://gerrit.iotivity.org/gerrit/16037
+Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
+Reviewed-by: Jihun Ha <jihun.ha@samsung.com>
+Reviewed-by: Uze Choi <uzchoi@samsung.com>
+Signed-off-by: Parkhi <h_w.park@samsung.com>
+Modifications:  
+  MODIFY       service/easy-setup/mediator/richsdk/inc/RemoteEnrollee.h        547adc192af77e436c1f0f16164d2c1b44fbba6a:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       service/easy-setup/mediator/richsdk/src/CloudResource.cpp       547adc192af77e436c1f0f16164d2c1b44fbba6a:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       service/easy-setup/mediator/richsdk/src/CloudResource.h 547adc192af77e436c1f0f16164d2c1b44fbba6a:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       service/easy-setup/mediator/richsdk/src/EnrolleeResource.cpp    547adc192af77e436c1f0f16164d2c1b44fbba6a:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       service/easy-setup/mediator/richsdk/src/EnrolleeResource.h      547adc192af77e436c1f0f16164d2c1b44fbba6a:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       service/easy-setup/mediator/richsdk/src/EnrolleeSecurity.cpp    547adc192af77e436c1f0f16164d2c1b44fbba6a:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       service/easy-setup/mediator/richsdk/src/EnrolleeSecurity.h      547adc192af77e436c1f0f16164d2c1b44fbba6a:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       service/easy-setup/mediator/richsdk/src/RemoteEnrollee.cpp      547adc192af77e436c1f0f16164d2c1b44fbba6a:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+--------------------------------------------------------------------------------
+Revision:       82fecb62dfd44d4b261502edf0b28264c34201a0
+User:           Jongmin Choi
+Date:           Fri Jan 06 13:33:40 KST 2017
+Comment:        
+TLS suites
+
+1. Added:
+   TLS_RSA_WITH_AES_256_CBC_SHA256          0x3D
+   TLS_RSA_WITH_AES_128_GCM_SHA256          0x009C
+   TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256  0xC02B
+   TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384  0xC024
+   TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384  0xC02C
+   TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_256   0xC027
+2. Removed:
+   TLS_RSA_WITH_AES_256_CBC_SHA             0x35
+   TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA     0xC009
+3. SSL code refactored
+4. Added unit tests for new cipher suites
+5. CAsslGenerateOwnerPsk modified to support all suites
+
+Change-Id: I33cbf2713a7b4e41d44d4bd97c3dc982d86df403
+Signed-off-by: Oleksii Beketov <ol.beketov@samsung.com>
+Signed-off-by: Dmitriy Zhuravlev <d.zhuravlev@samsung.com>
+Signed-off-by: Oleksii Beketov <ol.beketov@samsung.com>
+Signed-off-by: Jongmin Choi <jminl.choi@samsung.com>
+Reviewed-on: https://gerrit.iotivity.org/gerrit/15443
+Reviewed-by: Jongsung Lee <js126.lee@samsung.com>
+Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
+Reviewed-by: Greg Zaverucha <gregz@microsoft.com>
+Reviewed-by: Randeep Singh <randeep.s@samsung.com>
+Modifications:  
+  MODIFY       android/android_api/base/src/main/java/org/iotivity/ca/OicCipher.java   82fecb62dfd44d4b261502edf0b28264c34201a0:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       resource/csdk/connectivity/api/casecurityinterface.h    82fecb62dfd44d4b261502edf0b28264c34201a0:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       resource/csdk/connectivity/inc/ca_adapter_net_ssl.h     82fecb62dfd44d4b261502edf0b28264c34201a0:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       resource/csdk/connectivity/src/adapter_util/ca_adapter_net_ssl.c        82fecb62dfd44d4b261502edf0b28264c34201a0:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       resource/csdk/connectivity/src/caconnectivitymanager.c  82fecb62dfd44d4b261502edf0b28264c34201a0:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       resource/csdk/connectivity/test/ssladapter_test.cpp     82fecb62dfd44d4b261502edf0b28264c34201a0:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       resource/csdk/security/provisioning/sample/cloud/cloudCommon.c  82fecb62dfd44d4b261502edf0b28264c34201a0:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       resource/csdk/security/provisioning/src/ownershiptransfermanager.c      82fecb62dfd44d4b261502edf0b28264c34201a0:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       resource/csdk/security/provisioning/src/oxmmanufacturercert.c   82fecb62dfd44d4b261502edf0b28264c34201a0:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       resource/csdk/security/src/credresource.c       82fecb62dfd44d4b261502edf0b28264c34201a0:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+  MODIFY       resource/include/CAManager.h    82fecb62dfd44d4b261502edf0b28264c34201a0:db348f74888b03f7aa82db5682b5dd57c137e43d       null
+--------------------------------------------------------------------------------
+Revision:       db348f74888b03f7aa82db5682b5dd57c137e43d
+User:           jminl choi
+Date:           Fri Jan 06 12:59:04 KST 2017
+Comment:        
+Merge "Fix for patchset 15853" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       c30a318f97d8a5c2ae7c85311f4141018bdf072a
+User:           jminl choi
+Date:           Fri Jan 06 12:58:23 KST 2017
+Comment:        
+Merge "Send alert after bad client hello" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       f8a4e7eb5ee3cbb2e0d83211774fccafdc7624ad
+User:           js126.lee
+Date:           Fri Jan 06 12:44:59 KST 2017
+Comment:        
+Send alert after bad client hello
+
+Fix the following situation:
+1. client tries OTM to server
+2. OTM completed
+3. network of server goes down and up => DTLS session has been removed
+4. client tries to send a request to secure resource(e.g., /oic/sec/acl)
+5. server prints bad client error(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO), and then ignore this
+6. client never gets a response of it even if re-tries to sent same message
+
+Change-Id: Ie2cd3eaa49fc8782522126799994a5cd47cfaf4e
+Signed-off-by: Dmitriy Zhuravlev <d.zhuravlev@samsung.com>
+Signed-off-by: Oleksii Beketov <ol.beketov@samsung.com>
+Signed-off-by: Joonghwan Lee <jh05.lee@samsung.com>
+Signed-off-by: Jongsung Lee <js126.lee@samsung.com>
+Reviewed-on: https://gerrit.iotivity.org/gerrit/15853
+Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
+Reviewed-by: Randeep Singh <randeep.s@samsung.com>
+Modifications:  
+  MODIFY       resource/csdk/connectivity/src/adapter_util/ca_adapter_net_ssl.c        f8a4e7eb5ee3cbb2e0d83211774fccafdc7624ad:2cdfd5beff66b88ec15422b3f1197053ccb9fb2b       null
+--------------------------------------------------------------------------------
+Revision:       2cdfd5beff66b88ec15422b3f1197053ccb9fb2b
+User:           hyuna0213 jo
+Date:           Fri Jan 06 11:17:36 KST 2017
+Comment:        
+Merge "[SAMSUNG] temp pathc : replace MTU size with 514 byte" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       f29333f26eaaa25ee786cb5a294039dcafc90e84
+User:           js126 lee
+Date:           Thu Jan 05 20:40:50 KST 2017
+Comment:        
+Merge "Handshake Changed to One-Way Authentication" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       9ecc1f73df08a75143277c6487d24bba07d6f6c1
+User:           jaehong jo
+Date:           Thu Jan 05 20:24:26 KST 2017
+Comment:        
+Merge "stop BLE advertising for disconnection status.(android/tizen)" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       e17d70666df4195fe88dc00a576ef1eb2fa21aa1
+User:           Chul Lee
+Date:           Thu Jan 05 17:58:21 KST 2017
+Comment:        
+Removed compiler warnings for security modules.
+
+Patch #1 : initial upload.
+Patch #2 : retrigger.
+Patch #3~4 : update according to comments.
+Patch #5 : rebase
+
+Change-Id: Ie5009c484f50d40c8a2e2f9ac7c361cd9a712d93
+Signed-off-by: Chul Lee <chuls.lee@samsung.com>
+Reviewed-on: https://gerrit.iotivity.org/gerrit/15045
+Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
+Reviewed-by: Randeep Singh <randeep.s@samsung.com>
+Modifications:  
+  MODIFY       resource/csdk/security/include/internal/crlresource.h   e17d70666df4195fe88dc00a576ef1eb2fa21aa1:af9a7ecdba7de7b683e6677e9468cde72b014444       null
+  MODIFY       resource/csdk/security/provisioning/include/internal/otmcontextlist.h   e17d70666df4195fe88dc00a576ef1eb2fa21aa1:af9a7ecdba7de7b683e6677e9468cde72b014444       null
+  MODIFY       resource/csdk/security/provisioning/sample/provisioningclient.c e17d70666df4195fe88dc00a576ef1eb2fa21aa1:af9a7ecdba7de7b683e6677e9468cde72b014444       null
+  MODIFY       resource/csdk/security/provisioning/src/credentialgenerator.c   e17d70666df4195fe88dc00a576ef1eb2fa21aa1:af9a7ecdba7de7b683e6677e9468cde72b014444       null
+  MODIFY       resource/csdk/security/provisioning/src/otmcontextlist.c        e17d70666df4195fe88dc00a576ef1eb2fa21aa1:af9a7ecdba7de7b683e6677e9468cde72b014444       null
+  MODIFY       resource/csdk/security/provisioning/src/ownershiptransfermanager.c      e17d70666df4195fe88dc00a576ef1eb2fa21aa1:af9a7ecdba7de7b683e6677e9468cde72b014444       null
+  MODIFY       resource/csdk/security/provisioning/src/pmutility.c     e17d70666df4195fe88dc00a576ef1eb2fa21aa1:af9a7ecdba7de7b683e6677e9468cde72b014444       null
+  MODIFY       resource/csdk/security/provisioning/src/secureresourceprovider.c        e17d70666df4195fe88dc00a576ef1eb2fa21aa1:af9a7ecdba7de7b683e6677e9468cde72b014444       null
+  MODIFY       resource/csdk/security/src/credresource.c       e17d70666df4195fe88dc00a576ef1eb2fa21aa1:af9a7ecdba7de7b683e6677e9468cde72b014444       null
+  MODIFY       resource/csdk/security/src/crlresource.c        e17d70666df4195fe88dc00a576ef1eb2fa21aa1:af9a7ecdba7de7b683e6677e9468cde72b014444       null
+  MODIFY       resource/csdk/security/src/oxmpincommon.c       e17d70666df4195fe88dc00a576ef1eb2fa21aa1:af9a7ecdba7de7b683e6677e9468cde72b014444       null
+  MODIFY       resource/csdk/security/src/pbkdf2.c     e17d70666df4195fe88dc00a576ef1eb2fa21aa1:af9a7ecdba7de7b683e6677e9468cde72b014444       null
+--------------------------------------------------------------------------------
+Revision:       7bfdbb3856c23779d37c81627c4679d6facd150f
+User:           Senthil Kumar G S
+Date:           Thu Jan 05 15:02:23 KST 2017
+Comment:        
+Static Analysis(SVACE) issue fixes on Notification consumer.
+
+Change-Id: Ic7e10fcd7764098151c55684c6c6fa0ad9ac557e
+Signed-off-by: Senthil Kumar G S <senthil.gs@samsung.com>
+Modifications:  
+  MODIFY       service/notification/android/notification-service/src/main/jni/consumer/JniNotificationConsumer.cpp     7bfdbb3856c23779d37c81627c4679d6facd150f:fee573ad11f3e4f3addfe2a43fc1a8a3b2f32668       null
+--------------------------------------------------------------------------------
+Revision:       5a30dc184d68318357c4cb3c8fe1003d90e497f8
+User:           jihwan.seo
+Date:           Thu Jan 05 12:27:17 KST 2017
+Comment:        
+stop BLE advertising for disconnection status.(android/tizen)
+
+since advertising can be caused a big problem related battery.
+it should be stopped when it is not used.
+
+Change-Id: Ib645dafe9cba3218972b655cfa0f5b067ad971eb
+Signed-off-by: jihwan.seo <jihwan.seo@samsung.com>
+Modifications:  
+  MODIFY       resource/csdk/connectivity/src/bt_le_adapter/android/caleserver.c       5a30dc184d68318357c4cb3c8fe1003d90e497f8:31dd40f8572b86096bfd1055ecc145cfa66c47d0       null
+  MODIFY       resource/csdk/connectivity/src/bt_le_adapter/android/caleserver.h       5a30dc184d68318357c4cb3c8fe1003d90e497f8:31dd40f8572b86096bfd1055ecc145cfa66c47d0       null
+  MODIFY       resource/csdk/connectivity/src/bt_le_adapter/tizen/caleserver.c 5a30dc184d68318357c4cb3c8fe1003d90e497f8:31dd40f8572b86096bfd1055ecc145cfa66c47d0       null
+--------------------------------------------------------------------------------
+Revision:       d4b5830d7e10d9cf36dc8133d31ed8e380f3c1f1
+User:           Jongmin Choi
+Date:           Wed Jan 04 18:26:56 KST 2017
+Comment:        
+Handshake Changed to One-Way Authentication
+
+Handshake changed so that only client will verify server certificate
+
+Patch #1: Initial upload
+
+Change-Id: I8faa755022ec2f0f2eab5a4f9037c3fd1243aeb8
+Signed-off-by: Jongmin Choi <jminl.choi@samsung.com>
+Modifications:  
+  MODIFY       resource/csdk/connectivity/src/adapter_util/ca_adapter_net_ssl.c        d4b5830d7e10d9cf36dc8133d31ed8e380f3c1f1:5833fc1fa5af6cfc12c7cd7be762bf6f4711d2a0       null
+--------------------------------------------------------------------------------
+Revision:       fb88a108fbfe6201a3da403b88c2444f3d104c20
+User:           Md. Kamrujjaman Akon
+Date:           Wed Jan 04 17:47:54 KST 2017
+Comment:        
+1. iOS BLE connectivity added
+2. Style update and fixes
+
+Change-Id: Ic18998028410c842c3ada7604508dfcbdc03a73e
+Signed-off-by: Md. Kamrujjaman Akon <mdk.akon@samsung.com>
+Modifications:  
+  MODIFY       resource/csdk/connectivity/api/cautilinterface.h        fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  MODIFY       resource/csdk/connectivity/src/bt_le_adapter/caleadapter.c      fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  ADD  resource/csdk/connectivity/src/bt_le_adapter/ios/SConscript     fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  ADD  resource/csdk/connectivity/src/bt_le_adapter/ios/caleclient.h   fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  ADD  resource/csdk/connectivity/src/bt_le_adapter/ios/caleclient.m   fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  ADD  resource/csdk/connectivity/src/bt_le_adapter/ios/calenwmonitor.h        fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  ADD  resource/csdk/connectivity/src/bt_le_adapter/ios/calenwmonitor.m        fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  ADD  resource/csdk/connectivity/src/bt_le_adapter/ios/caleserver.h   fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  ADD  resource/csdk/connectivity/src/bt_le_adapter/ios/caleserver.m   fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  ADD  resource/csdk/connectivity/src/bt_le_adapter/ios/caleutils.h    fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  MODIFY       resource/csdk/connectivity/util/SConscript      fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  MODIFY       resource/csdk/connectivity/util/inc/camanagerleinterface.h      fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  ADD  resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/caleautoconnector.h     fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  ADD  resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/caleautoconnector.m     fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  ADD  resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/caleconnectionmanager.m fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  ADD  resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/camanagerdevice.h       fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  ADD  resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/camanagerdevice.m       fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  ADD  resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/camanagerleutil.h       fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  ADD  resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/camanagerleutil.m       fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+  MODIFY       resource/csdk/connectivity/util/src/cautilinterface.c   fb88a108fbfe6201a3da403b88c2444f3d104c20:f967b376c3dd5eaf0729ab439e55a0cdaed223cd       null
+--------------------------------------------------------------------------------
+Revision:       af9a7ecdba7de7b683e6677e9468cde72b014444
+User:           Jongmin Choi
+Date:           Tue Jan 03 19:05:00 KST 2017
+Comment:        
+Modify Reset Profile to include cred resource
+
+Reset Profile modified to include cred resource
+https://gerrit.iotivity.org/gerrit/#/c/16111/
+
+Patch #1: Initial upload
+Patch #2: ResetSecureResourceInPS() modified
+
+Change-Id: I5ed286ac43b32f3e04d33a9d0f1428a7443d7c08
+Signed-off-by: Jongmin Choi <jminl.choi@samsung.com>
+Reviewed-on: https://gerrit.iotivity.org/gerrit/16111
+Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
+Reviewed-by: Chul Lee <chuls.lee@samsung.com>
+Reviewed-by: Randeep Singh <randeep.s@samsung.com>
+Modifications:  
+  MODIFY       resource/csdk/security/src/psinterface.c        af9a7ecdba7de7b683e6677e9468cde72b014444:fee573ad11f3e4f3addfe2a43fc1a8a3b2f32668       null
+--------------------------------------------------------------------------------
+Revision:       e7449c4a6b1297359c21410d20f88a40e5b90f0b
+User:           Dmitriy Zhuravlev
+Date:           Fri Dec 30 16:28:14 KST 2016
+Comment:        
+Fix for patchset 15853
+
+Fixed OTM error caused by patchset 15853.
+Added close notify alert sending to DeletePeerList()
+
+Change-Id: Ib5363f8d16358a388df0f003e9111f1d56ccca62
+Signed-off-by: Oleksii Beketov <ol.beketov@samsung.com>
+Signed-off-by: Dmitriy Zhuravlev <d.zhuravlev@samsung.com>
+Signed-off-by: Jongsung Lee <js126.lee@samsung.com>
+Reviewed-on: https://gerrit.iotivity.org/gerrit/16001
+Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
+Reviewed-by: Chul Lee <chuls.lee@samsung.com>
+Reviewed-by: Jongsung Lee <js126.lee@samsung.com>
+Reviewed-by: Randeep Singh <randeep.s@samsung.com>
+Modifications:  
+  MODIFY       resource/csdk/connectivity/src/adapter_util/ca_adapter_net_ssl.c        e7449c4a6b1297359c21410d20f88a40e5b90f0b:f8a4e7eb5ee3cbb2e0d83211774fccafdc7624ad       null
+--------------------------------------------------------------------------------
+Revision:       4f01a28f4039959e481a14331489f5dc13debc8e
+User:           MSK
+Date:           Fri Dec 30 12:42:48 KST 2016
+Comment:        
+Updates for VD BLE support (Tizen TV)
+- Added calenwmonitor_vd.c
+
+Change-Id: I986dda7d72862988b17f4d0644715f6e6c83ae97
+Modifications:  
+  MODIFY       resource/csdk/connectivity/src/bt_le_adapter/tizen/SConscript   4f01a28f4039959e481a14331489f5dc13debc8e:ac2a56d8f2b8a8397b83b13be43b4e6564e75982       null
+  ADD  resource/csdk/connectivity/src/bt_le_adapter/tizen/calenwmonitor_vd.c   4f01a28f4039959e481a14331489f5dc13debc8e:ac2a56d8f2b8a8397b83b13be43b4e6564e75982       null
+  MODIFY       resource/csdk/connectivity/src/bt_le_adapter/tizen/caleserver_vd.c      4f01a28f4039959e481a14331489f5dc13debc8e:ac2a56d8f2b8a8397b83b13be43b4e6564e75982       null
+--------------------------------------------------------------------------------
+Revision:       f7688681728e25094273934d7ef79395a2ef1f30
+User:           hyuna0213.jo
+Date:           Wed Dec 28 08:56:11 KST 2016
+Comment:        
+Send error response in case request msg type is unicast
+
+It is unnecessary to respond to a multicast request
+
+Change-Id: I071300b21e8d56459bee4f29b9c031ceed973067
+Signed-off-by: hyuna0213.jo <hyuna0213.jo@samsung.com>
+Modifications:  
+  MODIFY       resource/csdk/stack/src/ocstack.c       f7688681728e25094273934d7ef79395a2ef1f30:e775ce68b215d8cf6a7e3f43595de81605b9aa4d       null
+--------------------------------------------------------------------------------
+Revision:       34fc43e4e36fc21097e6ca52176d0766158b3ecf
+User:           js126.lee
+Date:           Tue Dec 27 17:15:28 KST 2016
+Comment:        
+Add revstat into optdata of Cred according to OCF spec
+
+Accoding to ocf security spec, revstat is mandatory property.
+"revstat": {
+  "type": "boolean",
+  "description": "Revocation status flag
+                - true = revoked, false = not revoked"
+
+Patch 1: upload patch.
+Patch 2: update json2cbor.c to convert revstat
+
+Change-Id: Ifbb7743f8321cb8afbf69cfa307694598e24ea6e
+Signed-off-by: js126.lee <js126.lee@samsung.com>
+Reviewed-on: https://gerrit.iotivity.org/gerrit/15951
+Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
+Reviewed-by: Chul Lee <chuls.lee@samsung.com>
+Reviewed-by: Randeep Singh <randeep.s@samsung.com>
+Modifications:  
+  MODIFY       resource/csdk/security/include/internal/srmresourcestrings.h    34fc43e4e36fc21097e6ca52176d0766158b3ecf:2cdfd5beff66b88ec15422b3f1197053ccb9fb2b       null
+  MODIFY       resource/csdk/security/include/securevirtualresourcetypes.h     34fc43e4e36fc21097e6ca52176d0766158b3ecf:2cdfd5beff66b88ec15422b3f1197053ccb9fb2b       null
+  MODIFY       resource/csdk/security/provisioning/src/secureresourceprovider.c        34fc43e4e36fc21097e6ca52176d0766158b3ecf:2cdfd5beff66b88ec15422b3f1197053ccb9fb2b       null
+  MODIFY       resource/csdk/security/src/credresource.c       34fc43e4e36fc21097e6ca52176d0766158b3ecf:2cdfd5beff66b88ec15422b3f1197053ccb9fb2b       null
+  MODIFY       resource/csdk/security/src/srmresourcestrings.c 34fc43e4e36fc21097e6ca52176d0766158b3ecf:2cdfd5beff66b88ec15422b3f1197053ccb9fb2b       null
+  MODIFY       resource/csdk/security/tool/json2cbor.c 34fc43e4e36fc21097e6ca52176d0766158b3ecf:2cdfd5beff66b88ec15422b3f1197053ccb9fb2b       null
+--------------------------------------------------------------------------------
+Revision:       d00c6fec635e3cd3d1360ca48a0e097a47230cf9
+User:           jihwan.seo
+Date:           Tue Dec 27 14:15:01 KST 2016
+Comment:        
+[SAMSUNG] temp pathc : replace MTU size with 514 byte
+
+Change-Id: I41336dffb9c42019da7c0a676fb5fa63f8627003
+Signed-off-by: jihwan.seo <jihwan.seo@samsung.com>
+Modifications:  
+  MODIFY       resource/csdk/connectivity/inc/cafragmentation.h        d00c6fec635e3cd3d1360ca48a0e097a47230cf9:65ed3e6ea7f36d86e83c369e202a4712d2b79f65       null
+=======
+ cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/67/104767/1 && git cherry-pick FETCH_HEAD
+----------------------------------------------------------------------------------------------------------------------------------
+ http://suprem.sec.samsung.net/jira/browse/CONPRO-419
+
+ commit_info_2016-12-07.txt
+
+ commit_id: d30d635f1f83a1186885c35121cb0cdaa48b9bfd
+
+ cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/72/101872/7 && git cherry-pick FETCH_HEAD
+ cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/75/103475/4 && git cherry-pick FETCH_HEAD
+ cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/95/103495/3 && git cherry-pick FETCH_HEAD
+ cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/21/103621/1 && git cherry-pick FETCH_HEAD
+ cherrypick_cmd_id: git fetch http://suprem.sec.samsung.net/gerrit/IoTivity refs/changes/31/103631/1 && git cherry-pick FETCH_HEAD
+----------------------------------------------------------------------------------------------------------------------------------
+>>>>>>> e3989364802dccd6e7f25980ebf9c6da4104960d
+
+change_set: (from commit dc1f37ac0b54dade9f8bc1b5c9fe345729b8a4e4)
+--------------------------------------------------------------------------------
+Revision:       a0fa1b90b075ee3e5c500d3ce0f0f5572e35e429
+User:           chuls lee
+Date:           Thu Jan 12 12:55:12 KST 2017
+Comment:        
+Merge "Modify confirmable certificate OTM" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       7b0c28e3b2927fe9cce7340e6b20086b3dce8c59
+User:           jaehong jo
+Date:           Thu Jan 12 12:50:21 KST 2017
+Comment:        
+Merge "[CONPRO-575] Fixed crash issue when OCStop." into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       065234ad5a55d1681b18b9e77ce0d1652e2afcad
+User:           Joonghwan Lee
+Date:           Thu Jan 12 12:50:12 KST 2017
+Comment:        
+Merge "Changed gbsbuild.sh's permission." into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       eaa28609484dfefe7248e4c4cdf0324c5e453dfb
+User:           Chul Lee
+Date:           Thu Jan 12 12:46:03 KST 2017
+Comment:        
+Changed gbsbuild.sh's permission.
+
+Change-Id: I5f30401e86b7920b765fc162b82260cbd59aea93
+Signed-off-by: Chul Lee <chuls.lee@samsung.com>
+Modifications:  
+  MODIFY  gbsbuild.sh eaa28609484dfefe7248e4c4cdf0324c5e453dfb:19a2c96229168f0b80c36f666973ce749b42e2b4 null
+  MODIFY  resource/csdk/connectivity/build/tizen/gbsbuild.sh  eaa28609484dfefe7248e4c4cdf0324c5e453dfb:19a2c96229168f0b80c36f666973ce749b42e2b4 null
+  MODIFY  resource/csdk/stack/samples/tizen/build/gbsbuild.sh eaa28609484dfefe7248e4c4cdf0324c5e453dfb:19a2c96229168f0b80c36f666973ce749b42e2b4 null
+  MODIFY  service/easy-setup/sampleapp/enrollee/tizen-sdb/EnrolleeSample/build/tizen/gbsbuild.sh  eaa28609484dfefe7248e4c4cdf0324c5e453dfb:19a2c96229168f0b80c36f666973ce749b42e2b4 null
+--------------------------------------------------------------------------------
+Revision:       53d6e1a435a49b123862b7ddb504c56e1de69d6a
+User:           chuls lee
+Date:           Thu Jan 12 12:45:41 KST 2017
+Comment:        
+Merge "Add NULL check in StartRetransmit function." into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       19a2c96229168f0b80c36f666973ce749b42e2b4
+User:           dongik lee
+Date:           Thu Jan 12 10:07:06 KST 2017
+Comment:        
+Merge "Switch to non-confirmable message for Confirm cases" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       e2346ac58485bbd6a89afb560da35e9c3eabce91
+User:           chuls lee
+Date:           Thu Jan 12 10:00:29 KST 2017
+Comment:        
+Merge "Add NULL check in StartRetransmit function." into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       0aac13bff9aa7e641a8ca0675d2bb6e06a98e591
+User:           jaehong jo
+Date:           Thu Jan 12 08:24:42 KST 2017
+Comment:        
+Merge "[CONPRO-575] Fixed crash issue when OCStop." into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       5d4b029804d464302ae47723c911ef53ff93a515
+User:           jaehong jo
+Date:           Wed Jan 11 19:17:19 KST 2017
+Comment:        
+Merge "[CONPRO-589] Fixed Thread-unsafe code in caqueueingthread.c" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       71eb272ea15baf3193fe7e18c1b48fe309669f3f
+User:           hyuna0213.jo
+Date:           Wed Jan 11 18:05:41 KST 2017
+Comment:        
+[CONPRO-589] Fixed Thread-unsafe code in caqueueingthread.c
+
+Change-Id: Ie38bcef494a614a98f519425f75998345f35ebb0
+Signed-off-by: hyuna0213.jo <hyuna0213.jo@samsung.com>
+Modifications:  
+  MODIFY  resource/csdk/connectivity/src/caqueueingthread.c 71eb272ea15baf3193fe7e18c1b48fe309669f3f:f036dd3dda3a8b05543a16e75cb73e395ea807d1 null
+--------------------------------------------------------------------------------
+Revision:       aa2963b82f62e376e60a6837e51de3a1691dd027
+User:           Chul Lee
+Date:           Wed Jan 11 17:45:26 KST 2017
+Comment:        
+Add NULL check in StartRetransmit function.
+
+Change-Id: Ia7772c1cd574be8b001a43e7b6b482663dc2a2b4
+Signed-off-by: Chul Lee <chuls.lee@samsung.com>
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       5b5eec57142ae233873975917fa607e70864d5c2
+User:           Chul Lee
+Date:           Wed Jan 11 17:45:26 KST 2017
+Comment:        
+Add NULL check in StartRetransmit function.
+
+Change-Id: Ia7772c1cd574be8b001a43e7b6b482663dc2a2b4
+Signed-off-by: Chul Lee <chuls.lee@samsung.com>
+Modifications:  
+  MODIFY  resource/csdk/connectivity/src/adapter_util/ca_adapter_net_ssl.c  5b5eec57142ae233873975917fa607e70864d5c2:388321ff2a35273e60273a8c12c11069bc5494af null
+--------------------------------------------------------------------------------
+Revision:       388321ff2a35273e60273a8c12c11069bc5494af
+User:           hyuna0213 jo
+Date:           Wed Jan 11 17:22:58 KST 2017
+Comment:        
+Merge "fix to pending terminate logic when call OCStop" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       34665f457160f14a70fb1ea5f4ac4aa3df8fa2a0
+User:           jihwan seo
+Date:           Wed Jan 11 17:02:03 KST 2017
+Comment:        
+Merge "Add log messages on cathreadpool to improve debugging" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       f60d79322be5a9c20a7104f7bb2c2c8f620d8218
+User:           jihwan.seo
+Date:           Wed Jan 11 17:01:05 KST 2017
+Comment:        
+fix to pending terminate logic when call OCStop
+
+Change-Id: If5e02f49b8d0a69c6b2d1ed90ba9370f9da6328e
+Signed-off-by: jihwan.seo <jihwan.seo@samsung.com>
+Modifications:  
+  MODIFY  resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.c f60d79322be5a9c20a7104f7bb2c2c8f620d8218:827689d6f67d11b254bb04a01148df7971459afc null
+  MODIFY  resource/csdk/connectivity/src/bt_le_adapter/caleadapter.c  f60d79322be5a9c20a7104f7bb2c2c8f620d8218:827689d6f67d11b254bb04a01148df7971459afc null
+--------------------------------------------------------------------------------
+Revision:       269e3f882e38ed58c6b8c8ee4f41642344cdc254
+User:           hyuna0213.jo
+Date:           Wed Jan 11 15:07:29 KST 2017
+Comment:        
+Add log messages on cathreadpool to improve debugging
+
+Change-Id: Ic2163e4f84a9c5c4525f072e08c6f5a5b21ca1d9
+Signed-off-by: hyuna0213.jo <hyuna0213.jo@samsung.com>
+Modifications:  
+  MODIFY  resource/csdk/connectivity/common/src/cathreadpool_pthreads.c 269e3f882e38ed58c6b8c8ee4f41642344cdc254:f036dd3dda3a8b05543a16e75cb73e395ea807d1 null
+--------------------------------------------------------------------------------
+Revision:       52bf8944e8a17131c2b2727d822560ef88edd799
+User:           Chul Lee
+Date:           Wed Jan 11 14:24:11 KST 2017
+Comment:        
+Fix the build error for MOT.
+
+This error was caused by https://gerrit.iotivity.org/gerrit/#/c/16137/ (remove tinydtls)
+
+Change-Id: I48a68c9de65fdd1816904be3accb94e78381be40
+Signed-off-by: Chul Lee <chuls.lee@samsung.com>
+Reviewed-on: https://gerrit.iotivity.org/gerrit/16257
+Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
+Reviewed-by: Randeep Singh <randeep.s@samsung.com>
+Modifications:  
+  MODIFY  resource/csdk/security/provisioning/src/multipleownershiptransfermanager.c  52bf8944e8a17131c2b2727d822560ef88edd799:9dbd26a8d5435aaff774c8fac067e0ad9b5f2032 null
+  MODIFY  resource/csdk/security/src/doxmresource.c 52bf8944e8a17131c2b2727d822560ef88edd799:9dbd26a8d5435aaff774c8fac067e0ad9b5f2032 null
+--------------------------------------------------------------------------------
+Revision:       9dbd26a8d5435aaff774c8fac067e0ad9b5f2032
+User:           Chul Lee
+Date:           Wed Jan 11 14:22:47 KST 2017
+Comment:        
+Remove tinydtls library.
+
+Change-Id: I78f470af822587f2cd50eac6e9b1fb4ff5b87219
+Signed-off-by: Chul Lee <chuls.lee@samsung.com>
+Reviewed-on: https://gerrit.iotivity.org/gerrit/16137
+Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
+Reviewed-by: Greg Zaverucha <gregz@microsoft.com>
+Reviewed-by: Randeep Singh <randeep.s@samsung.com>
+Modifications:  
+  MODIFY  NOTICE.md 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  MODIFY  build_common/android/SConscript 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/0001-Add-TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256-cipher-su.patch  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/0001-Added-anonymous-ecdh-cipher-suite-into-tinydtls.patch 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/0001-Added-support-in-tinyDTLS-to-support-rehandshake.patch  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/0001-Adding-autoconf-generated-files-in-tinydtls-repo.patch  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/0001-Bug-Fix-in-earlier-rehandhsake-implementation.patch 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/0001-Fix-the-wrong-implementation-about-the-anonymous-cip.patch  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/0001-Fixed-issue-to-pass-PSK-identity-hint-to-application.patch  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/0001-Updated-tinyDTLS-test-apps-to-use-identity-hint.patch 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/0001-add-support-of-X.509-into-tinyDTLS-external-library.patch 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/Android.mk 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/LICENSE  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/Makefile.in  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/Makefile.tinydtls  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/README 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/README_Iotivity  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/SConscript 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/aes/Makefile.in  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/aes/rijndael.c 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/aes/rijndael.h 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/alert.h  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/ccm.c  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/ccm.h  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/configure.in 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/crypto.c 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/crypto.h 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/debug.c  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/debug.h  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/doc/Doxyfile.in  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/doc/DoxygenLayout.xml  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/doc/Makefile.in  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/dtls.c 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/dtls.h 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/dtls_config.h  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/dtls_config.h.in 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/dtls_hal.h 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/dtls_time.c  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/dtls_time.h  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/ecc/LICENSE.txt  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/ecc/Makefile.contiki 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/ecc/Makefile.ecc 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/ecc/Makefile.in  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/ecc/README.md  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/ecc/asm_arm.inc  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/ecc/asm_avr.inc  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/ecc/ecc.c  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/ecc/ecc.h  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/ecc/test/ecc_test/ecc_test.ino 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/ecc/test/emk_rules.py  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/ecc/test/test_ecdh.c 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/ecc/test/test_ecdsa.c  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/examples/contiki/Makefile.in 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/examples/contiki/dtls-client.c 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/examples/contiki/dtls-server.c 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/global.h 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/hmac.c 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/hmac.h 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/netq.c 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/netq.h 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/numeric.h  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/peer.c 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/peer.h 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/platform-specific/Makefile.in  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/platform-specific/config-cc2538dk.h  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/platform-specific/config-econotag.h  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/platform-specific/config-minimal-net.h 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/platform-specific/config-sky.h 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/platform-specific/config-wismote.h 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/prng.h 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/session.c  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/session.h  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/Makefile.in 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/README  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/sha2.c  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/sha2.h  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/sha2prog.c  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/sha2speed.c 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/sha2test.pl 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector001.dat 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector001.info  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector002.dat 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector002.info  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector003.dat 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector003.info  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector004.dat 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector004.info  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector005.dat 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector005.info  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector006.dat 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector006.info  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector007.dat 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector007.info  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector008.dat 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector008.info  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector009.dat 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector009.info  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector010.dat 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector010.info  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector011.dat 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector011.info  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector012.dat 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector012.info  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector013.dat 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector013.info  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector014.dat 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector014.info  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector015.dat 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector015.info  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector016.dat 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector016.info  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector017.dat 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector017.info  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector018.dat 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/sha2/testvectors/vector018.info  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/state.h  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/t_list.h 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/tests/Makefile.in  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/tests/cbc_aes128-test.c  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/tests/cbc_aes128-testdata.c  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/tests/ccm-test.c 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/tests/ccm-testdata.c 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/tests/dsrv-test.c  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/tests/dtls-client.c  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/tests/dtls-server.c  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/tests/netq-test.c  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/tests/pcap.c 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/tests/prf-test.c 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/tests/secure-server.c  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/tinydtls.h 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/tinydtls.h.in  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/uthash.h 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  DELETE  extlibs/tinydtls/utlist.h 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  MODIFY  gbsbuild.sh 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  ADD resource/c_common/utlist.h  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  MODIFY  resource/csdk/SConscript  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  MODIFY  resource/csdk/connectivity/build/android/jni/Android.mk 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  MODIFY  resource/csdk/connectivity/build/tizen/Makefile 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  MODIFY  resource/csdk/connectivity/build/tizen/gbsbuild.sh  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  MODIFY  resource/csdk/connectivity/build/tizen/packaging/com.oic.ca.spec  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  MODIFY  resource/csdk/connectivity/src/SConscript 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  MODIFY  resource/csdk/security/SConscript 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  MODIFY  resource/csdk/security/provisioning/SConscript  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  MODIFY  resource/csdk/security/provisioning/sample/SConscript 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  MODIFY  resource/csdk/security/provisioning/src/ownershiptransfermanager.c  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  MODIFY  resource/csdk/security/provisioning/src/oxmjustworks.c  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  MODIFY  resource/csdk/security/provisioning/src/oxmmanufacturercert.c 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  MODIFY  resource/csdk/security/provisioning/src/oxmpreconfpin.c 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  MODIFY  resource/csdk/security/provisioning/src/oxmrandompin.c  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  MODIFY  resource/csdk/security/provisioning/unittest/SConscript 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  MODIFY  resource/csdk/security/src/credresource.c 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  MODIFY  resource/csdk/security/src/directpairing.c  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  MODIFY  resource/csdk/security/src/doxmresource.c 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  MODIFY  resource/csdk/security/src/dpairingresource.c 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  MODIFY  resource/csdk/security/unittest/SConscript  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  MODIFY  resource/csdk/stack/samples/linux/SimpleClientServer/SConscript 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  MODIFY  resource/csdk/stack/samples/linux/secure/SConscript 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  MODIFY  resource/csdk/stack/samples/tizen/build/gbsbuild.sh 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  MODIFY  resource/csdk/stack/samples/tizen/build/packaging/com.oic.ri.spec 9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  MODIFY  service/coap-http-proxy/unittests/SConscript  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+  MODIFY  service/easy-setup/sampleapp/enrollee/tizen-sdb/EnrolleeSample/build/tizen/gbsbuild.sh  9dbd26a8d5435aaff774c8fac067e0ad9b5f2032:ff1bd1c4e3451634f8bccb427de6077af323cb82 null
+--------------------------------------------------------------------------------
+Revision:       ff1bd1c4e3451634f8bccb427de6077af323cb82
+User:           Joonghwan Lee
+Date:           Wed Jan 11 12:46:53 KST 2017
+Comment:        
+Merge "Modify SetResult to handle reset usecase" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       2d992b706768940def20fadf86f5f488e3834c2a
+User:           js126.lee
+Date:           Wed Jan 11 11:34:27 KST 2017
+Comment:        
+[CONPRO-593]Remove duplicated deviceID check in PM_Discovery
+
+Patch 1: upload
+Patch 2,3: If self reply, discard it.
+Patch 4: Retriger jenkins build
+Patch 5: Resolve conflict
+
+Change-Id: Ife6bf2a802aa17da63899ad904a1df085696340e
+Signed-off-by: js126.lee <js126.lee@samsung.com>
+Reviewed-on: https://gerrit.iotivity.org/gerrit/16297
+Reviewed-by: Chul Lee <chuls.lee@samsung.com>
+Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
+Reviewed-by: Randeep Singh <randeep.s@samsung.com>
+Modifications:  
+  MODIFY  resource/csdk/security/provisioning/src/pmutility.c 2d992b706768940def20fadf86f5f488e3834c2a:388321ff2a35273e60273a8c12c11069bc5494af null
+--------------------------------------------------------------------------------
+Revision:       462efb44880008008819e1f892f786c22dc55361
+User:           Jongmin Choi
+Date:           Wed Jan 11 11:22:50 KST 2017
+Comment:        
+Modify confirmable certificate OTM
+
+- In case of user denial, send relevant error message
+- Reset in case of confirmation failure
+
+Patch #1: initial upload
+Patch #2: OC_STACK_NOT_ACCEPTABLE added
+
+Change-Id: I9fe67488f4d19bab1b2cf222547e799be762f5f8
+Signed-off-by: Jongmin Choi <jminl.choi@samsung.com>
+Reviewed-on: https://gerrit.iotivity.org/gerrit/16295
+Reviewed-by: Chul Lee <chuls.lee@samsung.com>
+Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
+Reviewed-by: Randeep Singh <randeep.s@samsung.com>
+Modifications:  
+  MODIFY  android/android_api/base/jni/JniUtils.h 462efb44880008008819e1f892f786c22dc55361:53d6e1a435a49b123862b7ddb504c56e1de69d6a null
+  MODIFY  resource/csdk/security/provisioning/src/ownershiptransfermanager.c  462efb44880008008819e1f892f786c22dc55361:53d6e1a435a49b123862b7ddb504c56e1de69d6a null
+  MODIFY  resource/csdk/security/src/doxmresource.c 462efb44880008008819e1f892f786c22dc55361:53d6e1a435a49b123862b7ddb504c56e1de69d6a null
+  MODIFY  resource/csdk/stack/include/octypes.h 462efb44880008008819e1f892f786c22dc55361:53d6e1a435a49b123862b7ddb504c56e1de69d6a null
+  MODIFY  resource/csdk/stack/src/ocstack.c 462efb44880008008819e1f892f786c22dc55361:53d6e1a435a49b123862b7ddb504c56e1de69d6a null
+  MODIFY  resource/include/StringConstants.h  462efb44880008008819e1f892f786c22dc55361:53d6e1a435a49b123862b7ddb504c56e1de69d6a null
+  MODIFY  resource/src/OCException.cpp  462efb44880008008819e1f892f786c22dc55361:53d6e1a435a49b123862b7ddb504c56e1de69d6a null
+  MODIFY  resource/unittests/OCExceptionTest.cpp  462efb44880008008819e1f892f786c22dc55361:53d6e1a435a49b123862b7ddb504c56e1de69d6a null
+--------------------------------------------------------------------------------
+Revision:       7839869c1bd1d896c40d21f19d09d1ac2a919e28
+User:           js126.lee
+Date:           Tue Jan 10 21:03:02 KST 2017
+Comment:        
+[CONPRO585] Fixed Crash on SRMRequestHanlder
+
+Change-Id: I68de73aa4f737ab5a24dce8215d34b7e1bb8ad8e
+Signed-off-by: js126.lee <js126.lee@samsung.com>
+Modifications:  
+  MODIFY  resource/csdk/security/src/secureresourcemanager.c  7839869c1bd1d896c40d21f19d09d1ac2a919e28:ed12d5a019c06faf3b1db9842c36b08eb74cde51 null
+--------------------------------------------------------------------------------
+Revision:       ed12d5a019c06faf3b1db9842c36b08eb74cde51
+User:           Jongmin Choi
+Date:           Tue Jan 10 20:26:08 KST 2017
+Comment:        
+Support for One-Way Authentication
+
+Support for One-Way Authentication in Handshake
+
+Patch #1: initial upload
+
+Change-Id: I516a446cee5f89b11ad43a9895549b115042f51e
+Signed-off-by: Jongmin Choi <jminl.choi@samsung.com>
+Modifications:  
+  MODIFY  resource/csdk/connectivity/src/adapter_util/ca_adapter_net_ssl.c  ed12d5a019c06faf3b1db9842c36b08eb74cde51:f036dd3dda3a8b05543a16e75cb73e395ea807d1 null
+--------------------------------------------------------------------------------
+Revision:       ad4cf324726d0f362d635c4443e7905b38bbd797
+User:           Jaehong Jo
+Date:           Tue Jan 10 15:13:29 KST 2017
+Comment:        
+[CONPRO-575] Fixed crash issue when OCStop.
+
+Change-Id: Ib836b91960a3698d379d8964a2a1d03e2c8d0f6d
+Signed-off-by: Jaehong Jo <jaehong.jo@samsung.com>
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       3c5125182983e969f1fc681d71c98363883b60ca
+User:           Jaehong Jo
+Date:           Tue Jan 10 15:13:29 KST 2017
+Comment:        
+[CONPRO-575] Fixed crash issue when OCStop.
+
+Change-Id: Ib836b91960a3698d379d8964a2a1d03e2c8d0f6d
+Signed-off-by: Jaehong Jo <jaehong.jo@samsung.com>
+Modifications:  
+  MODIFY  android/android_api/base/src/main/java/org/iotivity/ca/CaBtPairingInterface.java  3c5125182983e969f1fc681d71c98363883b60ca:fa3b737b7d339b4ccc2196314d8c9d7aa6b93ffa null
+  MODIFY  android/android_api/base/src/main/java/org/iotivity/ca/CaEdrInterface.java  3c5125182983e969f1fc681d71c98363883b60ca:fa3b737b7d339b4ccc2196314d8c9d7aa6b93ffa null
+  MODIFY  android/android_api/base/src/main/java/org/iotivity/ca/CaIpInterface.java 3c5125182983e969f1fc681d71c98363883b60ca:fa3b737b7d339b4ccc2196314d8c9d7aa6b93ffa null
+  MODIFY  android/android_api/base/src/main/java/org/iotivity/ca/CaLeClientInterface.java 3c5125182983e969f1fc681d71c98363883b60ca:fa3b737b7d339b4ccc2196314d8c9d7aa6b93ffa null
+  MODIFY  resource/csdk/connectivity/src/tcp_adapter/catcpadapter.c 3c5125182983e969f1fc681d71c98363883b60ca:fa3b737b7d339b4ccc2196314d8c9d7aa6b93ffa null
+--------------------------------------------------------------------------------
+Revision:       f036dd3dda3a8b05543a16e75cb73e395ea807d1
+User:           js126.lee
+Date:           Tue Jan 10 14:50:54 KST 2017
+Comment:        
+Fixed build error on Security
+
+Change-Id: Iad4a8002750af459a82bb34b2151ab747a345215
+Signed-off-by: js126.lee <js126.lee@samsung.com>
+Modifications:  
+  MODIFY  resource/csdk/security/src/doxmresource.c f036dd3dda3a8b05543a16e75cb73e395ea807d1:827689d6f67d11b254bb04a01148df7971459afc null
+  MODIFY  resource/csdk/security/tool/svrdbeditor.c f036dd3dda3a8b05543a16e75cb73e395ea807d1:827689d6f67d11b254bb04a01148df7971459afc null
+--------------------------------------------------------------------------------
+Revision:       827689d6f67d11b254bb04a01148df7971459afc
+User:           jihwan seo
+Date:           Tue Jan 10 13:21:25 KST 2017
+Comment:        
+Merge "Fix stack build error for iOS" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       9a184e394259107f4db08225ed9d244cf28a652a
+User:           hyuna0213.jo
+Date:           Tue Jan 10 13:19:15 KST 2017
+Comment:        
+Fix stack build error for iOS
+
+Change-Id: Ieaf636202d99c894dd53f7bf8d79a32461feefb8
+Signed-off-by: hyuna0213.jo <hyuna0213.jo@samsung.com>
+Modifications:  
+  MODIFY  resource/csdk/stack/include/internal/ocstackinternal.h  9a184e394259107f4db08225ed9d244cf28a652a:8f0063c09f3a3695b55a7ac46d2c9e2dbc2bb7bc null
+--------------------------------------------------------------------------------
+Revision:       78a4328f188670fcbc3579ea8bff9e4ca1b035db
+User:           jihwan seo
+Date:           Tue Jan 10 13:17:07 KST 2017
+Comment:        
+Merge "[SAMSUNG-VER] Update base stack ver tag" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       ac78520efc27a09bdb532057bec4aae44612253e
+User:           jihwan.seo
+Date:           Tue Jan 10 13:16:42 KST 2017
+Comment:        
+[SAMSUNG-VER] Update base stack ver tag
+
+Change-Id: I2cf30b9cd25e1a5ffd0141bb6a9c18078c1e831b
+Signed-off-by: jihwan.seo <jihwan.seo@samsung.com>
+Modifications:  
+  MODIFY  resource/csdk/connectivity/api/cacommon.h ac78520efc27a09bdb532057bec4aae44612253e:02f9d8d7c38552dd70144383754e0257aa94a24f null
+--------------------------------------------------------------------------------
+Revision:       d1fff9be0f8fd9d5d26e93df468473b7ccfe3eac
+User:           Jongmin Choi
+Date:           Tue Jan 10 11:50:24 KST 2017
+Comment:        
+Modify SetResult to handle reset usecase
+
+SetResult modified to handle reset usecases
+- SecurePort used for closing secure connection
+- doxm and pstat properties reset after failed ownership transfer
+
+Patch #1: initial upload
+Patch #2: Fix
+
+Change-Id: Ia846397f68dc75883476015c4ad852d6213869f9
+Signed-off-by: Jongmin Choi <jminl.choi@samsung.com>
+Modifications:  
+  MODIFY  resource/csdk/security/provisioning/src/ownershiptransfermanager.c  d1fff9be0f8fd9d5d26e93df468473b7ccfe3eac:8f0063c09f3a3695b55a7ac46d2c9e2dbc2bb7bc null
+--------------------------------------------------------------------------------
+Revision:       29bff3da13b3d2446c8aacb56188f22aa1ee6033
+User:           Jongmin Choi
+Date:           Tue Jan 10 11:47:56 KST 2017
+Comment:        
+Switch to non-confirmable message for Confirm cases
+
+PostOwnerUuid message switched to non-confirmable for Confirm use cases
+This is a workaround solution and will be removed later
+
+Patch #1: initial upload
+
+Change-Id: Iec0debefeac672a48d4db4f36de195ec543d8c7c
+Signed-off-by: Jongmin Choi <jminl.choi@samsung.com>
+Modifications:  
+  MODIFY  resource/csdk/security/provisioning/src/ownershiptransfermanager.c  29bff3da13b3d2446c8aacb56188f22aa1ee6033:0f7bd146b0d012c8fad4152822a3bd0455d784a6 null
+--------------------------------------------------------------------------------
+Revision:       8f0063c09f3a3695b55a7ac46d2c9e2dbc2bb7bc
+User:           Chul Lee
+Date:           Tue Jan 10 11:37:43 KST 2017
+Comment:        
+Fix security build error for iOS
+
+Change-Id: I6359020b8bb10cc637d28db7de0866389de6d789
+Signed-off-by: Chul Lee <chuls.lee@samsung.com>
+Modifications:  
+  MODIFY  resource/csdk/security/src/srmutility.c 8f0063c09f3a3695b55a7ac46d2c9e2dbc2bb7bc:a0ec83004b3e26e7305e109b65761f4575a2a7a6 null
+--------------------------------------------------------------------------------
+Revision:       a0ec83004b3e26e7305e109b65761f4575a2a7a6
+User:           chuls lee
+Date:           Tue Jan 10 11:21:57 KST 2017
+Comment:        
+Merge "SVR DB Editor" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       0f7bd146b0d012c8fad4152822a3bd0455d784a6
+User:           h_w park
+Date:           Tue Jan 10 10:55:03 KST 2017
+Comment:        
+Merge "[CONPRO-487] Fix a logic to parse TC status property" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       02f9d8d7c38552dd70144383754e0257aa94a24f
+User:           Chul Lee
+Date:           Tue Jan 10 10:51:12 KST 2017
+Comment:        
+Fix unittest error for doxm resource
+
+Change-Id: I748c5aba0030927adca46b7c0731db83ff224074
+Signed-off-by: Chul Lee <chuls.lee@samsung.com>
+Modifications:  
+  MODIFY  resource/csdk/security/unittest/doxmresource.cpp  02f9d8d7c38552dd70144383754e0257aa94a24f:fbaad728969929e6c15e67d09e3ca98d9b5eb5b7 null
+--------------------------------------------------------------------------------
+Revision:       f19a97329292ccaf2b49a174bb3e515dd2193607
+User:           Chul Lee
+Date:           Tue Jan 10 10:44:40 KST 2017
+Comment:        
+SVR DB Editor
+
+This tool provides following features :
+ [Doxm]
+  - Print Doxm data
+  - Modify Doxm data (T.B.D)
+
+ [Pstat]
+  - Print Pstat data
+  - Modify Pstat data (T.B.D)
+
+ [ACL]
+  - Print ACL/ACE data (T.B.D)
+  - Modify ACL/ACE data (T.B.D)
+  - Insert ACE to ACL (T.B.D)
+  - Remove ACE from ACL (T.B.D)
+
+ [Credential]
+  - Print Credential data (Not fully supported yet)
+  - Modify Credential data (T.B.D)
+  - Insert credential to credential list (not fully supported yet)
+  - Remove credential from credential list
+
+ [Generate default SVR DB]
+  - T.B.D
+
+Patch #1 : Initial upload
+  - Print DOXM, PSTAT, CRED
+  - Insert CRED
+  - Remove CRED
+Patch #2 : Bug fix for add credential
+Patch #3 : Update print ACL/ACE
+Patch #4 : Bug fix for parse PEM cert.
+
+Change-Id: I9bd09006601b08f2f88789aabc2a0c2a661b7e51
+Signed-off-by: Chul Lee <chuls.lee@samsung.com>
+Modifications:  
+  MODIFY  resource/csdk/security/tool/SConscript  f19a97329292ccaf2b49a174bb3e515dd2193607:fbaad728969929e6c15e67d09e3ca98d9b5eb5b7 null
+  ADD resource/csdk/security/tool/svrdbeditor.c f19a97329292ccaf2b49a174bb3e515dd2193607:fbaad728969929e6c15e67d09e3ca98d9b5eb5b7 null
+--------------------------------------------------------------------------------
+Revision:       fbaad728969929e6c15e67d09e3ca98d9b5eb5b7
+User:           Jihun Ha
+Date:           Tue Jan 10 10:36:17 KST 2017
+Comment:        
+Merge "Update for Multi Ownership Transfer condition" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       4822ce8494040552372056e70ff0260cf45d83a9
+User:           jaehong jo
+Date:           Tue Jan 10 00:01:43 KST 2017
+Comment:        
+Merge "Replace u_array_list data structure with linked-list for keepalive" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       1c01cdcaeffd4c1181faadf1e0190eb2e5382d6d
+User:           hyuna0213.jo
+Date:           Mon Jan 09 23:24:51 KST 2017
+Comment:        
+Replace u_array_list data structure with linked-list for keepalive
+
+Change-Id: I0dfdba58fcae0e2201cd4841dccc3a0c0bf672e1
+Signed-off-by: hyuna0213.jo <hyuna0213.jo@samsung.com>
+Modifications:  
+  MODIFY  resource/csdk/stack/src/oickeepalive.c  1c01cdcaeffd4c1181faadf1e0190eb2e5382d6d:dae92ce0d732e267686e58c52a34892bb91dcecd null
+--------------------------------------------------------------------------------
+Revision:       fa3b737b7d339b4ccc2196314d8c9d7aa6b93ffa
+User:           hyuna0213 jo
+Date:           Mon Jan 09 22:54:18 KST 2017
+Comment:        
+Merge "Enable TCP, CLOUD, SECURED in Tizen" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       8ac0d5f1779e99f0098297b5c6d2937d68863438
+User:           Jaehong Jo
+Date:           Mon Jan 09 22:53:36 KST 2017
+Comment:        
+Enable TCP, CLOUD, SECURED in Tizen
+
+Change-Id: Ife74fc4e26777a3c812f5d0784b4ba82c6293aa0
+Signed-off-by: Jaehong Jo <jaehong.jo@samsung.com>
+Modifications:  
+  MODIFY  gbsbuild.sh 8ac0d5f1779e99f0098297b5c6d2937d68863438:0bc6c452599446a6bd417002816793a41589f0b9 null
+--------------------------------------------------------------------------------
+Revision:       dae92ce0d732e267686e58c52a34892bb91dcecd
+User:           js126 lee
+Date:           Mon Jan 09 22:35:20 KST 2017
+Comment:        
+Merge "Update PDM" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       c5a3654db1fe6c74318ff391744001b38d171607
+User:           js126 lee
+Date:           Mon Jan 09 22:35:09 KST 2017
+Comment:        
+Merge "Add API to set a seed value of device UUID." into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       54f1bd3d772c64e6aba30945d152f08d159dffad
+User:           chuls lee
+Date:           Mon Jan 09 22:30:30 KST 2017
+Comment:        
+Merge "Fix SetupCipher()" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       162ea1a58caad9cf72a38fce08c9df661dc3bb84
+User:           chuls lee
+Date:           Mon Jan 09 22:28:47 KST 2017
+Comment:        
+Merge "Fix ownership transfer issues" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       060511f45890c920b6bd945688afa0289efe471b
+User:           jihwan.seo
+Date:           Mon Jan 09 22:07:46 KST 2017
+Comment:        
+update debugging log related coap pdu
+
+Change-Id: Ic6625983e3272798b801a14e5acc9b1c7fddd6e1
+Signed-off-by: jihwan.seo <jihwan.seo@samsung.com>
+Modifications:  
+  MODIFY  resource/csdk/connectivity/src/camessagehandler.c 060511f45890c920b6bd945688afa0289efe471b:0bc6c452599446a6bd417002816793a41589f0b9 null
+--------------------------------------------------------------------------------
+Revision:       0bc6c452599446a6bd417002816793a41589f0b9
+User:           byonggon chun
+Date:           Mon Jan 09 21:58:59 KST 2017
+Comment:        
+Merge "Add Android sample to enable application layer keepalive mechanism." into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       3edfe2b2ece8d841d1cdf275d72bc9ec57fcc04c
+User:           Chul Lee
+Date:           Mon Jan 09 21:58:16 KST 2017
+Comment:        
+Add API to set a seed value of device UUID.
+
+After cloud related features updated,
+We faced issues with device UUID not fixed for each things.
+BTW, almost devices has a they own device unique value such as MAC address or machine ID.
+So we can use these value as seed value of UUID generation.
+
+Change-Id: I6ce668866b5881386a52ef8cb9de5226b8595749
+Signed-off-by: Chul Lee <chuls.lee@samsung.com>
+Modifications:  
+  MODIFY  resource/csdk/octbstack_product_secured.def 3edfe2b2ece8d841d1cdf275d72bc9ec57fcc04c:0d90ddeecc628e77d6b690d9217562ccc4b5ead3 null
+  MODIFY  resource/csdk/security/include/internal/doxmresource.h  3edfe2b2ece8d841d1cdf275d72bc9ec57fcc04c:0d90ddeecc628e77d6b690d9217562ccc4b5ead3 null
+  MODIFY  resource/csdk/security/include/srmutility.h 3edfe2b2ece8d841d1cdf275d72bc9ec57fcc04c:0d90ddeecc628e77d6b690d9217562ccc4b5ead3 null
+  MODIFY  resource/csdk/security/src/doxmresource.c 3edfe2b2ece8d841d1cdf275d72bc9ec57fcc04c:0d90ddeecc628e77d6b690d9217562ccc4b5ead3 null
+  MODIFY  resource/csdk/security/src/srmutility.c 3edfe2b2ece8d841d1cdf275d72bc9ec57fcc04c:0d90ddeecc628e77d6b690d9217562ccc4b5ead3 null
+  MODIFY  resource/csdk/security/unittest/srmutility.cpp  3edfe2b2ece8d841d1cdf275d72bc9ec57fcc04c:0d90ddeecc628e77d6b690d9217562ccc4b5ead3 null
+--------------------------------------------------------------------------------
+Revision:       94c550b081ab055210baa95fb671a3090c047a39
+User:           jaehong jo
+Date:           Mon Jan 09 21:58:07 KST 2017
+Comment:        
+Merge "Add C++ public api to expose keepalive api for App" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       1e8f7ebe6b306ef83b2f88a21c42955c0e79c781
+User:           jaehong jo
+Date:           Mon Jan 09 21:58:02 KST 2017
+Comment:        
+Merge "Added public API to enable application layer keepalive mechanism" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       b2cc02062fb563fb681ef2b612ca12a5f276eb07
+User:           Jongmin Choi
+Date:           Mon Jan 09 21:43:05 KST 2017
+Comment:        
+Fix ownership transfer issues
+
+Fix issues related to ownership transfer
+- Port change after failed ownership transfer
+
+Patch #1: initial upload
+Patch #2: Wrong Pin Max Attempt changed
+
+Change-Id: I2f2326a242f40b78453711f9d032b81eabac7e39
+Signed-off-by: Jongmin Choi <jminl.choi@samsung.com>
+Modifications:  
+  MODIFY  resource/csdk/connectivity/src/adapter_util/ca_adapter_net_ssl.c  b2cc02062fb563fb681ef2b612ca12a5f276eb07:0d90ddeecc628e77d6b690d9217562ccc4b5ead3 null
+  MODIFY  resource/csdk/security/provisioning/include/internal/ownershiptransfermanager.h b2cc02062fb563fb681ef2b612ca12a5f276eb07:0d90ddeecc628e77d6b690d9217562ccc4b5ead3 null
+  MODIFY  resource/csdk/security/provisioning/src/ownershiptransfermanager.c  b2cc02062fb563fb681ef2b612ca12a5f276eb07:0d90ddeecc628e77d6b690d9217562ccc4b5ead3 null
+--------------------------------------------------------------------------------
+Revision:       0d90ddeecc628e77d6b690d9217562ccc4b5ead3
+User:           hyuna0213 jo
+Date:           Mon Jan 09 21:28:30 KST 2017
+Comment:        
+Merge "fix crash issue related token copy" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       367d83b3e0ea3ff2a2b1aa88f6391fa5094243c9
+User:           Chul Lee
+Date:           Mon Jan 09 19:27:49 KST 2017
+Comment:        
+Temporarily disable failed TLSAdapter's unit tests.
+
+Change-Id: Ib8dd9d40684db9e0f68c4c82914b3c2f9b972656
+Signed-off-by: Chul Lee <chuls.lee@samsung.com>
+Modifications:  
+  MODIFY  resource/csdk/connectivity/test/ssladapter_test.cpp 367d83b3e0ea3ff2a2b1aa88f6391fa5094243c9:88f7cd936ab2e7753ef654558ee45e93809dc151 null
+--------------------------------------------------------------------------------
+Revision:       88f7cd936ab2e7753ef654558ee45e93809dc151
+User:           chuls lee
+Date:           Mon Jan 09 19:25:41 KST 2017
+Comment:        
+Merge "Revert "Temporarily disable failed TLSAdapter's unit tests."" into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       2b66bc52a7e87fae10aff32635c37f69fe8191b7
+User:           chuls lee
+Date:           Mon Jan 09 19:25:33 KST 2017
+Comment:        
+Revert "Temporarily disable failed TLSAdapter's unit tests."
+
+This reverts commit 1db88e2edaa2adb649e3bb351525da0d098a26d7.
+
+Change-Id: I48545c454455ce2e09aee6bda285e13309826a2c
+Modifications:  
+  MODIFY  resource/csdk/connectivity/test/ssladapter_test.cpp 2b66bc52a7e87fae10aff32635c37f69fe8191b7:1db88e2edaa2adb649e3bb351525da0d098a26d7 null
+--------------------------------------------------------------------------------
+Revision:       d15d3fecc696c855838e71d80c97825f60ed84d0
+User:           Jihun Ha
+Date:           Mon Jan 09 18:24:59 KST 2017
+Comment:        
+Merge "[CONPRO-487] Fix a logic to handle collection resource payload construction for vendor-specific properties in easy setup." into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       1e409f6f8f5e9fff6c359e5e21e567f0156dc95b
+User:           chuls lee
+Date:           Mon Jan 09 18:11:24 KST 2017
+Comment:        
+Merge "Temporarily disable failed TLSAdapter's unit tests." into 1.2-rel
+Modifications:  
+--------------------------------------------------------------------------------
+Revision:       1db88e2edaa2adb649e3bb351525da0d098a26d7
+User:           Chul Lee
+Date:           Mon Jan 09 18:06:25 KST 2017
+Comment:        
+Temporarily disable failed TLSAdapter's unit tests.
+
+Change-Id: I8d1e07112b7ab5bce88a94213d2a43b3d32f106f
+Signed-off-by: Chul Lee <chuls.lee@samsung.com>
+Modifications:  
+  MODIFY  resource/csdk/connectivity/test/ssladapter_test.cpp 1db88e2edaa2adb649e3bb351525da0d098a26d7:82fecb62dfd44d4b261502edf0b28264c34201a0 null
+--------------------------------------------------------------------------------
+Revision:       5f9e641e18162cfd4da6719fabf06b8355c530cc
+User:           jihwan.seo
+Date:           Mon Jan 09 17:48:57 KST 2017
+Comment:        
+fix crash issue related token copy
+
+Change-Id: I30d5a08bca32a4e7751ee389256ae6d4bfb6a0f3
+Signed-off-by: jihwan.seo <jihwan.seo@samsung.com>
+Modifications:  
+  MODIFY  resource/csdk/connectivity/src/caprotocolmessage.c  5f9e641e18162cfd4da6719fabf06b8355c530cc:dc1f37ac0b54dade9f8bc1b5c9fe345729b8a4e4 null
+  MODIFY  resource/csdk/connectivity/src/ip_adapter/caipserver.c  5f9e641e18162cfd4da6719fabf06b8355c530cc:dc1f37ac0b54dade9f8bc1b5c9fe345729b8a4e4 null
+--------------------------------------------------------------------------------
+Revision:       82da1a402856e24ed2bc351e8d68d77c691a0586
+User:           Jihun Ha
+Date:           Mon Jan 09 17:42:04 KST 2017
+Comment:        
+[CONPRO-487] Fix a logic to parse TC status property
+
+TC status is a property in provisioning resource so it can be retrieved
+in a root representation, not child one.
+
+Change-Id: I79b11234ac48f204f7823b638ffa3d6e573fddf1
+Signed-off-by: Jihun Ha <jihun.ha@samsung.com>
+Modifications:  
+  MODIFY  service/easy-setup/mediator/richsdk/inc/ESSCCommon.h  82da1a402856e24ed2bc351e8d68d77c691a0586:dc1f37ac0b54dade9f8bc1b5c9fe345729b8a4e4 null
+--------------------------------------------------------------------------------
+Revision:       9362b0dbeabc0ee8470163e9249fbd2bfefe25aa
+User:           bg.chun
+Date:           Mon Jan 09 15:58:41 KST 2017
+Comment:        
+Add public Java api to expose keepalive api for App
+
+Change-Id: Iaaf28d8cd2b5e4045bbdbbf582b8fcb174082d4a
+Signed-off-by: bg.chun <bg.chun@samsung.com>
+Modifications:  
+  MODIFY  android/android_api/base/jni/Android.mk 9362b0dbeabc0ee8470163e9249fbd2bfefe25aa:94c550b081ab055210baa95fb671a3090c047a39 null
+  MODIFY  android/android_api/base/jni/JniOcPlatform.cpp  9362b0dbeabc0ee8470163e9249fbd2bfefe25aa:94c550b081ab055210baa95fb671a3090c047a39 null
+  MODIFY  android/android_api/base/jni/JniOcPlatform.h  9362b0dbeabc0ee8470163e9249fbd2bfefe25aa:94c550b081ab055210baa95fb671a3090c047a39 null
+  ADD android/android_api/base/jni/JniPingListener.cpp  9362b0dbeabc0ee8470163e9249fbd2bfefe25aa:94c550b081ab055210baa95fb671a3090c047a39 null
+  ADD android/android_api/base/jni/JniPingListener.h  9362b0dbeabc0ee8470163e9249fbd2bfefe25aa:94c550b081ab055210baa95fb671a3090c047a39 null
+  MODIFY  android/android_api/base/src/main/java/org/iotivity/base/OcPlatform.java  9362b0dbeabc0ee8470163e9249fbd2bfefe25aa:94c550b081ab055210baa95fb671a3090c047a39 null
+--------------------------------------------------------------------------------
+Revision:       80bd3b8f0d3a99fec4a18a383c6fb0fbc9a57868
+User:           Jihun Ha
+Date:           Mon Jan 09 15:50:50 KST 2017
+Comment:        
+[CONPRO-487] Fix a logic to handle collection resource payload construction
+for vendor-specific properties in easy setup.
+
+For vendor-specific properties in provisioning resource, they should be
+included in 'rep' property.
+
+Change-Id: I3bbbe18696777ab21b3d813115ceace8ab84f7d8
+Signed-off-by: Jihun Ha <jihun.ha@samsung.com>
+Modifications:  
+  MODIFY  service/easy-setup/enrollee/src/resourcehandler.c 80bd3b8f0d3a99fec4a18a383c6fb0fbc9a57868:891c5af03e821cb1f0aebf726a855d13dac17938 null
+--------------------------------------------------------------------------------
+Revision:       da0c8f9fede11062c68efb2fc656a88cf61b257c
+User:           Jongmin Choi
+Date:           Mon Jan 09 14:04:56 KST 2017
+Comment:        
+Fix SetupCipher()
+
+Fix SetupCipher() to avoid duplicate ciphersuites
+
+Patch #1: Initial upload
+Patch #2: Logs added
+Patch #3-4: Server ciphersuite selection added
+Patch #5: Logs modified
+
+Change-Id: I3a4aefd2a739523caa88e3a609ad26c9d1986dad
+Signed-off-by: Jongmin Choi <jminl.choi@samsung.com>
+Modifications:  
+  MODIFY  resource/csdk/connectivity/src/adapter_util/ca_adapter_net_ssl.c  da0c8f9fede11062c68efb2fc656a88cf61b257c:dc1f37ac0b54dade9f8bc1b5c9fe345729b8a4e4 null
+  MODIFY  resource/csdk/security/src/credresource.c da0c8f9fede11062c68efb2fc656a88cf61b257c:dc1f37ac0b54dade9f8bc1b5c9fe345729b8a4e4 null
+--------------------------------------------------------------------------------
+Revision:       44b9ac78503bf0ef123dcedddc0aa0eb641cf6cb
+User:           Chul Lee
+Date:           Mon Jan 09 14:00:06 KST 2017
+Comment:        
+Update PDM
+
+This patch addresses the following exceptional cases :
+ 1. The PT terminates unexpectedly.
+    - Start the OTM process
+    - Device information will be changed to INIT state.
+    - PT terminated while OTM.
+    - Restart the PT process.
+    - Retry the OTM process.
+    * OTM start will be failed due to device info already save as INIT state.
+
+  2. Timeout is occured PT side while OTM.
+    - Start the OTM process
+    - Device information will be changed to INIT state.
+    - OTM timeout is occured at the application side.
+    - PT retry the OTM.
+    * OTM start will be failed due to device info already save as INIT state.
+
+I've added defence code and
+added cleanup API that can be used when timeout occurs.
+
+Patch #1 : Initial upload
+Patch #2 : Retrigger
+Patch #3 : Fix the bug for incorrect PIN inputed while random PIN OxM.
+Patch #4-5 : Retrigger
+Patch #6 : minor bug fix
+
+Change-Id: I7781c0d864db6fdac93fa41acbcbf1ac123d15da
+Signed-off-by: Chul Lee <chuls.lee@samsung.com>
+Modifications:  
+  MODIFY  resource/csdk/octbstack_product_secured.def 44b9ac78503bf0ef123dcedddc0aa0eb641cf6cb:dc1f37ac0b54dade9f8bc1b5c9fe345729b8a4e4 null
+  MODIFY  resource/csdk/security/provisioning/include/internal/provisioningdatabasemanager.h  44b9ac78503bf0ef123dcedddc0aa0eb641cf6cb:dc1f37ac0b54dade9f8bc1b5c9fe345729b8a4e4 null
+  MODIFY  resource/csdk/security/provisioning/include/ocprovisioningmanager.h 44b9ac78503bf0ef123dcedddc0aa0eb641cf6cb:dc1f37ac0b54dade9f8bc1b5c9fe345729b8a4e4 null
+  MODIFY  resource/csdk/security/provisioning/sample/provisioningclient.c 44b9ac78503bf0ef123dcedddc0aa0eb641cf6cb:dc1f37ac0b54dade9f8bc1b5c9fe345729b8a4e4 null
+  MODIFY  resource/csdk/security/provisioning/sample/subownerclient.c 44b9ac78503bf0ef123dcedddc0aa0eb641cf6cb:dc1f37ac0b54dade9f8bc1b5c9fe345729b8a4e4 null
+  MODIFY  resource/csdk/security/provisioning/src/ocprovisioningmanager.c 44b9ac78503bf0ef123dcedddc0aa0eb641cf6cb:dc1f37ac0b54dade9f8bc1b5c9fe345729b8a4e4 null
+  MODIFY  resource/csdk/security/provisioning/src/ownershiptransfermanager.c  44b9ac78503bf0ef123dcedddc0aa0eb641cf6cb:dc1f37ac0b54dade9f8bc1b5c9fe345729b8a4e4 null
+  MODIFY  resource/csdk/security/provisioning/src/provisioningdatabasemanager.c 44b9ac78503bf0ef123dcedddc0aa0eb641cf6cb:dc1f37ac0b54dade9f8bc1b5c9fe345729b8a4e4 null
+  MODIFY  resource/include/OCProvisioningManager.hpp  44b9ac78503bf0ef123dcedddc0aa0eb641cf6cb:dc1f37ac0b54dade9f8bc1b5c9fe345729b8a4e4 null
+  MODIFY  resource/provisioning/src/OCProvisioningManager.cpp 44b9ac78503bf0ef123dcedddc0aa0eb641cf6cb:dc1f37ac0b54dade9f8bc1b5c9fe345729b8a4e4 null
+--------------------------------------------------------------------------------
+Revision:       719d85e16af22b4f459e96e363e1e9a3bf696d75
+User:           Jaehong Jo
+Date:           Mon Jan 09 10:49:25 KST 2017
+Comment:        
+Add Android sample to enable application layer keepalive mechanism.
+
+C API : http://suprem.sec.samsung.net/gerrit/#/c/106295/
+C++, JNI : http://suprem.sec.samsung.net/gerrit/#/c/106297/
+
+Change-Id: I2a1ae66d90c013727581a9a7e8569ff2f36d2e63
+Signed-off-by: Jaehong Jo <jaehong.jo@samsung.com>
+Modifications:  
+  MODIFY  android/examples/simplebase/src/main/AndroidManifest.xml  719d85e16af22b4f459e96e363e1e9a3bf696d75:3d2bee77cf604c3aa82d99367f50ee1ee1c7b7e3 null
+  MODIFY  android/examples/simplebase/src/main/java/org/iotivity/base/examples/DrawerFragment.java  719d85e16af22b4f459e96e363e1e9a3bf696d75:3d2bee77cf604c3aa82d99367f50ee1ee1c7b7e3 null
+  ADD android/examples/simplebase/src/main/java/org/iotivity/base/examples/PingFragment.java  719d85e16af22b4f459e96e363e1e9a3bf696d75:3d2bee77cf604c3aa82d99367f50ee1ee1c7b7e3 null
+  MODIFY  android/examples/simplebase/src/main/java/org/iotivity/base/examples/SimpleBase.java  719d85e16af22b4f459e96e363e1e9a3bf696d75:3d2bee77cf604c3aa82d99367f50ee1ee1c7b7e3 null
+  ADD android/examples/simplebase/src/main/res/layout/fragment_ping.xml 719d85e16af22b4f459e96e363e1e9a3bf696d75:3d2bee77cf604c3aa82d99367f50ee1ee1c7b7e3 null
+  MODIFY  android/examples/simplebase/src/main/res/values/strings.xml 719d85e16af22b4f459e96e363e1e9a3bf696d75:3d2bee77cf604c3aa82d99367f50ee1ee1c7b7e3 null
+--------------------------------------------------------------------------------
+Revision:       0e65992484d7480be7e246da995ed45044fb6070
+User:           bg.chun
+Date:           Sat Jan 07 16:33:59 KST 2017
+Comment:        
+Add C++ public api to expose keepalive api for App
+
+Change-Id: I3b1e6fb908de94437d140091069ba45210f1ab56
+Signed-off-by: bg.chun <bg.chun@samsung.com>
+Modifications:  
+  MODIFY  resource/include/IClientWrapper.h 0e65992484d7480be7e246da995ed45044fb6070:3b47e8e329a464e892e626d724856f29a0bf6a96 null
+  MODIFY  resource/include/InProcClientWrapper.h  0e65992484d7480be7e246da995ed45044fb6070:3b47e8e329a464e892e626d724856f29a0bf6a96 null
+  MODIFY  resource/include/OCApi.h  0e65992484d7480be7e246da995ed45044fb6070:3b47e8e329a464e892e626d724856f29a0bf6a96 null
+  MODIFY  resource/include/OCPlatform.h 0e65992484d7480be7e246da995ed45044fb6070:3b47e8e329a464e892e626d724856f29a0bf6a96 null
+  MODIFY  resource/include/OCPlatform_impl.h  0e65992484d7480be7e246da995ed45044fb6070:3b47e8e329a464e892e626d724856f29a0bf6a96 null
+  MODIFY  resource/include/OutOfProcClientWrapper.h 0e65992484d7480be7e246da995ed45044fb6070:3b47e8e329a464e892e626d724856f29a0bf6a96 null
+  MODIFY  resource/src/InProcClientWrapper.cpp  0e65992484d7480be7e246da995ed45044fb6070:3b47e8e329a464e892e626d724856f29a0bf6a96 null
+  MODIFY  resource/src/OCPlatform.cpp 0e65992484d7480be7e246da995ed45044fb6070:3b47e8e329a464e892e626d724856f29a0bf6a96 null
+  MODIFY  resource/src/OCPlatform_impl.cpp  0e65992484d7480be7e246da995ed45044fb6070:3b47e8e329a464e892e626d724856f29a0bf6a96 null
+--------------------------------------------------------------------------------
+Revision:       3b47e8e329a464e892e626d724856f29a0bf6a96
+User:           hyuna0213.jo
+Date:           Sat Jan 07 16:32:59 KST 2017
+Comment:        
+Added public API to enable application layer keepalive mechanism
+
+Change-Id: Ice7da518ab406825a1330e450ab73d7fafad2ab2
+Signed-off-by: hyuna0213.jo <hyuna0213.jo@samsung.com>
+Modifications:  
+  MODIFY  resource/csdk/SConscript  3b47e8e329a464e892e626d724856f29a0bf6a96:d4611ef24f131302fa08fe8a55ee6199a78d9bc9 null
+  MODIFY  resource/csdk/stack/include/internal/ocstackinternal.h  3b47e8e329a464e892e626d724856f29a0bf6a96:d4611ef24f131302fa08fe8a55ee6199a78d9bc9 null
+  DELETE  resource/csdk/stack/include/internal/oickeepalive.h 3b47e8e329a464e892e626d724856f29a0bf6a96:d4611ef24f131302fa08fe8a55ee6199a78d9bc9 null
+  ADD resource/csdk/stack/include/internal/oickeepaliveinternal.h 3b47e8e329a464e892e626d724856f29a0bf6a96:d4611ef24f131302fa08fe8a55ee6199a78d9bc9 null
+  ADD resource/csdk/stack/include/oickeepalive.h  3b47e8e329a464e892e626d724856f29a0bf6a96:d4611ef24f131302fa08fe8a55ee6199a78d9bc9 null
+  MODIFY  resource/csdk/stack/src/ocresource.c  3b47e8e329a464e892e626d724856f29a0bf6a96:d4611ef24f131302fa08fe8a55ee6199a78d9bc9 null
+  MODIFY  resource/csdk/stack/src/ocstack.c 3b47e8e329a464e892e626d724856f29a0bf6a96:d4611ef24f131302fa08fe8a55ee6199a78d9bc9 null
+  MODIFY  resource/csdk/stack/src/oickeepalive.c  3b47e8e329a464e892e626d724856f29a0bf6a96:d4611ef24f131302fa08fe8a55ee6199a78d9bc9 null
+--------------------------------------------------------------------------------
+Revision:       ae5e9187e6b2abfab08c6284be56b9004fb57b7a
+User:           Jihun Ha
+Date:           Sat Jan 07 13:09:08 KST 2017
+Comment:        
+Update for Multi Ownership Transfer condition
+
+The found enrollee's owner ID indicates a same ID of mediator.
+However, a list of owned devices managed in mediator's PMD db has
+no element for the found enrollee. In that case, MOT will be failed.
+
+For this, ES_OWNERSHIP_IS_NOT_SYNCHRONIZED value is returned, which
+guides a user to reset a Enrollee's SVR DB file.
+
+Change-Id: Ia5feaccccfc4cca4a0673d08cbba4d473324e37f
+Signed-off-by: Parkhi <h_w.park@samsung.com>
+Signed-off-by: Jihun Ha <jihun.ha@samsung.com>
+Modifications:  
+  MODIFY  service/easy-setup/inc/escommon.h ae5e9187e6b2abfab08c6284be56b9004fb57b7a:3d2bee77cf604c3aa82d99367f50ee1ee1c7b7e3 null
+  MODIFY  service/easy-setup/mediator/richsdk/src/EnrolleeSecurity.cpp  ae5e9187e6b2abfab08c6284be56b9004fb57b7a:3d2bee77cf604c3aa82d99367f50ee1ee1c7b7e3 null
+--------------------------------------------------------------------------------
+Revision:       8ab1077b3f1a58fac06850cd5703cbc8f118637f
+User:           Jongmin Choi
+Date:           Fri Jan 06 15:43:35 KST 2017
+Comment:        
+Logs added for confirmation callbacks
+
+Logs added for confirmation callbacks
+
+Patch #1: initial upload
+Patch #2: Additional logs added
+
+Change-Id: I0b42eeaccb21c9b11d1c8effecd8797ee80c2929
+Signed-off-by: Jongmin Choi <jminl.choi@samsung.com>
+Modifications:  
+  MODIFY  resource/csdk/security/provisioning/src/ownershiptransfermanager.c  8ab1077b3f1a58fac06850cd5703cbc8f118637f:dc1f37ac0b54dade9f8bc1b5c9fe345729b8a4e4 null
+  MODIFY  resource/csdk/security/src/oxmverifycommon.c  8ab1077b3f1a58fac06850cd5703cbc8f118637f:dc1f37ac0b54dade9f8bc1b5c9fe345729b8a4e4 null
index 249730d..80b72ae 100644 (file)
@@ -29,10 +29,13 @@ target_os = env.get('TARGET_OS')
 src_dir = env.get('SRC_DIR')
 rd_mode = env.get('RD_MODE')
 
+if target_os == 'tizenrt' and not env.get('RELEASE'):
+       env.AppendUnique(CCFLAGS = ['-g'])
+
 # Build liblogger
 SConscript('csdk/logger/SConscript')
 
-if target_os not in ['arduino', 'darwin', 'ios', 'android', 'msys_nt', 'windows']:
+if target_os not in ['arduino', 'darwin', 'ios', 'android', 'msys_nt', 'windows', 'tizenrt']:
        env.AppendUnique(LIBS=['rt'])
 
 # Download (if not already present) & build libcoap
@@ -57,16 +60,16 @@ SConscript('csdk/security/SConscript')
 # Build liboctbstack
 SConscript('csdk/SConscript')
 
-if target_os not in ['arduino','darwin']:
+if target_os not in ['arduino','darwin', 'tizenrt']:
        # Build liboc_logger
        SConscript('oc_logger/SConscript')
 
        # Build liboc
        SConscript('src/SConscript')
 
-if target_os not in ['arduino','darwin','ios','android']:
+#if target_os not in ['arduino','darwin','ios','android', 'tizenrt']:
        # Build examples
-       SConscript('examples/SConscript')
+#      SConscript('examples/SConscript')
 
 if target_os in ['linux', 'windows']:
        # Build C Samples
index 8facaa1..0a9ff8e 100644 (file)
@@ -89,6 +89,12 @@ if target_os == 'arduino':
        # Detection of headers on the Arduino platform is currently broken.
        cxx_headers = []
 
+if target_os in ['tizenrt']:
+       env.AppendUnique(CCFLAGS = ['-std=c99'])
+       env.AppendUnique(CCFLAGS = ['-w'])
+       cxx_headers.remove('sys/timeb.h')
+       config_h_body += "#include <tinyara/config.h>\n\n"
+
 if target_os == 'msys_nt':
        # WinPThread provides a pthread.h, but we want to use native threads.
        cxx_headers.remove('pthread.h')
@@ -98,8 +104,12 @@ def get_define_from_header_file(header_file):
        return "HAVE_" + header_file_converted
 
 for header_file_name in cxx_headers:
-       if conf.CheckCXXHeader(header_file_name):
-               config_h_body += "#define %s 1\n\n" % get_define_from_header_file(header_file_name)
+       if target_os == 'tizenrt':
+               if conf.CheckCHeader(header_file_name):
+                       config_h_body += "#define %s 1\n\n" % get_define_from_header_file(header_file_name)
+       else:
+               if conf.CheckCXXHeader(header_file_name):
+                       config_h_body += "#define %s 1\n\n" % get_define_from_header_file(header_file_name)
 conf.Finish()
 
 # Autoconf feature doesn't work with Jenkins' arduino toolchain, so hardcode it here.
@@ -138,7 +148,8 @@ env.AppendUnique(CPPPATH = [
             os.path.join(Dir('.').abspath, 'oic_malloc', 'include'),
             os.path.join(Dir('.').abspath, 'oic_string', 'include'),
             os.path.join(Dir('.').abspath, 'oic_time', 'include'),
-            os.path.join(Dir('.').abspath, 'ocrandom', 'include')
+            os.path.join(Dir('.').abspath, 'ocrandom', 'include'),
+            os.path.join(Dir('.').abspath, 'octhread', 'include')
         ])
 
 if target_os == 'tizen':
@@ -158,8 +169,16 @@ common_src = [
        'oic_string/src/oic_string.c',
        'oic_malloc/src/oic_malloc.c',
        'oic_time/src/oic_time.c',
-       'ocrandom/src/ocrandom.c',
+       'ocrandom/src/ocrandom.c'
        ]
+
+if env['POSIX_SUPPORTED']:
+       common_src.append('octhread/src/posix/octhread.c')
+elif target_os  in ['windows']:
+       common_src.append('octhread/src/windows/octhread.c')
+else:
+       common_src.append('octhread/src/noop/octhread.c')
+
 commonlib = common_env.StaticLibrary('c_common', common_src)
 common_env.InstallTarget(commonlib, 'c_common')
 common_env.UserInstallTargetLib(commonlib, 'c_common')
index e53c594..e0dcdc5 100644 (file)
@@ -141,7 +141,7 @@ int8_t OCSeedRandom()
     gettimeofday(&tv, NULL);
     currentTime = tv.tv_sec * (uint64_t)1000000 + tv.tv_usec;
 #endif
-#if defined(__unix__) || defined(__APPLE__)
+#if defined(__unix__) || defined(__APPLE__) || defined(__TIZENRT__)
     int32_t fd = open("/dev/urandom", O_RDONLY);
     if (fd >= 0)
     {
@@ -333,7 +333,6 @@ OCRandomUuidResult OCGenerateUuidString(char uuidString[UUID_STRING_SIZE])
     }
     else
     {
-        close(fd);
         return RAND_UUID_READ_ERROR;
     }
 #elif defined(HAVE_UUID_UUID_H)
diff --git a/resource/c_common/octhread/include/octhread.h b/resource/c_common/octhread/include/octhread.h
new file mode 100644 (file)
index 0000000..95728d1
--- /dev/null
@@ -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 mutex and semaphores.
+ */
+
+#ifndef OC_THREAD_H_
+#define OC_THREAD_H_
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+typedef struct oc_mutex_internal *oc_mutex;
+typedef struct oc_cond_internal *oc_cond;
+typedef struct oc_thread_internal *oc_thread;
+
+/**
+ * Enums for oc_cond_wait_for return values.
+ */
+typedef enum
+{
+   OC_WAIT_SUCCESS = 0,    /**< Condition Signal. */
+   OC_WAIT_INVAL = -1,     /**< Invalid Condition. */
+   OC_WAIT_TIMEDOUT = -2   /**< Condition Timed Out. */
+} OCWaitResult_t;
+
+typedef enum
+{
+    OC_THREAD_SUCCESS = 0,
+    OC_THREAD_ALLOCATION_FAILURE = 1,
+    OC_THREAD_CREATE_FAILURE = 2,
+    OC_THREAD_INVALID = 3,
+    OC_THREAD_WAIT_FAILURE = 4,
+    OC_THREAD_INVALID_PARAMETER = 5,
+    OC_THREAD_CANCEL_FAILURE = 6
+} OCThreadResult_t;
+
+/**
+ * Allocates, and starts a new thread
+ *
+ * @param[out] t  The thread that will refer to a newly allocated, and started thread
+ * @param[in] start_routine The function that will execute in a new thread
+ * @param[in] arg The information passed to the start_routine
+ * @return OCThreadResult_t An enumeration of possible outcomes
+ * @retval OC_THREAD_SUCCESS If a thread was successfully allocated and started.
+ * @retval OC_THREAD_ALLOCATION_FAILURE If a thread was unable to be allocated
+ * @retval OC_THREAD_CREATE_FAILURE If a thread was unable to be started
+ *
+ */
+#ifndef __TIZENRT__
+OCThreadResult_t oc_thread_new(oc_thread *t, void *(*start_routine)(void *), void *arg);
+#else
+OCThreadResult_t oc_thread_new(oc_thread *t, void *(*start_routine)(void *), void *arg,
+                               const char *task_name, int stack_size);
+#endif
+
+/**
+ * Frees a thread previously allocated with oc_thread_new()
+ *
+ * @param[in] t The thread to be unallocated
+ * @return OCThreadResult_t An enumeration of possible outcomes
+ * @retval OC_THREAD_SUCCESS If a thread was successfully unallocated
+ * @retval OC_THREAD_INVALID_PARAMETER If param t is NULL
+ *
+ */
+OCThreadResult_t oc_thread_free(oc_thread t);
+
+/**
+ * Block until a thread's execution has been completed
+ *
+ * @param[in] t The thread to be waited on
+ * @return OCThreadResult_t An enumeration of possible outcomes
+ * @retval OC_THREAD_SUCCESS If the thread successfully completed execution
+ * @retval OC_THREAD_WAIT_FAILURE If a problem occured while waiting for execution of the thread to complete
+ *
+ */
+OCThreadResult_t oc_thread_wait(oc_thread t);
+
+#ifdef __TIZEN__
+/**
+ * Cancel the thread without block
+ *
+ * @param[in] t The thread to be canceled on
+ * @return OCThreadResult_t An enumeration of possible outcomes
+ * @retval OC_THREAD_SUCCESS If the thread successfully completed execution
+ * @retval OC_THREAD_CANCEL_FAILURE If a problem occured while canceling
+ *
+ */
+OCThreadResult_t oc_thread_cancel(oc_thread t);
+#endif
+
+/**
+ * Creates new mutex.
+ *
+ * @return  Reference to newly created mutex, otherwise NULL.
+ *
+ */
+oc_mutex oc_mutex_new(void);
+
+/**
+ * Lock the mutex.
+ *
+ * @param  mutex  The mutex to be locked.
+ *
+ */
+void oc_mutex_lock(oc_mutex mutex);
+
+/**
+ * Unlock the mutex.
+ *
+ * @param  mutex  The mutex to be unlocked.
+ *
+ */
+void oc_mutex_unlock(oc_mutex mutex);
+
+/**
+ * Free the mutex.
+ *
+ * @param  mutex  The mutex to be freed.
+ * @return bool to indicate success or failure
+ * @retval true if mutex was freed successfully
+ * @retval false if mutex parameter is invalid
+ *
+ */
+bool oc_mutex_free(oc_mutex mutex);
+
+/**
+ * Creates new condition.
+ *
+ * @return  Reference to newly created oc_cond, otherwise NULL.
+ *
+ */
+oc_cond oc_cond_new(void);
+
+/**
+ * One of threads is woken up if multiple threads are waiting for cond.
+ *
+ * @param  cond  The condtion to be signaled.
+ *
+ */
+void oc_cond_signal(oc_cond cond);
+
+/**
+ * All of threads are woken up if multiple threads are waiting for cond.
+ *
+ * @param  cond  The condtion to be signaled.
+ *
+ */
+void oc_cond_broadcast(oc_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 oc_cond_wait(oc_cond cond, oc_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, oc_cond_wait_for() acts like oc_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 OC_WAIT_SUCCESS if the condition was signaled,
+ *         OC_WAIT_TIMEDOUT if wait period exceeded,
+ *         OC_WAIT_INVAL for invalid parameters.
+ *
+ */
+OCWaitResult_t oc_cond_wait_for(oc_cond cond, oc_mutex mutex, uint64_t microseconds);
+
+/**
+ * Free the condition.
+ *
+ * @param  cond  The condition to be freed.
+ *
+ */
+void oc_cond_free(oc_cond cond);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* OC_THREAD_H_ */
@@ -26,8 +26,7 @@
  * This file provides APIs related to mutex with no operation
  * for Singlethread implementation.
  */
-
-#include "camutex.h"
+#include "octhread.h"
 
 /**
  * TAG
 
 typedef struct _tagMutexInfo_t
 {
-#if defined(_MSC_VER)
-    uint8_t unused; //VS doesnt like empty structs
-#endif
-} ca_mutex_internal;
+} oc_mutex_internal;
 
 typedef struct _tagEventInfo_t
 {
-#if defined(_MSC_VER)
-    uint8_t unused; //VS doesnt like empty structs
-#endif
-} ca_cond_internal;
+} oc_cond_internal;
+
+typedef struct _tagThreadInfo_t
+{
+} oc_thread_internal;
+
 
 /**
  * @var g_mutexInfo
- * @brief This is used to return a non NULL value for ca_mutex_new().
+ * @brief This is used to return a non NULL value for oc_mutex_new().
  */
-static ca_mutex_internal g_mutexInfo = { 0 };
+static oc_mutex_internal g_mutexInfo = { 0 };
 
 /**
  * @var g_condInfo
- * @brief This is used to return a non NULL value for ca_cond_new().
+ * @brief This is used to return a non NULL value for oc_cond_new().
  */
-static ca_cond_internal g_condInfo = { 0 };
+static oc_cond_internal g_condInfo = { 0 };
+
+OCThreadResult_t oc_thread_new(oc_thread *t, void *(*start_routine)(void *), void *arg)
+{
+    return OC_THREAD_CREATE_FAILURE;
+}
+
+OCThreadResult_t oc_thread_free(oc_thread t)
+{
+    return OC_THREAD_INVALID;
+}
+
+OCThreadResult_t oc_thread_wait(oc_thread t)
+{
+    return OC_THREAD_INVALID;
+}
 
-ca_mutex ca_mutex_new(void)
+oc_mutex oc_mutex_new(void)
 {
-    return (ca_mutex)&g_mutexInfo;
+    return (oc_mutex)&g_mutexInfo;
 }
 
-bool ca_mutex_free(ca_mutex mutex)
+bool oc_mutex_free(oc_mutex mutex)
 {
     return true;
 }
 
-void ca_mutex_lock(ca_mutex mutex)
+void oc_mutex_lock(oc_mutex mutex)
 {
     return;
 }
 
-void ca_mutex_unlock(ca_mutex mutex)
+void oc_mutex_unlock(oc_mutex mutex)
 {
     return;
 }
 
-ca_cond ca_cond_new(void)
+oc_cond oc_cond_new(void)
 {
-    return (ca_cond)&g_condInfo;
+    return (oc_cond)&g_condInfo;
 }
 
-void ca_cond_free(ca_cond cond)
+void oc_cond_free(oc_cond cond)
 {
     return;
 }
 
-void ca_cond_signal(ca_cond cond)
+void oc_cond_signal(oc_cond cond)
 {
     return;
 }
 
-void ca_cond_broadcast(ca_cond cond)
+void oc_cond_broadcast(oc_cond cond)
 {
     return;
 }
 
-void ca_cond_wait(ca_cond cond, ca_mutex mutex)
+void oc_cond_wait(oc_cond cond, oc_mutex mutex)
 {
     return;
 }
 
-CAWaitResult_t ca_cond_wait_for(ca_cond cond, ca_mutex mutex, uint64_t microseconds)
+OCWaitResult_t oc_cond_wait_for(oc_cond cond, oc_mutex mutex, uint64_t microseconds)
 {
-    return CA_WAIT_SUCCESS;
+    return OC_WAIT_SUCCESS;
 }
 
@@ -37,6 +37,7 @@
 #endif
 
 #include "iotivity_config.h"
+#include "octhread.h"
 #ifdef HAVE_STRING_H
 #include <string.h>
 #endif
 #ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
 #endif
-#ifdef HAVE_WINSOCK2_H
-#include <winsock2.h>
-#endif
 #include <stdio.h>
 #include <errno.h>
 #include <assert.h>
 #include <oic_malloc.h>
-#include "camutex.h"
 #include "logger.h"
 
 /**
@@ -90,45 +87,128 @@ static const uint64_t NANOSECS_PER_SEC      = 1000000000L;
 
 typedef struct _tagMutexInfo_t
 {
-#if defined(_WIN32)
-    CRITICAL_SECTION mutex;
-#else
     pthread_mutex_t mutex;
-#endif
-} ca_mutex_internal;
+} oc_mutex_internal;
 
 typedef struct _tagEventInfo_t
 {
-#if defined(_WIN32)
-    CONDITION_VARIABLE cond;
-#else
     pthread_cond_t cond;
     pthread_condattr_t condattr;
+} oc_cond_internal;
+
+typedef struct _tagThreadInfo_t
+{
+    pthread_t thread;
+    pthread_attr_t  threadattr;
+} oc_thread_internal;
+
+#ifndef __TIZENRT__
+OCThreadResult_t oc_thread_new(oc_thread *t, void *(*start_routine)(void *), void *arg)
+#else
+OCThreadResult_t oc_thread_new(oc_thread *t, void *(*start_routine)(void *), void *arg,
+                                   const char *task_name, int stack_size)
+#endif
+{
+    OCThreadResult_t res = OC_THREAD_SUCCESS;
+    oc_thread_internal *threadInfo = (oc_thread_internal*)OICMalloc(sizeof(oc_thread_internal));
+    if (NULL != threadInfo)
+    {
+#ifdef __TIZENRT__
+        pthread_attr_t attr;
+        pthread_attr_init(&attr);
+        struct sched_param prio;
+        prio.sched_priority = 90;
+        (void)pthread_attr_setschedparam(&attr, &prio);
+        (void)pthread_attr_setstacksize(&attr, stack_size);
+        int result = pthread_create(&threadInfo->thread, &attr, start_routine, arg);
+        pthread_setname_np(threadInfo->thread, task_name);
+#else
+        int result = pthread_create(&threadInfo->thread, NULL, start_routine, arg);
+#endif
+        if (result != 0)
+        {
+            res = OC_THREAD_CREATE_FAILURE;
+            *t = NULL;
+            OICFree(threadInfo);
+            OIC_LOG_V(ERROR, TAG, "%s: pthread_create failed", __func__);
+        }
+        else
+        {
+            *t = (oc_thread)threadInfo;
+        }
+    }
+    else
+    {
+        OIC_LOG_V(ERROR, TAG, "%s Failed to allocate thread!", __func__);
+        *t = NULL;
+        res = OC_THREAD_ALLOCATION_FAILURE;
+    }
+    return res;
+}
+
+OCThreadResult_t oc_thread_free(oc_thread t)
+{
+    OCThreadResult_t res = OC_THREAD_SUCCESS;
+    oc_thread_internal *threadInfo = (oc_thread_internal*) t;
+    if (threadInfo)
+    {
+        OICFree(threadInfo);
+    }
+    else
+    {
+        OIC_LOG_V(ERROR, TAG, "%s Invalid thread !", __func__);
+        res = OC_THREAD_INVALID;
+    }
+    return res;
+}
+
+OCThreadResult_t oc_thread_wait(oc_thread t)
+{
+    OCThreadResult_t res = OC_THREAD_SUCCESS;
+    oc_thread_internal *threadInfo = (oc_thread_internal*) t;
+    int joinres = pthread_join(threadInfo->thread, NULL);
+    if (0 != joinres)
+    {
+        OIC_LOG_V(ERROR, TAG, "Failed to join thread with error %d", joinres);
+        res = OC_THREAD_WAIT_FAILURE;
+    }
+
+    return res;
+}
+
+#ifdef __TIZEN__
+OCThreadResult_t oc_thread_cancel(oc_thread t)
+{
+    OCThreadResult_t res = OC_THREAD_SUCCESS;
+    oc_thread_internal *threadInfo = (oc_thread_internal*) t;
+    int ret = pthread_cancel(threadInfo->thread);
+    if (0 != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "Failed to cancel thread with error %d", ret);
+        res = OC_THREAD_CANCEL_FAILURE;
+    }
+
+    return res;
+}
 #endif
-} ca_cond_internal;
 
-ca_mutex ca_mutex_new(void)
+oc_mutex oc_mutex_new(void)
 {
-    ca_mutex retVal = NULL;
-    ca_mutex_internal *mutexInfo = (ca_mutex_internal*) OICMalloc(sizeof(ca_mutex_internal));
+    oc_mutex retVal = NULL;
+    oc_mutex_internal *mutexInfo = (oc_mutex_internal*) OICMalloc(sizeof(oc_mutex_internal));
     if (NULL != mutexInfo)
     {
-#if defined(_WIN32)
-        InitializeCriticalSection(&mutexInfo->mutex);
-        retVal = (ca_mutex)mutexInfo;
-#else
         // create the mutex with the attributes set
         int ret=pthread_mutex_init(&(mutexInfo->mutex), PTHREAD_MUTEX_DEFAULT);
         if (0 == ret)
         {
-            retVal = (ca_mutex) mutexInfo;
+            retVal = (oc_mutex) mutexInfo;
         }
         else
         {
             OIC_LOG_V(ERROR, TAG, "%s Failed to initialize mutex !", __func__);
             OICFree(mutexInfo);
         }
-#endif
     }
     else
     {
@@ -138,18 +218,12 @@ ca_mutex ca_mutex_new(void)
     return retVal;
 }
 
-bool ca_mutex_free(ca_mutex mutex)
+bool oc_mutex_free(oc_mutex mutex)
 {
     bool bRet=false;
-
-    ca_mutex_internal *mutexInfo = (ca_mutex_internal*) mutex;
+    oc_mutex_internal *mutexInfo = (oc_mutex_internal*) mutex;
     if (mutexInfo)
     {
-#if defined(_WIN32)
-        DeleteCriticalSection(&mutexInfo->mutex);
-        OICFree(mutexInfo);
-        bRet=true;
-#else
         int ret = pthread_mutex_destroy(&mutexInfo->mutex);
         if (0 == ret)
         {
@@ -160,7 +234,6 @@ bool ca_mutex_free(ca_mutex mutex)
         {
             OIC_LOG_V(ERROR, TAG, "%s Failed to free mutex !", __func__);
         }
-#endif
     }
     else
     {
@@ -170,63 +243,54 @@ bool ca_mutex_free(ca_mutex mutex)
     return bRet;
 }
 
-void ca_mutex_lock(ca_mutex mutex)
+void oc_mutex_lock(oc_mutex mutex)
 {
-    ca_mutex_internal *mutexInfo = (ca_mutex_internal*) mutex;
+    oc_mutex_internal *mutexInfo = (oc_mutex_internal*) mutex;
     if (mutexInfo)
     {
-#if defined(_WIN32)
-        EnterCriticalSection(&mutexInfo->mutex);
-#else
         int ret = pthread_mutex_lock(&mutexInfo->mutex);
         if(ret != 0)
         {
             OIC_LOG_V(ERROR, TAG, "Pthread Mutex lock failed: %d", ret);
             exit(ret);
         }
-#endif
     }
     else
     {
         OIC_LOG_V(ERROR, TAG, "%s Invalid mutex !", __func__);
-        return;
     }
 }
 
-void ca_mutex_unlock(ca_mutex mutex)
+void oc_mutex_unlock(oc_mutex mutex)
 {
-    ca_mutex_internal *mutexInfo = (ca_mutex_internal*) mutex;
+    oc_mutex_internal *mutexInfo = (oc_mutex_internal*) mutex;
     if (mutexInfo)
     {
-#if defined(_WIN32)
-        LeaveCriticalSection(&mutexInfo->mutex);
-#else
+#if defined(__TIZENRT__)
+        if (mutexInfo->mutex.pid == 0)
+        {
+            return;
+        }
+#endif
         int ret = pthread_mutex_unlock(&mutexInfo->mutex);
-        if(ret != 0)
+        if (ret != 0)
         {
             OIC_LOG_V(ERROR, TAG, "Pthread Mutex unlock failed: %d", ret);
             exit(ret);
         }
-        (void)ret;
-#endif
     }
     else
     {
         OIC_LOG_V(ERROR, TAG, "%s: Invalid mutex !", __func__);
-        return;
     }
 }
 
-ca_cond ca_cond_new(void)
+oc_cond oc_cond_new(void)
 {
-    ca_cond retVal = NULL;
-    ca_cond_internal *eventInfo = (ca_cond_internal*) OICMalloc(sizeof(ca_cond_internal));
+    oc_cond retVal = NULL;
+    oc_cond_internal *eventInfo = (oc_cond_internal*) OICMalloc(sizeof(oc_cond_internal));
     if (NULL != eventInfo)
     {
-#if defined(_WIN32)
-        InitializeConditionVariable(&eventInfo->cond);
-        retVal = (ca_cond) eventInfo;
-#else
         int ret = pthread_condattr_init(&(eventInfo->condattr));
         if(0 != ret)
         {
@@ -258,7 +322,7 @@ ca_cond ca_cond_new(void)
         ret = pthread_cond_init(&(eventInfo->cond), &(eventInfo->condattr));
         if (0 == ret)
         {
-            retVal = (ca_cond) eventInfo;
+            retVal = (oc_cond) eventInfo;
         }
         else
         {
@@ -266,7 +330,6 @@ ca_cond ca_cond_new(void)
             pthread_condattr_destroy(&(eventInfo->condattr));
             OICFree(eventInfo);
         }
-#endif
     }
     else
     {
@@ -276,14 +339,11 @@ ca_cond ca_cond_new(void)
     return retVal;
 }
 
-void ca_cond_free(ca_cond cond)
+void oc_cond_free(oc_cond cond)
 {
-    ca_cond_internal *eventInfo = (ca_cond_internal*) cond;
+    oc_cond_internal *eventInfo = (oc_cond_internal*) cond;
     if (eventInfo != NULL)
     {
-#if defined(_WIN32)
-        OICFree(cond);
-#else
         int ret = pthread_cond_destroy(&(eventInfo->cond));
         int ret2 = pthread_condattr_destroy(&(eventInfo->condattr));
         if (0 == ret && 0 == ret2)
@@ -295,7 +355,6 @@ void ca_cond_free(ca_cond cond)
             OIC_LOG_V(ERROR, TAG, "%s: Failed to destroy condition variable %d, %d",
                     __func__, ret, ret2);
         }
-#endif
     }
     else
     {
@@ -303,20 +362,16 @@ void ca_cond_free(ca_cond cond)
     }
 }
 
-void ca_cond_signal(ca_cond cond)
+void oc_cond_signal(oc_cond cond)
 {
-    ca_cond_internal *eventInfo = (ca_cond_internal*) cond;
+    oc_cond_internal *eventInfo = (oc_cond_internal*) cond;
     if (eventInfo != NULL)
     {
-#if defined(_WIN32)
-        WakeConditionVariable(&eventInfo->cond);
-#else
         int ret = pthread_cond_signal(&(eventInfo->cond));
         if (0 != ret)
         {
             OIC_LOG_V(ERROR, TAG, "%s: Failed to signal condition variable", __func__);
         }
-#endif
     }
     else
     {
@@ -324,20 +379,16 @@ void ca_cond_signal(ca_cond cond)
     }
 }
 
-void ca_cond_broadcast(ca_cond cond)
+void oc_cond_broadcast(oc_cond cond)
 {
-    ca_cond_internal* eventInfo = (ca_cond_internal*) cond;
+    oc_cond_internal* eventInfo = (oc_cond_internal*) cond;
     if (eventInfo != NULL)
     {
-#if defined(_WIN32)
-        WakeAllConditionVariable(&eventInfo->cond);
-#else
         int ret = pthread_cond_broadcast(&(eventInfo->cond));
         if (0 != ret)
         {
             OIC_LOG_V(ERROR, TAG, "%s: failed to signal condition variable", __func__);
         }
-#endif
     }
     else
     {
@@ -345,9 +396,9 @@ void ca_cond_broadcast(ca_cond cond)
     }
 }
 
-void ca_cond_wait(ca_cond cond, ca_mutex mutex)
+void oc_cond_wait(oc_cond cond, oc_mutex mutex)
 {
-    ca_cond_wait_for(cond, mutex, 0L);
+    oc_cond_wait_for(cond, mutex, 0L);
 }
 
 #ifndef TIMEVAL_TO_TIMESPEC
@@ -357,8 +408,7 @@ void ca_cond_wait(ca_cond cond, ca_mutex mutex)
 }
 #endif
 
-#if !defined(_WIN32)
-struct timespec ca_get_current_time()
+struct timespec oc_get_current_time()
 {
 #if defined(__ANDROID__) || _POSIX_TIMERS > 0
     struct timespec ts;
@@ -373,7 +423,7 @@ struct timespec ca_get_current_time()
 #endif
 }
 
-void ca_add_microseconds_to_timespec(struct timespec* ts, uint64_t microseconds)
+void oc_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;
@@ -383,48 +433,28 @@ void ca_add_microseconds_to_timespec(struct timespec* ts, uint64_t microseconds)
     ts->tv_nsec = (totalNs)% NANOSECS_PER_SEC;
     ts->tv_sec += secPart + secOfNs;
 }
-#endif
 
-CAWaitResult_t ca_cond_wait_for(ca_cond cond, ca_mutex mutex, uint64_t microseconds)
+OCWaitResult_t oc_cond_wait_for(oc_cond cond, oc_mutex mutex, uint64_t microseconds)
 {
-    CAWaitResult_t retVal = CA_WAIT_INVAL;
+    OCWaitResult_t retVal = OC_WAIT_INVAL;
 
-    ca_cond_internal *eventInfo = (ca_cond_internal*) cond;
-    ca_mutex_internal *mutexInfo = (ca_mutex_internal*) mutex;
+    oc_cond_internal *eventInfo = (oc_cond_internal*) cond;
+    oc_mutex_internal *mutexInfo = (oc_mutex_internal*) mutex;
 
     if (NULL == mutexInfo)
     {
         OIC_LOG_V(ERROR, TAG, "%s: Invalid mutex", __func__);
-        return CA_WAIT_INVAL;
+        return OC_WAIT_INVAL;
     }
 
     if (NULL == eventInfo)
     {
         OIC_LOG_V(ERROR, TAG, "%s: Invalid condition", __func__);
-        return CA_WAIT_INVAL;
+        return OC_WAIT_INVAL;
     }
 
     if (microseconds > 0)
     {
-#if defined(_WIN32)
-        // Wait for the given time
-        DWORD milli = (DWORD)(microseconds / 1000);
-        if (!SleepConditionVariableCS(&eventInfo->cond, &mutexInfo->mutex, milli))
-        {
-            if (GetLastError() == ERROR_TIMEOUT)
-            {
-                retVal = CA_WAIT_TIMEDOUT;
-            }
-            else
-            {
-                OIC_LOG_V(ERROR, TAG, "SleepConditionVariableCS() with Timeout failed %i", GetLastError());
-                retVal = CA_WAIT_INVAL;
-            }
-        }else
-        {
-            retVal = CA_WAIT_SUCCESS;
-        }
-#else
         int ret = 0;
         struct timespec abstime = { .tv_sec = 0 };
 
@@ -438,8 +468,8 @@ CAWaitResult_t ca_cond_wait_for(ca_cond cond, ca_mutex mutex, uint64_t microseco
         } else
 #endif
         {
-             abstime = ca_get_current_time();
-            ca_add_microseconds_to_timespec(&abstime, microseconds);
+             abstime = oc_get_current_time();
+            oc_add_microseconds_to_timespec(&abstime, microseconds);
 
             //Wait for the given time
             ret = pthread_cond_timedwait(&(eventInfo->cond), &(mutexInfo->mutex), &abstime);
@@ -449,39 +479,26 @@ CAWaitResult_t ca_cond_wait_for(ca_cond cond, ca_mutex mutex, uint64_t microseco
         {
             case 0:
                 // Success
-                retVal = CA_WAIT_SUCCESS;
+                retVal = OC_WAIT_SUCCESS;
                 break;
             case ETIMEDOUT:
-                retVal = CA_WAIT_TIMEDOUT;
+                retVal = OC_WAIT_TIMEDOUT;
                 break;
             case EINVAL:
                 OIC_LOG_V(ERROR, TAG, "%s: condition, mutex, or abstime is Invalid", __func__);
-                retVal = CA_WAIT_INVAL;
+                retVal = OC_WAIT_INVAL;
                 break;
             default:
                 OIC_LOG_V(ERROR, TAG, "%s: pthread_cond_timedwait returned %d", __func__, retVal);
-                retVal = CA_WAIT_INVAL;
+                retVal = OC_WAIT_INVAL;
                 break;
         }
-#endif
     }
     else
     {
-#if defined(_WIN32)
-        // Wait forever
-        if (!SleepConditionVariableCS(&eventInfo->cond, &mutexInfo->mutex, INFINITE))
-        {
-            OIC_LOG_V(ERROR, TAG, "SleepConditionVariableCS() w/o Timeout failed %i", GetLastError());
-            retVal = CA_WAIT_INVAL;
-        }else
-        {
-            retVal = CA_WAIT_SUCCESS;
-        }
-#else
         // Wait forever
         int ret = pthread_cond_wait(&eventInfo->cond, &mutexInfo->mutex);
-        retVal = ret == 0 ? CA_WAIT_SUCCESS : CA_WAIT_INVAL;
-#endif
+        retVal = ret == 0 ? OC_WAIT_SUCCESS : OC_WAIT_INVAL;
     }
     return retVal;
 }
diff --git a/resource/c_common/octhread/src/windows/octhread.c b/resource/c_common/octhread/src/windows/octhread.c
new file mode 100644 (file)
index 0000000..2613883
--- /dev/null
@@ -0,0 +1,287 @@
+/* *****************************************************************
+*
+* Copyright 2016 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.
+*
+******************************************************************/
+
+
+/**
+ * @file
+ * This file provides APIs related to mutex, semaphores, and threads.
+ */
+#include "iotivity_config.h"
+#include "octhread.h"
+#include <string.h>
+#include <time.h>
+#include <winsock2.h>
+#include <stdio.h>
+#include <errno.h>
+#include <oic_malloc.h>
+
+#include "logger.h"
+
+static const uint64_t USECS_PER_MSEC = 1000;
+
+typedef struct _tagMutexInfo_t
+{
+    CRITICAL_SECTION mutex;
+} oc_mutex_internal;
+
+typedef struct _tagEventInfo_t
+{
+    CONDITION_VARIABLE cond;
+} oc_cond_internal;
+
+typedef struct _tagThreadInfo_t
+{
+    HANDLE handle;
+} oc_thread_internal;
+
+OCThreadResult_t oc_thread_new(oc_thread *t, void *(*start_routine)(void *), void *arg)
+{
+    OCThreadResult_t res = OC_THREAD_SUCCESS;
+    oc_thread_internal *threadInfo = (oc_thread_internal*)OICMalloc(sizeof(oc_thread_internal));
+    if (NULL != threadInfo)
+    {
+        threadInfo->handle = CreateThread(NULL, 0, (PTHREAD_START_ROUTINE)start_routine, arg, 0, NULL);
+        if (threadInfo->handle == NULL)
+        {
+            res = OC_THREAD_CREATE_FAILURE;
+            *t = NULL;
+            OICFree(threadInfo);
+            OIC_LOG_V(ERROR, TAG, "%s: CreateThread failed: %i", __func__, GetLastError());
+        }
+        else
+        {
+            *t = (oc_thread)threadInfo;
+        }
+    }
+    else
+    {
+        OIC_LOG_V(ERROR, TAG, "%s Failed to allocate thread!", __func__);
+        *t = NULL;
+        res = OC_THREAD_ALLOCATION_FAILURE;
+    }
+
+   return res;
+}
+
+OCThreadResult_t oc_thread_free(oc_thread t)
+{
+    OCThreadResult_t res = OC_THREAD_INVALID_PARAMETER;
+    oc_thread_internal *threadInfo = (oc_thread_internal*) t;
+    if (threadInfo)
+    {
+        CloseHandle(threadInfo->handle);
+        OICFree(threadInfo);
+        res = OC_THREAD_SUCCESS;
+    }
+    else
+    {
+        OIC_LOG_V(ERROR, TAG, "%s Invalid thread !", __func__);
+    }
+    return res;
+}
+
+OCThreadResult_t oc_thread_wait(oc_thread t)
+{
+    OCThreadResult_t res = OC_THREAD_SUCCESS;
+    oc_thread_internal *threadInfo = (oc_thread_internal*) t;
+    DWORD joinres = WaitForSingleObject(threadInfo->handle, INFINITE);
+    if (WAIT_OBJECT_0 != joinres)
+    {
+        OIC_LOG(ERROR, TAG, "Failed to join thread");
+        res = OC_THREAD_WAIT_FAILURE;
+    }
+    else
+    {
+        CloseHandle(threadInfo->handle);
+    }
+    return res;
+}
+
+oc_mutex oc_mutex_new(void)
+{
+    oc_mutex retVal = NULL;
+    oc_mutex_internal *mutexInfo = (oc_mutex_internal*) OICMalloc(sizeof(oc_mutex_internal));
+    if (NULL != mutexInfo)
+    {
+        InitializeCriticalSection(&mutexInfo->mutex);
+        retVal = (oc_mutex)mutexInfo;
+    }
+    else
+    {
+        OIC_LOG_V(ERROR, TAG, "%s Failed to allocate mutex!", __func__);
+    }
+
+    return retVal;
+}
+
+bool oc_mutex_free(oc_mutex mutex)
+{
+    bool bRet = false;
+    oc_mutex_internal *mutexInfo = (oc_mutex_internal*) mutex;
+    if (mutexInfo)
+    {
+        DeleteCriticalSection(&mutexInfo->mutex);
+        OICFree(mutexInfo);
+        bRet=true;
+    }
+    else
+    {
+        OIC_LOG_V(ERROR, TAG, "%s Invalid mutex !", __func__);
+    }
+
+    return bRet;
+}
+
+void oc_mutex_lock(oc_mutex mutex)
+{
+    oc_mutex_internal *mutexInfo = (oc_mutex_internal*) mutex;
+    if (mutexInfo)
+    {
+        EnterCriticalSection(&mutexInfo->mutex);
+    }
+    else
+    {
+        OIC_LOG_V(ERROR, TAG, "%s Invalid mutex !", __func__);
+    }
+}
+
+void oc_mutex_unlock(oc_mutex mutex)
+{
+    oc_mutex_internal *mutexInfo = (oc_mutex_internal*) mutex;
+    if (mutexInfo)
+    {
+        LeaveCriticalSection(&mutexInfo->mutex);
+    }
+    else
+    {
+        OIC_LOG_V(ERROR, TAG, "%s: Invalid mutex !", __func__);
+    }
+}
+
+oc_cond oc_cond_new(void)
+{
+    oc_cond retVal = NULL;
+    oc_cond_internal *eventInfo = (oc_cond_internal*) OICMalloc(sizeof(oc_cond_internal));
+    if (NULL != eventInfo)
+    {
+        InitializeConditionVariable(&eventInfo->cond);
+        retVal = (oc_cond) eventInfo;
+    }
+    else
+    {
+        OIC_LOG_V(ERROR, TAG, "%s: Failed to allocate condition variable!", __func__);
+    }
+
+    return retVal;
+}
+
+void oc_cond_free(oc_cond cond)
+{
+    oc_cond_internal *eventInfo = (oc_cond_internal*) cond;
+    if (eventInfo != NULL)
+    {
+        OICFree(cond);
+    }
+    else
+    {
+        OIC_LOG_V(ERROR, TAG, "%s: Invalid parameter", __func__);
+    }
+}
+
+void oc_cond_signal(oc_cond cond)
+{
+    oc_cond_internal *eventInfo = (oc_cond_internal*) cond;
+    if (eventInfo != NULL)
+    {
+        WakeConditionVariable(&eventInfo->cond);
+    }
+    else
+    {
+        OIC_LOG_V(ERROR, TAG, "%s: Invalid parameter", __func__);
+    }
+}
+
+void oc_cond_broadcast(oc_cond cond)
+{
+    oc_cond_internal* eventInfo = (oc_cond_internal*) cond;
+    if (eventInfo != NULL)
+    {
+        WakeAllConditionVariable(&eventInfo->cond);
+    }
+    else
+    {
+        OIC_LOG_V(ERROR, TAG, "%s: Invalid parameter", __func__);
+    }
+}
+
+void oc_cond_wait(oc_cond cond, oc_mutex mutex)
+{
+    oc_cond_wait_for(cond, mutex, 0L);
+}
+
+OCWaitResult_t oc_cond_wait_for(oc_cond cond, oc_mutex mutex, uint64_t microseconds)
+{
+    OCWaitResult_t retVal = OC_WAIT_INVAL;
+
+    oc_cond_internal *eventInfo = (oc_cond_internal*) cond;
+    oc_mutex_internal *mutexInfo = (oc_mutex_internal*) mutex;
+
+    if (NULL == mutexInfo)
+    {
+        OIC_LOG_V(ERROR, TAG, "%s: Invalid mutex", __func__);
+        return OC_WAIT_INVAL;
+    }
+
+    if (NULL == eventInfo)
+    {
+        OIC_LOG_V(ERROR, TAG, "%s: Invalid condition", __func__);
+        return OC_WAIT_INVAL;
+    }
+
+    DWORD milli = 0;
+    if (microseconds > 0)
+    {
+        milli = (DWORD)(microseconds / USECS_PER_MSEC);
+    }
+    else
+    {
+        milli = INFINITE;
+    }
+
+    // Wait for the given time        
+    if (!SleepConditionVariableCS(&eventInfo->cond, &mutexInfo->mutex, milli))
+    {
+        if (GetLastError() == ERROR_TIMEOUT)
+        {
+            retVal = OC_WAIT_TIMEDOUT;
+        }
+        else
+        {
+            OIC_LOG_V(ERROR, TAG, "SleepConditionVariableCS() failed %i", GetLastError());
+            retVal = OC_WAIT_INVAL;
+        }
+    }
+    else
+    {
+        retVal = OC_WAIT_SUCCESS;
+    }
+
+    return retVal;
+}
+
index 3af42cd..5e1a065 100644 (file)
 #ifndef PLATFORM_FEATURES_H_
 #define PLATFORM_FEATURES_H_
 
-
-#if (__cplusplus >=201103L) || defined(__GXX_EXPERIMENTAL_CXX0X__)
-#  define SUPPORTS_DEFAULT_CTOR
+#ifndef __TIZENRT__
+#  if (__cplusplus >=201103L) || defined(__GXX_EXPERIMENTAL_CXX0X__)
+#    define SUPPORTS_DEFAULT_CTOR
+#  endif
 #endif
 
-#if (__STDC_VERSION__ >= 201112L)
-#  include <assert.h>
-#  define OC_STATIC_ASSERT(condition, msg) static_assert(condition, msg)
-#elif defined(_WIN32)
-#  if defined(__msys_nt__) && !defined(__cplusplus)
-#    define static_assert _Static_assert
+#ifndef __TIZENRT__
+#  if (__STDC_VERSION__ >= 201112L)
+#    include <assert.h>
+#    define OC_STATIC_ASSERT(condition, msg) static_assert(condition, msg)
+#  elif defined(_WIN32)
+#    if defined(__msys_nt__) && !defined(__cplusplus)
+#      define static_assert _Static_assert
+#    endif
+#    define OC_STATIC_ASSERT(condition, msg) static_assert(condition, msg)
+#  else
+#    define OC_STATIC_ASSERT(condition, msg) ((void)sizeof(char[2*!!(condition) - 1]))
 #  endif
-#  define OC_STATIC_ASSERT(condition, msg) static_assert(condition, msg)
-#else
-#  define OC_STATIC_ASSERT(condition, msg) ((void)sizeof(char[2*!!(condition) - 1]))
 #endif
 
 #ifndef INLINE_API
diff --git a/resource/c_common/utlist.h b/resource/c_common/utlist.h
new file mode 100644 (file)
index 0000000..84216ae
--- /dev/null
@@ -0,0 +1,892 @@
+/*
+Copyright (c) 2007-2016, Troy D. Hanson   http://troydhanson.github.com/uthash/
+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 UTLIST_H
+#define UTLIST_H
+
+#define UTLIST_VERSION 2.0.1
+
+#include <assert.h>
+
+/*
+ * 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 && defined(__cplusplus)  /* VS2010 or newer in C++ mode */
+#define LDECLTYPE(x) decltype(x)
+#else                     /* VS2008 or older (or VS2010 in C mode) */
+#define NO_DECLTYPE
+#endif
+#elif defined(__ICCARM__)
+#define NO_DECLTYPE
+#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 IF_NO_DECLTYPE(x) x
+#define LDECLTYPE(x) char*
+#define _SV(elt,list) _tmp = (char*)(list); {char **_alias = (char**)&(list); *_alias = (elt); }
+#define _NEXT(elt,list,next) ((char*)((list)->next))
+#define _NEXTASGN(elt,list,to,next) { char **_alias = (char**)&((list)->next); *_alias=(char*)(to); }
+/* #define _PREV(elt,list,prev) ((char*)((list)->prev)) */
+#define _PREVASGN(elt,list,to,prev) { 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 IF_NO_DECLTYPE(x)
+#define _SV(elt,list)
+#define _NEXT(elt,list,next) ((elt)->next)
+#define _NEXTASGN(elt,list,to,next) ((elt)->next)=(to)
+/* #define _PREV(elt,list,prev) ((elt)->prev) */
+#define _PREVASGN(elt,list,to,prev) ((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)                                                                     \
+    LL_SORT2(list, cmp, next)
+
+#define LL_SORT2(list, cmp, next)                                                              \
+do {                                                                                           \
+  LDECLTYPE(list) _ls_p;                                                                       \
+  LDECLTYPE(list) _ls_q;                                                                       \
+  LDECLTYPE(list) _ls_e;                                                                       \
+  LDECLTYPE(list) _ls_tail;                                                                    \
+  IF_NO_DECLTYPE(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);                                                                   \
+      (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,next); _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,next); _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,next); _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,next); _RS(list); _ls_psize--;                                  \
+          } else {                                                                             \
+            _ls_e = _ls_q; _SV(_ls_q,list); _ls_q =                                            \
+              _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--;                                  \
+          }                                                                                    \
+          if (_ls_tail) {                                                                      \
+            _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e,next); _RS(list);                \
+          } else {                                                                             \
+            _CASTASGN(list,_ls_e);                                                             \
+          }                                                                                    \
+          _ls_tail = _ls_e;                                                                    \
+        }                                                                                      \
+        _ls_p = _ls_q;                                                                         \
+      }                                                                                        \
+      if (_ls_tail) {                                                                          \
+        _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL,next); _RS(list);                     \
+      }                                                                                        \
+      if (_ls_nmerges <= 1) {                                                                  \
+        _ls_looping=0;                                                                         \
+      }                                                                                        \
+      _ls_insize *= 2;                                                                         \
+    }                                                                                          \
+  }                                                                                            \
+} while (0)
+
+
+#define DL_SORT(list, cmp)                                                                     \
+    DL_SORT2(list, cmp, prev, next)
+
+#define DL_SORT2(list, cmp, prev, next)                                                        \
+do {                                                                                           \
+  LDECLTYPE(list) _ls_p;                                                                       \
+  LDECLTYPE(list) _ls_q;                                                                       \
+  LDECLTYPE(list) _ls_e;                                                                       \
+  LDECLTYPE(list) _ls_tail;                                                                    \
+  IF_NO_DECLTYPE(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);                                                                   \
+      (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,next); _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,next); _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,next); _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,next); _RS(list); _ls_psize--;                                  \
+          } else {                                                                             \
+            _ls_e = _ls_q; _SV(_ls_q,list); _ls_q =                                            \
+              _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--;                                  \
+          }                                                                                    \
+          if (_ls_tail) {                                                                      \
+            _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e,next); _RS(list);                \
+          } else {                                                                             \
+            _CASTASGN(list,_ls_e);                                                             \
+          }                                                                                    \
+          _SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail,prev); _RS(list);                     \
+          _ls_tail = _ls_e;                                                                    \
+        }                                                                                      \
+        _ls_p = _ls_q;                                                                         \
+      }                                                                                        \
+      _CASTASGN((list)->prev, _ls_tail);                                                       \
+      _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL,next); _RS(list);                       \
+      if (_ls_nmerges <= 1) {                                                                  \
+        _ls_looping=0;                                                                         \
+      }                                                                                        \
+      _ls_insize *= 2;                                                                         \
+    }                                                                                          \
+  }                                                                                            \
+} while (0)
+
+#define CDL_SORT(list, cmp)                                                                    \
+    CDL_SORT2(list, cmp, prev, next)
+
+#define CDL_SORT2(list, cmp, prev, next)                                                       \
+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);                                                                     \
+          if (_NEXT(_ls_q,list,next) == _ls_oldhead) {                                         \
+            _ls_q = NULL;                                                                      \
+          } else {                                                                             \
+            _ls_q = _NEXT(_ls_q,list,next);                                                    \
+          }                                                                                    \
+          _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,next); _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,next); _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,next); _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,next); _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,next); _RS(list);                \
+          } else {                                                                             \
+            _CASTASGN(list,_ls_e);                                                             \
+          }                                                                                    \
+          _SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail,prev); _RS(list);                     \
+          _ls_tail = _ls_e;                                                                    \
+        }                                                                                      \
+        _ls_p = _ls_q;                                                                         \
+      }                                                                                        \
+      _CASTASGN((list)->prev,_ls_tail);                                                        \
+      _CASTASGN(_tmp,list);                                                                    \
+      _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_tmp,next); _RS(list);                       \
+      if (_ls_nmerges <= 1) {                                                                  \
+        _ls_looping=0;                                                                         \
+      }                                                                                        \
+      _ls_insize *= 2;                                                                         \
+    }                                                                                          \
+  }                                                                                            \
+} while (0)
+
+/******************************************************************************
+ * singly linked list macros (non-circular)                                   *
+ *****************************************************************************/
+#define LL_PREPEND(head,add)                                                                   \
+    LL_PREPEND2(head,add,next)
+
+#define LL_PREPEND2(head,add,next)                                                             \
+do {                                                                                           \
+  (add)->next = (head);                                                                        \
+  (head) = (add);                                                                              \
+} while (0)
+
+#define LL_CONCAT(head1,head2)                                                                 \
+    LL_CONCAT2(head1,head2,next)
+
+#define LL_CONCAT2(head1,head2,next)                                                           \
+do {                                                                                           \
+  LDECLTYPE(head1) _tmp;                                                                       \
+  if (head1) {                                                                                 \
+    _tmp = (head1);                                                                            \
+    while (_tmp->next) { _tmp = _tmp->next; }                                                  \
+    _tmp->next=(head2);                                                                        \
+  } else {                                                                                     \
+    (head1)=(head2);                                                                           \
+  }                                                                                            \
+} while (0)
+
+#define LL_APPEND(head,add)                                                                    \
+    LL_APPEND2(head,add,next)
+
+#define LL_APPEND2(head,add,next)                                                              \
+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)                                                                    \
+    LL_DELETE2(head,del,next)
+
+#define LL_DELETE2(head,del,next)                                                              \
+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)
+
+#define LL_COUNT(head,el,counter)                                                              \
+    LL_COUNT2(head,el,counter,next)                                                            \
+
+#define LL_COUNT2(head,el,counter,next)                                                        \
+do {                                                                                           \
+  (counter) = 0;                                                                               \
+  LL_FOREACH2(head,el,next) { ++(counter); }                                                   \
+} while (0)
+
+#define LL_FOREACH(head,el)                                                                    \
+    LL_FOREACH2(head,el,next)
+
+#define LL_FOREACH2(head,el,next)                                                              \
+    for ((el) = (head); el; (el) = (el)->next)
+
+#define LL_FOREACH_SAFE(head,el,tmp)                                                           \
+    LL_FOREACH_SAFE2(head,el,tmp,next)
+
+#define LL_FOREACH_SAFE2(head,el,tmp,next)                                                     \
+  for ((el) = (head); (el) && ((tmp) = (el)->next, 1); (el) = (tmp))
+
+#define LL_SEARCH_SCALAR(head,out,field,val)                                                   \
+    LL_SEARCH_SCALAR2(head,out,field,val,next)
+
+#define LL_SEARCH_SCALAR2(head,out,field,val,next)                                             \
+do {                                                                                           \
+    LL_FOREACH2(head,out,next) {                                                               \
+      if ((out)->field == (val)) break;                                                        \
+    }                                                                                          \
+} while (0)
+
+#define LL_SEARCH(head,out,elt,cmp)                                                            \
+    LL_SEARCH2(head,out,elt,cmp,next)
+
+#define LL_SEARCH2(head,out,elt,cmp,next)                                                      \
+do {                                                                                           \
+    LL_FOREACH2(head,out,next) {                                                               \
+      if ((cmp(out,elt))==0) break;                                                            \
+    }                                                                                          \
+} while (0)
+
+#define LL_REPLACE_ELEM2(head, el, add, next)                                                  \
+do {                                                                                           \
+ LDECLTYPE(head) _tmp;                                                                         \
+ assert((head) != NULL);                                                                       \
+ assert((el) != NULL);                                                                         \
+ assert((add) != NULL);                                                                        \
+ (add)->next = (el)->next;                                                                     \
+ if ((head) == (el)) {                                                                         \
+  (head) = (add);                                                                              \
+ } else {                                                                                      \
+  _tmp = (head);                                                                               \
+  while (_tmp->next && (_tmp->next != (el))) {                                                 \
+   _tmp = _tmp->next;                                                                          \
+  }                                                                                            \
+  if (_tmp->next) {                                                                            \
+    _tmp->next = (add);                                                                        \
+  }                                                                                            \
+ }                                                                                             \
+} while (0)
+
+#define LL_REPLACE_ELEM(head, el, add)                                                         \
+    LL_REPLACE_ELEM2(head, el, add, next)
+
+#define LL_PREPEND_ELEM2(head, el, add, next)                                                  \
+do {                                                                                           \
+ if (el) {                                                                                     \
+  LDECLTYPE(head) _tmp;                                                                        \
+  assert((head) != NULL);                                                                      \
+  assert((add) != NULL);                                                                       \
+  (add)->next = (el);                                                                          \
+  if ((head) == (el)) {                                                                        \
+   (head) = (add);                                                                             \
+  } else {                                                                                     \
+   _tmp = (head);                                                                              \
+   while (_tmp->next && (_tmp->next != (el))) {                                                \
+    _tmp = _tmp->next;                                                                         \
+   }                                                                                           \
+   if (_tmp->next) {                                                                           \
+     _tmp->next = (add);                                                                       \
+   }                                                                                           \
+  }                                                                                            \
+ } else {                                                                                      \
+  LL_APPEND2(head, add, next);                                                                 \
+ }                                                                                             \
+} while (0)                                                                                    \
+
+#define LL_PREPEND_ELEM(head, el, add)                                                         \
+    LL_PREPEND_ELEM2(head, el, add, next)
+
+#define LL_APPEND_ELEM2(head, el, add, next)                                                   \
+do {                                                                                           \
+ if (el) {                                                                                     \
+  assert((head) != NULL);                                                                      \
+  assert((add) != NULL);                                                                       \
+  (add)->next = (el)->next;                                                                    \
+  (el)->next = (add);                                                                          \
+ } else {                                                                                      \
+  LL_PREPEND2(head, add, next);                                                                \
+ }                                                                                             \
+} while (0)                                                                                    \
+
+#define LL_APPEND_ELEM(head, el, add)                                                          \
+    LL_APPEND_ELEM2(head, el, add, next)
+
+#ifdef NO_DECLTYPE
+/* Here are VS2008 / NO_DECLTYPE replacements for a few functions */
+
+#undef LL_CONCAT2
+#define LL_CONCAT2(head1,head2,next)                                                           \
+do {                                                                                           \
+  char *_tmp;                                                                                  \
+  if (head1) {                                                                                 \
+    _tmp = (char*)(head1);                                                                     \
+    while ((head1)->next) { (head1) = (head1)->next; }                                         \
+    (head1)->next = (head2);                                                                   \
+    _RS(head1);                                                                                \
+  } else {                                                                                     \
+    (head1)=(head2);                                                                           \
+  }                                                                                            \
+} while (0)
+
+#undef LL_APPEND2
+#define LL_APPEND2(head,add,next)                                                              \
+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)
+
+#undef LL_DELETE2
+#define LL_DELETE2(head,del,next)                                                              \
+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);                                                            \
+    }                                                                                          \
+    _RS(head);                                                                                 \
+  }                                                                                            \
+} while (0)
+
+#undef LL_REPLACE_ELEM2
+#define LL_REPLACE_ELEM2(head, el, add, next)                                                  \
+do {                                                                                           \
+  assert((head) != NULL);                                                                      \
+  assert((el) != NULL);                                                                        \
+  assert((add) != NULL);                                                                       \
+  if ((head) == (el)) {                                                                        \
+    (head) = (add);                                                                            \
+  } else {                                                                                     \
+    (add)->next = head;                                                                        \
+    while ((add)->next->next && ((add)->next->next != (el))) {                                 \
+      (add)->next = (add)->next->next;                                                         \
+    }                                                                                          \
+    if ((add)->next->next) {                                                                   \
+      (add)->next->next = (add);                                                               \
+    }                                                                                          \
+  }                                                                                            \
+  (add)->next = (el)->next;                                                                    \
+} while (0)
+
+#undef LL_PREPEND_ELEM2
+#define LL_PREPEND_ELEM2(head, el, add, next)                                                  \
+do {                                                                                           \
+  if (el) {                                                                                    \
+    assert((head) != NULL);                                                                    \
+    assert((add) != NULL);                                                                     \
+    if ((head) == (el)) {                                                                      \
+      (head) = (add);                                                                          \
+    } else {                                                                                   \
+      (add)->next = (head);                                                                    \
+      while ((add)->next->next && ((add)->next->next != (el))) {                               \
+        (add)->next = (add)->next->next;                                                       \
+      }                                                                                        \
+      if ((add)->next->next) {                                                                 \
+        (add)->next->next = (add);                                                             \
+      }                                                                                        \
+    }                                                                                          \
+    (add)->next = (el);                                                                        \
+  } else {                                                                                     \
+    LL_APPEND2(head, add, next);                                                               \
+  }                                                                                            \
+} while (0)                                                                                    \
+
+#endif /* NO_DECLTYPE */
+
+/******************************************************************************
+ * doubly linked list macros (non-circular)                                   *
+ *****************************************************************************/
+#define DL_PREPEND(head,add)                                                                   \
+    DL_PREPEND2(head,add,prev,next)
+
+#define DL_PREPEND2(head,add,prev,next)                                                        \
+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)                                                                    \
+    DL_APPEND2(head,add,prev,next)
+
+#define DL_APPEND2(head,add,prev,next)                                                         \
+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_CONCAT(head1,head2)                                                                 \
+    DL_CONCAT2(head1,head2,prev,next)
+
+#define DL_CONCAT2(head1,head2,prev,next)                                                      \
+do {                                                                                           \
+  LDECLTYPE(head1) _tmp;                                                                       \
+  if (head2) {                                                                                 \
+    if (head1) {                                                                               \
+        _CASTASGN(_tmp, (head2)->prev);                                                        \
+        (head2)->prev = (head1)->prev;                                                         \
+        (head1)->prev->next = (head2);                                                         \
+        _CASTASGN((head1)->prev, _tmp);                                                        \
+    } else {                                                                                   \
+        (head1)=(head2);                                                                       \
+    }                                                                                          \
+  }                                                                                            \
+} while (0)
+
+#define DL_DELETE(head,del)                                                                    \
+    DL_DELETE2(head,del,prev,next)
+
+#define DL_DELETE2(head,del,prev,next)                                                         \
+do {                                                                                           \
+  assert((del)->prev != NULL);                                                                 \
+  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_COUNT(head,el,counter)                                                              \
+    DL_COUNT2(head,el,counter,next)                                                            \
+
+#define DL_COUNT2(head,el,counter,next)                                                        \
+do {                                                                                           \
+  (counter) = 0;                                                                               \
+  DL_FOREACH2(head,el,next) { ++(counter); }                                                   \
+} while (0)
+
+#define DL_FOREACH(head,el)                                                                    \
+    DL_FOREACH2(head,el,next)
+
+#define DL_FOREACH2(head,el,next)                                                              \
+    for ((el) = (head); el; (el) = (el)->next)
+
+/* this version is safe for deleting the elements during iteration */
+#define DL_FOREACH_SAFE(head,el,tmp)                                                           \
+    DL_FOREACH_SAFE2(head,el,tmp,next)
+
+#define DL_FOREACH_SAFE2(head,el,tmp,next)                                                     \
+  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
+#define DL_SEARCH_SCALAR2 LL_SEARCH_SCALAR2
+#define DL_SEARCH2 LL_SEARCH2
+
+#define DL_REPLACE_ELEM2(head, el, add, prev, next)                                            \
+do {                                                                                           \
+ assert((head) != NULL);                                                                       \
+ assert((el) != NULL);                                                                         \
+ assert((add) != NULL);                                                                        \
+ if ((head) == (el)) {                                                                         \
+  (head) = (add);                                                                              \
+  (add)->next = (el)->next;                                                                    \
+  if ((el)->next == NULL) {                                                                    \
+   (add)->prev = (add);                                                                        \
+  } else {                                                                                     \
+   (add)->prev = (el)->prev;                                                                   \
+   (add)->next->prev = (add);                                                                  \
+  }                                                                                            \
+ } else {                                                                                      \
+  (add)->next = (el)->next;                                                                    \
+  (add)->prev = (el)->prev;                                                                    \
+  (add)->prev->next = (add);                                                                   \
+  if ((el)->next == NULL) {                                                                    \
+   (head)->prev = (add);                                                                       \
+  } else {                                                                                     \
+   (add)->next->prev = (add);                                                                  \
+  }                                                                                            \
+ }                                                                                             \
+} while (0)
+
+#define DL_REPLACE_ELEM(head, el, add)                                                         \
+    DL_REPLACE_ELEM2(head, el, add, prev, next)
+
+#define DL_PREPEND_ELEM2(head, el, add, prev, next)                                            \
+do {                                                                                           \
+ if (el) {                                                                                     \
+  assert((head) != NULL);                                                                      \
+  assert((add) != NULL);                                                                       \
+  (add)->next = (el);                                                                          \
+  (add)->prev = (el)->prev;                                                                    \
+  (el)->prev = (add);                                                                          \
+  if ((head) == (el)) {                                                                        \
+   (head) = (add);                                                                             \
+  } else {                                                                                     \
+   (add)->prev->next = (add);                                                                  \
+  }                                                                                            \
+ } else {                                                                                      \
+  DL_APPEND2(head, add, prev, next);                                                           \
+ }                                                                                             \
+} while (0)                                                                                    \
+
+#define DL_PREPEND_ELEM(head, el, add)                                                         \
+    DL_PREPEND_ELEM2(head, el, add, prev, next)
+
+#define DL_APPEND_ELEM2(head, el, add, prev, next)                                             \
+do {                                                                                           \
+ if (el) {                                                                                     \
+  assert((head) != NULL);                                                                      \
+  assert((add) != NULL);                                                                       \
+  (add)->next = (el)->next;                                                                    \
+  (add)->prev = (el);                                                                          \
+  (el)->next = (add);                                                                          \
+  if ((add)->next) {                                                                           \
+   (add)->next->prev = (add);                                                                  \
+  } else {                                                                                     \
+   (head)->prev = (add);                                                                       \
+  }                                                                                            \
+ } else {                                                                                      \
+  DL_PREPEND2(head, add, prev, next);                                                          \
+ }                                                                                             \
+} while (0)                                                                                    \
+
+#define DL_APPEND_ELEM(head, el, add)                                                          \
+   DL_APPEND_ELEM2(head, el, add, prev, next)
+
+/******************************************************************************
+ * circular doubly linked list macros                                         *
+ *****************************************************************************/
+#define CDL_APPEND(head,add)                                                                   \
+    CDL_APPEND2(head,add,prev,next)
+
+#define CDL_APPEND2(head,add,prev,next)                                                        \
+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_PREPEND(head,add)                                                                  \
+    CDL_PREPEND2(head,add,prev,next)
+
+#define CDL_PREPEND2(head,add,prev,next)                                                       \
+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)                                                                   \
+    CDL_DELETE2(head,del,prev,next)
+
+#define CDL_DELETE2(head,del,prev,next)                                                        \
+do {                                                                                           \
+  if (((head)==(del)) && ((head)->next == (head))) {                                           \
+      (head) = NULL;                                                                           \
+  } else {                                                                                     \
+     (del)->next->prev = (del)->prev;                                                          \
+     (del)->prev->next = (del)->next;                                                          \
+     if ((del) == (head)) (head)=(del)->next;                                                  \
+  }                                                                                            \
+} while (0)
+
+#define CDL_COUNT(head,el,counter)                                                             \
+    CDL_COUNT2(head,el,counter,next)                                                           \
+
+#define CDL_COUNT2(head, el, counter,next)                                                     \
+do {                                                                                           \
+  (counter) = 0;                                                                               \
+  CDL_FOREACH2(head,el,next) { ++(counter); }                                                  \
+} while (0)
+
+#define CDL_FOREACH(head,el)                                                                   \
+    CDL_FOREACH2(head,el,next)
+
+#define CDL_FOREACH2(head,el,next)                                                             \
+    for ((el)=(head);el;(el)=(((el)->next==(head)) ? NULL : (el)->next))
+
+#define CDL_FOREACH_SAFE(head,el,tmp1,tmp2)                                                    \
+    CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next)
+
+#define CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next)                                         \
+  for ((el) = (head), (tmp1) = (head) ? (head)->prev : NULL;                                   \
+       (el) && ((tmp2) = (el)->next, 1);                                                       \
+       (el) = ((el) == (tmp1) ? NULL : (tmp2)))
+
+#define CDL_SEARCH_SCALAR(head,out,field,val)                                                  \
+    CDL_SEARCH_SCALAR2(head,out,field,val,next)
+
+#define CDL_SEARCH_SCALAR2(head,out,field,val,next)                                            \
+do {                                                                                           \
+    CDL_FOREACH2(head,out,next) {                                                              \
+      if ((out)->field == (val)) break;                                                        \
+    }                                                                                          \
+} while (0)
+
+#define CDL_SEARCH(head,out,elt,cmp)                                                           \
+    CDL_SEARCH2(head,out,elt,cmp,next)
+
+#define CDL_SEARCH2(head,out,elt,cmp,next)                                                     \
+do {                                                                                           \
+    CDL_FOREACH2(head,out,next) {                                                              \
+      if ((cmp(out,elt))==0) break;                                                            \
+    }                                                                                          \
+} while (0)
+
+#define CDL_REPLACE_ELEM2(head, el, add, prev, next)                                           \
+do {                                                                                           \
+ assert((head) != NULL);                                                                       \
+ assert((el) != NULL);                                                                         \
+ assert((add) != NULL);                                                                        \
+ if ((el)->next == (el)) {                                                                     \
+  (add)->next = (add);                                                                         \
+  (add)->prev = (add);                                                                         \
+  (head) = (add);                                                                              \
+ } else {                                                                                      \
+  (add)->next = (el)->next;                                                                    \
+  (add)->prev = (el)->prev;                                                                    \
+  (add)->next->prev = (add);                                                                   \
+  (add)->prev->next = (add);                                                                   \
+  if ((head) == (el)) {                                                                        \
+   (head) = (add);                                                                             \
+  }                                                                                            \
+ }                                                                                             \
+} while (0)
+
+#define CDL_REPLACE_ELEM(head, el, add)                                                        \
+    CDL_REPLACE_ELEM2(head, el, add, prev, next)
+
+#define CDL_PREPEND_ELEM2(head, el, add, prev, next)                                           \
+do {                                                                                           \
+  if (el) {                                                                                    \
+    assert((head) != NULL);                                                                    \
+    assert((add) != NULL);                                                                     \
+    (add)->next = (el);                                                                        \
+    (add)->prev = (el)->prev;                                                                  \
+    (el)->prev = (add);                                                                        \
+    (add)->prev->next = (add);                                                                 \
+    if ((head) == (el)) {                                                                      \
+      (head) = (add);                                                                          \
+    }                                                                                          \
+  } else {                                                                                     \
+    CDL_APPEND2(head, add, prev, next);                                                        \
+  }                                                                                            \
+} while (0)
+
+#define CDL_PREPEND_ELEM(head, el, add)                                                        \
+    CDL_PREPEND_ELEM2(head, el, add, prev, next)
+
+#define CDL_APPEND_ELEM2(head, el, add, prev, next)                                            \
+do {                                                                                           \
+ if (el) {                                                                                     \
+  assert((head) != NULL);                                                                      \
+  assert((add) != NULL);                                                                       \
+  (add)->next = (el)->next;                                                                    \
+  (add)->prev = (el);                                                                          \
+  (el)->next = (add);                                                                          \
+  (add)->next->prev = (add);                                                                   \
+ } else {                                                                                      \
+  CDL_PREPEND2(head, add, prev, next);                                                         \
+ }                                                                                             \
+} while (0)
+
+#define CDL_APPEND_ELEM(head, el, add)                                                         \
+    CDL_APPEND_ELEM2(head, el, add, prev, next)
+
+#endif /* UTLIST_H */
index 4bc1fdc..5420d98 100644 (file)
@@ -98,10 +98,9 @@ if target_os in ['linux'] and liboctbstack_env.get('SIMULATOR', False):
        liboctbstack_env.Append( RPATH = liboctbstack_env.Literal('\\$$ORIGIN'))
 
 if env.get('SECURED') == '1':
-       liboctbstack_env.AppendUnique(LIBS = ['tinydtls'])
        liboctbstack_env.AppendUnique(LIBS = ['mbedtls','mbedx509','mbedcrypto'])
 
-if target_os in ['android', 'linux', 'tizen', 'msys_nt', 'windows']:
+if target_os in ['android', 'linux', 'tizen', 'msys_nt', 'windows', 'tizenrt']:
        liboctbstack_env.PrependUnique(LIBS = ['connectivity_abstraction'])
 
        if with_ra_ibb:
@@ -134,6 +133,7 @@ else:
 
 if target_os in ['tizen', 'linux']:
        liboctbstack_env.ParseConfig("pkg-config --cflags --libs uuid")
+if target_os in ['tizen']:
        liboctbstack_env.ParseConfig('pkg-config --cflags --libs sqlite3')
 
 if target_os == 'arduino':
@@ -172,7 +172,6 @@ if 'CLIENT' in rd_mode or 'SERVER' in rd_mode:
 ######################################################################
 OCTBSTACK_SRC = 'stack/src/'
 liboctbstack_src = [
-       '../../extlibs/cjson/cJSON.c',
        '../../extlibs/timer/timer.c',
        OCTBSTACK_SRC + 'ocstack.c',
        OCTBSTACK_SRC + 'ocpayload.c',
@@ -186,8 +185,12 @@ liboctbstack_src = [
        OCTBSTACK_SRC + 'oicgroup.c'
        ]
 
+if target_os != 'tizenrt':
+        liboctbstack_src.append('../../extlibs/cjson/cJSON.c')
+
 if with_tcp == True:
        liboctbstack_src.append(OCTBSTACK_SRC + 'oickeepalive.c')
+       liboctbstack_env.UserInstallTargetHeader('stack/include/oickeepalive.h', 'resource', 'oickeepalive.h')
 
 if 'SERVER' in rd_mode:
     liboctbstack_src.append(OCTBSTACK_SRC + 'oicresourcedirectory.c')
@@ -212,7 +215,7 @@ else:
 
 octbstack_libs = Flatten(static_liboctbstack)
 
-if target_os not in ['arduino','darwin','ios'] :
+if target_os not in ['arduino','darwin','ios','tizenrt'] :
        shared_liboctbstack = liboctbstack_env.SharedLibrary('octbstack', liboctbstack_src)
        octbstack_libs += Flatten(shared_liboctbstack)
        liboctbstack_env.UserInstallTargetHeader('stack/include/ocstack.h', 'resource', 'ocstack.h')
index 85267e0..16f1377 100644 (file)
@@ -10,6 +10,7 @@ build_sample = env.get('BUILD_SAMPLE')
 with_ra = env.get('WITH_RA')
 with_tcp = env.get('WITH_TCP')
 with_mq = env.get('WITH_MQ')
+ble_custom_adv = env.get('BLE_CUSTOM_ADV')
 
 print "Given Transport is %s" % transport
 print "Given OS is %s" % target_os
@@ -56,6 +57,11 @@ else:
        if 'BLE' in transport:
                env.AppendUnique(CPPDEFINES = ['LE_ADAPTER'])
                print "CA Transport is BLE"
+               if ble_custom_adv in ['True']:
+                       env.AppendUnique(CPPDEFINES = ['BLE_CUSTOM_ADVERTISE'])
+                       print "BLE Custom advertisement supported"
+               else:
+                       print "BLE Custom advertisement not supported"
        else:
                env.AppendUnique(CPPDEFINES = ['NO_LE_ADAPTER'])
 
@@ -66,7 +72,7 @@ else:
                env.AppendUnique(CPPDEFINES = ['NO_IP_ADAPTER'])
 
        if with_tcp == True:
-               if target_os in ['linux', 'tizen', 'android', 'arduino', 'ios']:
+               if target_os in ['linux', 'tizen', 'android', 'arduino', 'ios', 'tizenrt']:
                        env.AppendUnique(CPPDEFINES = ['TCP_ADAPTER', 'WITH_TCP'])
                        print "CA Transport is TCP"
                else:
index 1f31730..fc47ed1 100755 (executable)
 #include <stdlib.h>
 #include <stdbool.h>
 
+#ifdef __TIZENRT__
+#include <poll.h>
+#else
 #ifdef HAVE_SYS_POLL_H
 #include <sys/poll.h>
 #endif
+#endif
 
 #ifdef HAVE_WINSOCK2_H
 #include <winsock2.h>
@@ -53,6 +57,15 @@ extern "C"
 #endif
 
 /**
+ * TAG of Analyzer log.
+ */
+#define ANALYZER_TAG       "OIC_CA_ANALYZER_071801"
+#define BLE_CLIENT_TAG     "OIC_CA_LE_CLIENT_0718"
+#define BLE_SERVER_MCD_TAG "OIC_CA_LE_SER_MC_0718"
+#define IP_SERVER_TAG      "OIC_CA_IP_SERVER_0718"
+#define TCP_SERVER_TAG     "OIC_CA_TCP_SERVER_0718"
+
+/**
  * IP address Length.
  */
 #define CA_IPADDR_SIZE 16
@@ -70,7 +83,7 @@ extern "C"
 /**
  * Max header options data length.
  */
-#ifdef ARDUINO
+#if defined(ARDUINO) || defined(__TIZENRT__)
 #define CA_MAX_HEADER_OPTION_DATA_LENGTH 20
 #else
 #define CA_MAX_HEADER_OPTION_DATA_LENGTH 1024
@@ -106,7 +119,12 @@ extern "C"
 /**
  *Maximum length of the remoteEndpoint identity.
  */
-#define CA_MAX_ENDPOINT_IDENTITY_LEN   (32)
+#define CA_MAX_ENDPOINT_IDENTITY_LEN  CA_MAX_IDENTITY_SIZE
+
+/**
+ * Max identity size.
+ */
+#define CA_MAX_IDENTITY_SIZE (37)
 
 /**
  * option types - the highest option number 63.
@@ -210,6 +228,17 @@ typedef enum
     CA_SCOPE_GLOBAL    = 0xE, // IPv6 Global scope
 } CATransportFlags_t;
 
+typedef enum
+{
+    CA_DEFAULT_BT_FLAGS = 0,
+    // flags for BLE transport
+    CA_LE_ADV_DISABLE   = 0x1,   // disable BLE advertisement.
+    CA_LE_ADV_ENABLE    = 0x2,   // enable BLE advertisement.
+    CA_LE_SERVER_DISABLE = (1 << 4),   // disable gatt server.
+    // flags for EDR transport
+    CA_EDR_SERVER_DISABLE = (1 << 7)   // disable rfcomm server.
+} CATransportBTFlags_t;
+
 #define CA_IPFAMILY_MASK (CA_IPV6|CA_IPV4)
 #define CA_SCOPE_MASK 0xf     // mask scope bits above
 
@@ -280,6 +309,7 @@ typedef struct
     uint16_t                port;       // for IP
     char                    addr[MAX_ADDR_STR_SIZE_CA]; // address for all
     uint32_t                ifindex;    // usually zero for default interface
+    char                    remoteId[CA_MAX_IDENTITY_SIZE]; // device ID of remote device
 #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP)
     char                    routeData[MAX_ADDR_STR_SIZE_CA]; /**< GatewayId:ClientId of
                                                                     destination. **/
@@ -345,7 +375,9 @@ typedef enum
     CA_REQUEST_ENTITY_INCOMPLETE = 408,     /**< Request Entity Incomplete */
     CA_REQUEST_ENTITY_TOO_LARGE = 413,      /**< Request Entity Too Large */
     CA_INTERNAL_SERVER_ERROR = 500,         /**< Internal Server Error */
-    CA_BAD_GATEWAY = 502,
+    CA_NOT_IMPLEMENTED = 501,               /**< Not Implenented */
+    CA_BAD_GATEWAY = 502,                   /**< Bad Gateway */
+    CA_SERVICE_UNAVAILABLE = 503,           /**< Server Unavailable */
     CA_RETRANSMIT_TIMEOUT = 504,            /**< Retransmit timeout */
     CA_PROXY_NOT_SUPPORTED = 505            /**< Proxy not enabled to service a request */
     /* Response status code - END HERE */
@@ -361,9 +393,17 @@ typedef enum
     CA_REQUEST_DATA = 1,
     CA_RESPONSE_DATA,
     CA_ERROR_DATA,
-    CA_RESPONSE_FOR_RES
+    CA_RESPONSE_FOR_RES,
+    CA_NETWORK_COMMAND
 } CADataType_t;
 
+typedef enum
+{
+    CA_DISCONNECTED = 0,
+    CA_CONNECTED,
+    CA_REQ_DISCONNECT
+} CAConnectEvent_t;
+
 /**
  * Transport Protocol IDs for additional options.
  */
@@ -439,6 +479,7 @@ typedef struct
     CAURI_t resourceUri;        /**< Resource URI information **/
     CARemoteId_t identity;      /**< endpoint identity */
     CADataType_t dataType;      /**< data type */
+    CAConnectEvent_t event;     /**< network request message / event type */
 } CAInfo_t;
 
 /**
@@ -559,8 +600,10 @@ typedef struct
 #if defined(_WIN32)
         WSAEVENT shutdownEvent;     /**< Event used to signal threads to stop */
 #else
+#ifndef __TIZENRT__
         int shutdownFds[2];         /**< fds used to signal threads to stop */
 #endif
+#endif
         int selectTimeout;          /**< in seconds */
         int maxfd;                  /**< highest fd (for select) */
         bool started;               /**< the IP adapter has started */
@@ -599,7 +642,9 @@ typedef struct
         void *svrlist;          /**< unicast IPv4 TCP server information*/
         int selectTimeout;      /**< in seconds */
         int listenBacklog;      /**< backlog counts*/
+#ifndef __TIZENRT__
         int shutdownFds[2];     /**< shutdown pipe */
+#endif
         int connectionFds[2];   /**< connection pipe */
         int maxfd;              /**< highest fd (for select) */
         bool started;           /**< the TCP adapter has started */
@@ -608,10 +653,17 @@ typedef struct
         bool ipv6tcpenabled;    /**< IPv6 TCP enabled by OCInit flags */
     } tcp;
 #endif
+    CATransportBTFlags_t bleFlags;
 } CAGlobals_t;
 
 extern CAGlobals_t caglobals;
 
+typedef enum
+{
+    CA_LOG_LEVEL_ALL = 1,             // all logs.
+    CA_LOG_LEVEL_INFO,                // debug level is disabled
+} CAUtilLogLevel_t;
+
 /**
  * Callback function type for request delivery.
  * @param[out]   object       Endpoint object from which the request is received.
index 1c2bbfa..b667766 100644 (file)
@@ -68,8 +68,11 @@ typedef struct
 /**
  * Callback function to pass the connection information from CA to RI.
  * @param[out]   object           remote device information.
+ * @param[out]   isConnected      Whether keepalive message needs to be sent.
+ * @param[out]   isClient         Host Mode of Operation.
  */
-typedef void (*CAKeepAliveConnectionCallback)(const CAEndpoint_t *object, bool isConnected);
+typedef void (*CAKeepAliveConnectionCallback)(const CAEndpoint_t *object, bool isConnected,
+                                              bool isClient);
 
 /**
  * Register connection status changes callback to process KeepAlive.
@@ -82,10 +85,10 @@ void CARegisterKeepAliveHandler(CAKeepAliveConnectionCallback ConnHandler);
  * Initialize the connectivity abstraction module.
  * It will initialize adapters, thread pool and other modules based on the platform
  * compilation options.
- *
+ * @param[in]   transportType  transport type to initialize.
  * @return  ::CA_STATUS_OK or ::CA_STATUS_FAILED or ::CA_MEMORY_ALLOC_FAILED
  */
-CAResult_t CAInitialize();
+CAResult_t CAInitialize(CATransportAdapter_t transportType);
 
 /**
  * Terminate the connectivity abstraction module.
index 9b0b5e9..736541d 100644 (file)
 #ifndef CA_SECURITY_INTERFACE_H_
 #define CA_SECURITY_INTERFACE_H_
 
-
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+#include "mbedtls/ssl.h"
+#include "mbedtls/x509_crt.h"
+#endif //__WITH_DTLS__ or __WITH_TLS__
 #include "cacommon.h"
 #include "byte_array.h"
 
@@ -50,6 +53,26 @@ typedef enum
 } CADtlsPskCredType_t;
 
 /**
+ *@enum CASslEkcbRole_t
+ * type of SSL role to be used when invoking export key callback
+ */
+typedef enum
+{
+    CA_SSL_EKCB_CLIENT = 0,
+    CA_SSL_EKCB_SERVER = 1
+}CASslEkcbRole_t;
+
+/**
+ *@enum CASslEkcbProtocol_t
+ * type of SSL protocol(TLS or DTLS) to be used when invoking export key callback
+ */
+typedef enum
+{
+    CA_SSL_EKCB_TLS = 0,
+    CA_SSL_EKCB_DTLS = 1
+}CASslEkcbProtocol_t;
+
+/**
  * This internal callback is used by CA layer to
  * retrieve PSK credentials from SRM.
  *
@@ -67,7 +90,7 @@ typedef int (*CAgetPskCredentialsHandler)(CADtlsPskCredType_t type,
               uint8_t *result, size_t result_length);
 
 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 /**
  * API to get a secure connected peer information
  *
@@ -76,7 +99,7 @@ typedef int (*CAgetPskCredentialsHandler)(CADtlsPskCredType_t type,
  * @return  secure connected peer information on success, otherwise NULL
  */
 const CASecureEndpoint_t *CAGetSecureEndpointData(const CAEndpoint_t *peer);
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 #endif
 
 /**
@@ -103,12 +126,28 @@ typedef struct
     ByteArray_t crl;
 } PkiInfo_t;
 
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+/**
+ * this callback will be invoked to utilize peer certificate information
+ */
+typedef int (*PeerCertCallback)(void *ctx, const mbedtls_x509_crt *peerCert,
+        int depth);
+
+/**
+ * API to set callback used to utilize peer certificate information
+ * @param[in] peerCertCallback callback to utilize certificate information
+ *
+ * return CA_STATUS_OK on success
+ */
+CAResult_t CAsetPeerCertCallback(void *ctx, PeerCertCallback peerCertCallback);
+#endif
+
 /**
  * Register callback to receive credential types.
  * @param[in] credTypesCallback callback to get cerdential types
  * @return ::CA_STATUS_OK
  */
-CAResult_t CAregisterGetCredentialTypesCallback(CAgetCredentialTypesHandler credTypesCallback);
+CAResult_t CAregisterGetCredentialTypesHandler(CAgetCredentialTypesHandler credTypesCallback);
 /**
  * Register callback to receive the result of TLS handshake.
  * @param[in] tlsHandshakeCallback callback for get tls handshake result
@@ -132,6 +171,24 @@ CAResult_t CAregisterPskCredentialsHandler(CAgetPskCredentialsHandler getTlsCred
  */
 typedef void (*CAgetPkixInfoHandler)(PkiInfo_t * inf);
 
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+/**
+ * @brief   Callback function type for setup PK context
+ *
+ * @param   pkCtx[in]   mbedtls's PK context
+ *
+ * @return  0 on success
+ */
+typedef int (*CAsetupPkContextHandler)(mbedtls_pk_context * pkCtx);
+
+/**
+ * Register callback to setup PK Context
+ * @param[in]   setupPkContextCallback    Callback function to setup PK context.
+ * @return  ::CA_STATUS_OK or appropriate error code.
+ */
+CAResult_t CAregisterSetupPkContextHandler(CAsetupPkContextHandler setupPkContextHandler);
+#endif //__WITH_DTLS__ or __WITH_TLS__
+
 /**
  * Register callback to get PKIX related info.
  * @param[in]   getPkixInfoHandler    Get PKIX related info callback.
@@ -149,9 +206,17 @@ CAResult_t CAregisterGetCredentialTypesHandler(CAgetCredentialTypesHandler getCr
  * Select the cipher suite for dtls handshake.
  *
  * @param[in] cipher  cipher suite (Note : Make sure endianness).
- *                    0xC018 : TLS_ECDH_anon_WITH_AES_128_CBC_SHA
- *                    0xC0A8 : TLS_PSK_WITH_AES_128_CCM_8
- *                    0xC0AE : TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
+ *                        TLS_RSA_WITH_AES_256_CBC_SHA256          0x3D
+ *                        TLS_RSA_WITH_AES_128_GCM_SHA256          0x009C
+ *                        TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256  0xC02B
+ *                        TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8       0xC0AE
+ *                        TLS_ECDHE_ECDSA_WITH_AES_128_CCM         0xC0AC
+ *                        TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256  0xC023
+ *                        TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384  0xC024
+ *                        TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384  0xC02C
+ *                        TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256    0xC037
+ *                        TLS_ECDH_anon_WITH_AES_128_CBC_SHA       0xC018
+ * @param[in] adapter  transport adapter (TCP/IP/BLE)
  *
  * @retval  ::CA_STATUS_OK    Successful.
  * @retval  ::CA_STATUS_INVALID_PARAM  Invalid input arguments.
@@ -239,11 +304,58 @@ CAResult_t CAinitiateSslHandshake(const CAEndpoint_t *endpoint);
  */
 CAResult_t CAcloseSslConnection(const CAEndpoint_t *endpoint);
 
+/**
+ * Close the TLS session using UUID
+ *
+ * @param[in] identity  UUID of target device
+ * @param[in] idLength Byte length of 'identity'
+ *
+ * @retval  ::CA_STATUS_OK    Successful.
+ * @retval  ::CA_STATUS_FAILED Operation failed.
+ */
+CAResult_t CAcloseSslConnectionUsingUuid(const uint8_t *identity, size_t idLength);
 
 /**
  * Close All of DTLS sessions.
  */
-void CAcloseSslConnectionAll();
+void CAcloseSslConnectionAll(CATransportAdapter_t transportType);
+
+#if defined(__WITH_TLS__) || defined(__WITH_DTLS__)
+
+/**
+ * @brief           Callback type: Export key block and master secret
+ * @note            This is required for certain uses of TLS, e.g. EAP-TLS
+ *                  (RFC 5216) and Thread. The key pointers are ephemeral and
+ *                  therefore must not be stored. The master secret and keys
+ *                  should not be used directly except as an input to a key
+ *                  derivation function.
+ *
+ * @aram[in] masterSecret        Pointer to master secret (fixed length: 48 bytes)
+ * @param[in] keyBlock        Pointer to key block, see RFC 5246 section 6.3
+ *                  (variable length: 2 * maclen + 2 * keylen + 2 * ivlen).
+ * @param[in] maclen    MAC length
+ * @param[in] keylen    Key length
+ * @param[in] ivlen     IV length
+ */
+typedef void (*SslExportKeysCallback_t)(const unsigned char* masterSecret,
+                                        const unsigned char* keyBlock,
+                                        size_t macLen, size_t keyLen, size_t ivLen);
+
+/**
+ * API to set a export SSL(TLS/DTLS) key callback.
+ * This callback will be invoked when SSL handshake occured.
+ *
+ * @param[in] exportKeysCb implementation of SslExportKeysCallback_t
+ * @param[in] protocol CA_SSL_EKCB_TLS=TLS, CA_SSL_EKCB_DTLS=DTLS (@ref CASslEkcbProtocol_t)
+ * @param[in] role CA_SSL_EKCB_CLIENT=client, CA_SSL_EKCB_SERVER=server (@ref CASslEkcbRole_t)
+ *
+ * @return CA_STATUS_OK on success, otherwise fail.
+ */
+CAResult_t CASetSslExportKeysCallback(SslExportKeysCallback_t exportKeysCb,
+                                      CASslEkcbProtocol_t protocol, CASslEkcbRole_t role);
+
+#endif //__WITH_TLS__ or __WITH_DTLS__
+
 
 #ifdef __cplusplus
 } /* extern "C" */
index 47d840a..15727ff 100644 (file)
@@ -31,6 +31,37 @@ extern "C"
 #endif
 
 /**
+ * this level depends on transmission time.
+ * unicast based UDP will be checked by caretransmission.
+ */
+typedef enum
+{
+    HIGH_SPEED = 0,
+    NORMAL_SPEED
+} CMSpeedLevel_t;
+
+typedef struct
+{
+    /** address for all **/
+    char addr[MAX_ADDR_STR_SIZE_CA];
+
+    /** adapter priority of all transmissions. **/
+    CATransportAdapter_t adapter;
+
+    /** level about speed of response. **/
+    CMSpeedLevel_t level;
+} CMConfigureInfo_t;
+
+/*
+ * CAUtilConfig_t structure.
+ */
+typedef struct
+{
+    CATransportBTFlags_t bleFlags;
+    CMConfigureInfo_t cmInfo;
+} CAUtilConfig_t;
+
+/**
  * Callback function type for connection status changes delivery.
  * @param[out]   info           Remote endpoint information.
  * @param[out]   isConnected    Current connection status info.
@@ -101,6 +132,42 @@ CAResult_t CASetPortNumberToAssign(CATransportAdapter_t adapter,
  */
 uint16_t CAGetAssignedPortNumber(CATransportAdapter_t adapter, CATransportFlags_t flag);
 
+//custom advertisement data setting
+#if defined(__TIZEN__) && defined(LE_ADAPTER) && defined(BLE_CUSTOM_ADVERTISE)
+CAResult_t CASetAdvertisementData(const char* data, int length);
+CAResult_t CASetScanResponseData(const char* data, int length);
+#endif
+
+#ifdef __APPLE__
+/**
+ * initialize client connection manager
+ */
+CAResult_t CAUtilClientInitialize();
+
+/**
+ * terminate client connection manager
+ */
+CAResult_t CAUtilClientTerminate();
+
+/**
+ * stop LE scan.
+ * @return  ::CA_STATUS_OK or ::CA_NOT_SUPPORTED
+ */
+CAResult_t CAUtilStopLEScan();
+
+/**
+ * start LE scan.
+ * @return  ::CA_STATUS_OK or ::CA_NOT_SUPPORTED
+ */
+CAResult_t CAUtilStartLEScan();
+
+/**
+ * Client disconnect.
+ * @return  ::CA_STATUS_OK or ::CA_NOT_SUPPORTED
+ */
+CAResult_t CAUtilClientDisconnect();
+#endif
+
 #ifdef __ANDROID__
 /**
  * initialize util client for android
@@ -152,12 +219,89 @@ void CAUtilSetFoundDeviceListener(jobject listener);
  * @param[in]  intervalTime         interval time(Seconds).
  * @param[in]  workingCount         working cycle for selected interval time.
  *
- * @return  ::CA_STATUS_OK or ::CA_STATUS_FAILED or ::CA_MEMORY_ALLOC_FAILED
+ * @return  ::CA_STATUS_OK or ::CA_NOT_SUPPORTED
  */
 CAResult_t CAUtilSetLEScanInterval(jint intervalTime, jint workingCount);
 
+/**
+ * stop LE scan.
+ *
+ * @return  ::CA_STATUS_OK or ::CA_NOT_SUPPORTED
+ */
+CAResult_t CAUtilStopLEScan();
 #endif
 
+// BLE util
+/**
+ * start BLE advertising.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CAUtilStartLEAdvertising();
+
+/**
+ * stop BLE advertising.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CAUtilStopLEAdvertising();
+
+/**
+ * set CAUtil BT configure.
+ * @param[in]  config       ::CAUtilConfig_t value
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CAUtilSetBTConfigure(CAUtilConfig_t config);
+
+/**
+ * set CAUtil log preference.
+ * @param[in]  level                     ::CAUtilLogLevel_t value
+ * @param[in]  hidePrivateLogEntries     Private Log Entries.
+ *                                       Example:
+ *                                       true : hide private log.
+ *                                       false : show private log.
+ *                                       (privacy : uid, did, access token, etc)
+ */
+void CAUtilSetLogLevel(CAUtilLogLevel_t level, bool hidePrivateLogEntries);
+
+/**
+ * Set multicast time to live value to control the scope of the multicasts.
+ * @param[in]  ttl         To be set to any value from 0 to 255.
+ *                         Example:
+ *                         0: Are restricted to the same host.
+ *                         1: Are restricted to the same subnet.
+ *                         32: Are restricted to the same site.
+ *                         64: Are restricted to the same region.
+ *                         128: Are restricted to the same continent.
+ *                         255: Are unrestricted in scope.
+ *                         We cannot support region, continent and unrestricted in scope.
+ *
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CAUtilSetMulticastTTL(size_t ttl);
+
+/**
+ * Get multicast time to live value.
+ * @param[out]  ttl        TTL pointer to get the stored multicast time to live.
+ *
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CAUtilGetMulticastTTL(size_t *ttl);
+
+/**
+ * Disconnect TCP session.
+ * When there is no transmission for a long time.
+ * Some carrier Vendor is blocking data.
+ * Thur, TCP Session is cleaned through this function.
+ * @param[in]   address        Address.
+ * @param[in]   port           Port.
+ * @param[in]   flags          Transport flag.
+ */
+CAResult_t CAUtilTCPDisconnectSession(const char *address,
+                                      uint16_t port,
+                                      CATransportFlags_t flags);
+
+CAResult_t CAUtilStartGattServer();
+CAResult_t CAUtilStopGattServer();
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
index efbf64f..1f255a1 100644 (file)
@@ -23,7 +23,6 @@ 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
 OIC_C_COMMON_PATH           = $(ROOT_DIR_PATH)/resource/c_common
 #GLIB_PATH                  = ../../../../../../extlibs/glib/glib-2.40.2
 
@@ -47,12 +46,6 @@ BUILD_FLAG.release      =       $(DEFINE_FLAG)
 BUILD_FLAG = $(BUILD_FLAG.$(BUILD))
 
 #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-#Build TinyDtls
-
-include $(CLEAR_VARS)
-include $(DTLS_LIB)/Android.mk
-
-#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 #Build OIC C Common libraries required for CA
 
 include $(CLEAR_VARS)
@@ -131,7 +124,7 @@ LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog
 LOCAL_PATH = $(PROJECT_SRC_PATH)
 LOCAL_MODULE = CA
 
-LOCAL_STATIC_LIBRARIES = CACommon CACoap TinyDtls
+LOCAL_STATIC_LIBRARIES = CACommon CACoap
 
 LOCAL_C_INCLUDES = $(PROJECT_API_PATH)
 LOCAL_C_INCLUDES += $(PROJECT_COMMON_INC_PATH)
index 2449860..10f5e06 100644 (file)
@@ -18,13 +18,10 @@ 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 dlog capi-network-bluetooth glib-2.0`
+COMPILEFLAG = `pkg-config --cflags --libs dlog ttrace capi-network-bluetooth glib-2.0`
 
 # Include files will be copied into a single folder on gbsbuild.
 # NO NEED to mention the path explicitly.
index 458e227..772cc8e 100755 (executable)
@@ -54,7 +54,6 @@ cp -R $cur_dir/samples/tizen/ $sourcedir/tmp/con/sample/
 mkdir -p $sourcedir/tmp/con/sample/external/inc
 cp -R $cur_dir/external/inc/* $sourcedir/tmp/con/sample/external/inc/
 
-cp -R ./extlibs/tinydtls/ $sourcedir/tmp/con/extlibs/
 cp -R ./extlibs/mbedtls/ $sourcedir/tmp/con/mbedtls/
 cp -R ./extlibs/timer/ $sourcedir/tmp/con/extlibs/
 cp -R ./extlibs/libcoap/ $sourcedir/tmp/con/extlibs/
index 852c3c1..de7a474 100644 (file)
@@ -28,8 +28,12 @@ Source0: http://mirrors.kernel.org/%{name}/%{version}/%{name}-%{version}.tar.gz
 %{!?TARGET_TRANSPORT: %define TARGET_TRANSPORT IP}
 %{!?VERBOSE: %define VERBOSE 1}
 %{!?WITH_TCP: %define WITH_TCP 0}
+%{!?OIC_SUPPORT_TIZEN_TRACE: %define OIC_SUPPORT_TIZEN_TRACE False}
 
 BuildRequires: pkgconfig(dlog)
+%if "%{OIC_SUPPORT_TIZEN_TRACE}" == "True"
+BuildRequires:  pkgconfig(ttrace)
+%endif
 BuildRequires: pkgconfig(glib-2.0)
 BuildRequires: pkgconfig(capi-network-connection)
 BuildRequires: pkgconfig(capi-network-bluetooth)
@@ -56,6 +60,7 @@ scons %{JOB} \
     TARGET_TRANSPORT=%{TARGET_TRANSPORT} \
     VERBOSE=%{VERBOSE} \
     WITH_TCP=%{WITH_TCP} \
+    OIC_SUPPORT_TIZEN_TRACE=%{OIC_SUPPORT_TIZEN_TRACE} \
     #eol
 
 
@@ -66,10 +71,9 @@ mkdir -p %{DEST_LIB_DIR}/pkgconfig
 cp -f %{ROOTDIR}/con/src/libconnectivity_abstraction.so %{buildroot}/%{_libdir}
 cp -f %{ROOTDIR}/extlibs/libcoap/libcoap.a %{buildroot}/%{_libdir}
 if echo %{SECURED}|grep -qi '1'; then
-       cp -f %{ROOTDIR}/con/extlibs/tinydtls/libtinydtls.a %{buildroot}/%{_libdir}
        cp -f %{ROOTDIR}/con/extlibs/mbedtls/libmbedcrypto.a %{buildroot}/%{_libdir}
-       cp -f %{ROOTDIR}/con/extlibs/tinydtls/libmbedtls.a %{buildroot}/%{_libdir}
-       cp -f %{ROOTDIR}/con/extlibs/tinydtls/libmbedx509.a %{buildroot}/%{_libdir}
+       cp -f %{ROOTDIR}/con/extlibs/mbedtls/libmbedtls.a %{buildroot}/%{_libdir}
+       cp -f %{ROOTDIR}/con/extlibs/mbedtls/libmbedx509.a %{buildroot}/%{_libdir}
 fi
 cp -rf %{ROOTDIR}/con/api/cacommon.h* %{DEST_INC_DIR}/
 cp -rf %{ROOTDIR}/con/inc/caadapterinterface.h* %{DEST_INC_DIR}/
index a6ae41e..621a39d 100644 (file)
@@ -21,6 +21,9 @@ if env.get('LOGGING'):
     env.AppendUnique(CPPDEFINES = ['TB_LOG'])
 
 env.ParseConfig("pkg-config --cflags --libs capi-network-connection dlog glib-2.0")
+if env.get('OIC_SUPPORT_TIZEN_TRACE') == 'True':
+    env.ParseConfig("pkg-config --cflags --libs ttrace")
+
 if 'ALL' in transport:
                env.AppendUnique(CPPDEFINES = ['WIFI_ADAPTER', 'NO_ETHERNET_ADAPTER','EDR_ADAPTER','LE_ADAPTER'])
                print "CA Transport is ALL"
index 4db7d47..3cdeef1 100644 (file)
@@ -15,6 +15,7 @@ ca_common_path = root_dir + 'common/'
 ca_common_src_path = ca_common_path + 'src/'
 
 env.AppendUnique(CPPPATH = [
+       '#resource/c_common/octhread/include/',
        'common/inc/',
        src_dir + '/resource/csdk/logger/include/',
        ])
@@ -29,16 +30,12 @@ ca_common_src = [
                ca_common_src_path + 'caremotehandler.c'
        ]
 
-if env['POSIX_SUPPORTED'] or (ca_os in ['windows']):
+if env['POSIX_SUPPORTED'] or ca_os in ['windows']:
        platform_src = [
                ca_common_src_path + 'cathreadpool_pthreads.c',
-               ca_common_src_path + 'camutex_pthreads.c'
        ]
 else:
-       platform_src = [
-               ca_common_src_path + 'camutex_noop.c'
-               ]
-
+       platform_src = []
 
 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
deleted file mode 100644 (file)
index 5a1c00f..0000000
+++ /dev/null
@@ -1,144 +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
- *
- * 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);
-
-/**
- * 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_TIMEDOUT 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_ */
index 9df11e9..ef59413 100644 (file)
@@ -67,12 +67,29 @@ CAResult_t ca_thread_pool_init(int32_t num_of_threads, ca_thread_pool_t *thread_
  * @param thread_pool The thread pool structure.
  * @param method The routine to be executed.
  * @param data The data to be passed to the routine.
+ * @param taskId An unique identifier of task.
  *
  * @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);
+#ifndef __TIZENRT__
+CAResult_t ca_thread_pool_add_task(ca_thread_pool_t thread_pool, ca_thread_func method, void *data,
+                                   uint32_t *taskId);
+#else
+CAResult_t ca_thread_pool_add_task(ca_thread_pool_t thread_pool, ca_thread_func method, void *data,
+                                   uint32_t *taskId, const char *task_name, int stack_size);
+#endif
+
+/**
+ * This function removes a routine to be executed by the thread pool.
+ *
+ * @param thread_pool The thread pool structure.
+ * @param taskId An unique identifier of task.
+ *
+ * @return CA_STATUS_OK on success.
+ * @return Error on failure.
+ */
+CAResult_t ca_thread_pool_remove_task(ca_thread_pool_t thread_pool, uint32_t taskId);
 
 /**
  * This function stops all the worker threads (stop & exit). And frees all the allocated memory.
index 31a70f6..cf1085b 100644 (file)
@@ -68,8 +68,9 @@ void u_arraylist_free(u_arraylist_t **list);
  * entries.
  * @param list the list to operate on.
  * @param count the size to attempt to reserve room for.
+ * @return true if success, false otherwise.
  */
-void u_arraylist_reserve(u_arraylist_t *list, size_t count);
+bool u_arraylist_reserve(u_arraylist_t *list, size_t count);
 
 /**
  * Request that the storage in the list be reduced to fit its current length.
@@ -88,6 +89,15 @@ void u_arraylist_shrink_to_fit(u_arraylist_t *list);
 void *u_arraylist_get(const u_arraylist_t *list, uint32_t index);
 
 /**
+ * Returns the index of the data from the array list.
+ * @param[in] list         pointer of array list.
+ * @param[in] data         pointer of data.
+ * @param[out]index        index of array list.
+ * @return true if success, false otherwise.
+ */
+bool u_arraylist_get_index(const u_arraylist_t *list, const void *data,  uint32_t *index);
+
+/**
  * Add data in the array list.
  * @param[in] list        pointer of array list.
  * @param[in] data        pointer of data.
index 724c3f2..4079b40 100644 (file)
@@ -125,6 +125,22 @@ CAResult_t u_queue_reset(u_queue_t *queue);
  */
 u_queue_message_t *u_queue_get_head(u_queue_t *queue);
 
+/** Data destroy function. **/
+typedef void (*QueueDataDestroyFunction)(void *data, uint32_t size);
+typedef bool (*QueueContextDataDestroy)(void *data, uint32_t size, void *ctx);
+
+/**
+ * Removes messages from anywhere in the queue
+ * @param queue     pointer to queue
+ * @param callback  Function returns true if element is to be destroyed
+ * @param ctx       data that should be passed to callback
+ * @param destroy   Function to destroy the data, if NULL OICFree will be used
+ * @return ::CA_STATUS_OK if Success, ::CA_STATUS_FAILED otherwise
+ */
+CAResult_t u_queue_remove_req_elements(u_queue_t *queue,
+                                       QueueContextDataDestroy callback, void *ctx,
+                                       QueueDataDestroyFunction destroy);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif /* __cplusplus */
index 6a7fea2..deccb3d 100644 (file)
@@ -115,11 +115,16 @@ CAResponseInfo_t *CACloneResponseInfo(const CAResponseInfo_t *rep)
         case CA_BAD_OPT:
         case CA_FORBIDDEN_REQ:
         case CA_NOT_FOUND:
+        case CA_METHOD_NOT_ALLOWED:
         case CA_NOT_ACCEPTABLE:
         case CA_REQUEST_ENTITY_INCOMPLETE:
         case CA_REQUEST_ENTITY_TOO_LARGE:
         case CA_INTERNAL_SERVER_ERROR:
+        case CA_NOT_IMPLEMENTED:
+        case CA_BAD_GATEWAY:
+        case CA_SERVICE_UNAVAILABLE:
         case CA_RETRANSMIT_TIMEOUT:
+        case CA_PROXY_NOT_SUPPORTED:
             break;
         default:
             OIC_LOG_V(ERROR, TAG, "Response code  %u is invalid", rep->result);
index 7157005..8d143e7 100644 (file)
@@ -29,9 +29,6 @@
 #endif
 #include "iotivity_config.h"
 #include <errno.h>
-#if defined HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
 #if defined HAVE_WINSOCK2_H
 #include <winsock2.h>
 #endif
@@ -39,7 +36,8 @@
 #include "logger.h"
 #include "oic_malloc.h"
 #include "uarraylist.h"
-#include "camutex.h"
+#include "octhread.h"
+#include "ocrandom.h"
 #include "platform_features.h"
 
 #define TAG PCF("UTHREADPOOL")
@@ -51,7 +49,7 @@
 typedef struct ca_thread_pool_details_t
 {
     u_arraylist_t* threads_list;
-    ca_mutex list_lock;
+    oc_mutex list_lock;
 } ca_thread_pool_details_t;
 
 /**
@@ -64,6 +62,12 @@ typedef struct ca_thread_pool_callback_info_t
     void* data;
 } ca_thread_pool_callback_info_t;
 
+typedef struct ca_thread_pool_thread_info_t
+{
+    oc_thread thread;
+    uint32_t taskId;
+} ca_thread_pool_thread_info_t;
+
 // passthrough function to convert the pthreads call to a u_thread_func call
 void* ca_thread_pool_pthreads_delegate(void* data)
 {
@@ -111,7 +115,7 @@ CAResult_t ca_thread_pool_init(int32_t num_of_threads, ca_thread_pool_t *thread_
         return CA_MEMORY_ALLOC_FAILED;
     }
 
-    (*thread_pool)->details->list_lock = ca_mutex_new();
+    (*thread_pool)->details->list_lock = oc_mutex_new();
 
     if(!(*thread_pool)->details->list_lock)
     {
@@ -124,7 +128,7 @@ CAResult_t ca_thread_pool_init(int32_t num_of_threads, ca_thread_pool_t *thread_
     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))
+        if(!oc_mutex_free((*thread_pool)->details->list_lock))
         {
             OIC_LOG(ERROR, TAG, "Failed to free thread-pool mutex");
         }
@@ -141,10 +145,15 @@ exit:
     return CA_STATUS_FAILED;
 }
 
-CAResult_t ca_thread_pool_add_task(ca_thread_pool_t thread_pool, ca_thread_func method,
-                                    void *data)
+#ifndef __TIZENRT__
+CAResult_t ca_thread_pool_add_task(ca_thread_pool_t thread_pool, ca_thread_func method, void *data,
+                                   uint32_t *taskId)
+#else
+CAResult_t ca_thread_pool_add_task(ca_thread_pool_t thread_pool, ca_thread_func method, void *data,
+                                   uint32_t *taskId, const char *task_name, int stack_size)
+#endif
 {
-    OIC_LOG(DEBUG, TAG, "IN");
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
 
     if(NULL == thread_pool || NULL == method)
     {
@@ -162,81 +171,132 @@ CAResult_t ca_thread_pool_add_task(ca_thread_pool_t thread_pool, ca_thread_func
     info->func = method;
     info->data = data;
 
-    pthread_t threadHandle;
-    int result = pthread_create(&threadHandle, NULL, ca_thread_pool_pthreads_delegate, info);
-
-    if(result != 0)
+    ca_thread_pool_thread_info_t *threadInfo =
+            (ca_thread_pool_thread_info_t *) OICCalloc(1, sizeof(ca_thread_pool_thread_info_t));
+    if (!threadInfo)
     {
-        OIC_LOG_V(ERROR, TAG, "Thread start failed with error %d", result);
+        OIC_LOG(ERROR, TAG, "Memory allocation failed");
+        OICFree(info);
         return CA_STATUS_FAILED;
     }
+    threadInfo->taskId = OCGetRandom();
+    if (taskId)
+    {
+        *taskId = threadInfo->taskId;
+    }
 
-    ca_mutex_lock(thread_pool->details->list_lock);
-    bool addResult = u_arraylist_add(thread_pool->details->threads_list, (void*)threadHandle);
-    ca_mutex_unlock(thread_pool->details->list_lock);
-
+    oc_mutex_lock(thread_pool->details->list_lock);
+    bool addResult = u_arraylist_add(thread_pool->details->threads_list, (void*) threadInfo);
     if (!addResult)
     {
-        OIC_LOG_V(ERROR, TAG, "Arraylist Add failed, may not be properly joined: %d", addResult);
-#if defined(_WIN32)
-        DWORD joinres = WaitForSingleObject(threadHandle, INFINITE);
-        if (WAIT_OBJECT_0 != joinres)
-        {
-            OIC_LOG_V(ERROR, TAG, "Failed to join thread with error %d", joinres);
-        }
-        CloseHandle(threadHandle);
+        // Note that this is considered non-fatal.
+        oc_mutex_unlock(thread_pool->details->list_lock);
+        OIC_LOG(ERROR, TAG, "Arraylist add failed");
+        OICFree(info);
+        OICFree(threadInfo);
+        return CA_STATUS_FAILED;
+    }
+
+#ifndef __TIZENRT__
+    int thrRet = oc_thread_new(&threadInfo->thread, ca_thread_pool_pthreads_delegate, info);
 #else
-        int joinres = pthread_join(threadHandle, NULL);
-        if (0 != joinres)
+    int thrRet = oc_thread_new(&threadInfo->thread, ca_thread_pool_pthreads_delegate, info,
+                               task_name, stack_size);
+#endif
+    if (thrRet != 0)
+    {
+        uint32_t index = 0;
+        if (u_arraylist_get_index(thread_pool->details->threads_list, threadInfo, &index))
         {
-            OIC_LOG_V(ERROR, TAG, "Failed to join thread with error %d", joinres);
+            u_arraylist_remove(thread_pool->details->threads_list, index);
         }
-#endif
+        oc_mutex_unlock(thread_pool->details->list_lock);
+        OIC_LOG_V(ERROR, TAG, "Thread start failed with error %d", thrRet);
+        OICFree(info);
         return CA_STATUS_FAILED;
     }
+    OIC_LOG_V(DEBUG, TAG, "created taskId: %u", threadInfo->taskId);
+    oc_mutex_unlock(thread_pool->details->list_lock);
 
-    OIC_LOG(DEBUG, TAG, "OUT");
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+    return CA_STATUS_OK;
+}
+
+CAResult_t ca_thread_pool_remove_task(ca_thread_pool_t thread_pool, uint32_t taskId)
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+
+    if (!thread_pool)
+    {
+        OIC_LOG(ERROR, TAG, "Invalid parameter thread_pool was NULL");
+        return CA_STATUS_FAILED;
+    }
+
+    oc_mutex_lock(thread_pool->details->list_lock);
+    for (uint32_t i = 0; i < u_arraylist_length(thread_pool->details->threads_list); ++i)
+    {
+        ca_thread_pool_thread_info_t *threadInfo = (ca_thread_pool_thread_info_t *)
+                u_arraylist_get(thread_pool->details->threads_list, i);
+        if (threadInfo)
+        {
+            if (threadInfo->taskId == taskId)
+            {
+                OIC_LOG_V(INFO, TAG, "waiting.. taskId: %u", threadInfo->taskId);
+                oc_thread_wait(threadInfo->thread);
+
+                OIC_LOG_V(DEBUG, TAG, "removed taskId: %u", threadInfo->taskId);
+                u_arraylist_remove(thread_pool->details->threads_list, i);
+                oc_thread_free(threadInfo->thread);
+                OICFree(threadInfo);
+                break;
+            }
+        }
+    }
+    oc_mutex_unlock(thread_pool->details->list_lock);
+
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
     return CA_STATUS_OK;
 }
 
 void ca_thread_pool_free(ca_thread_pool_t thread_pool)
 {
-    OIC_LOG(DEBUG, TAG, "IN");
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
 
-    if(!thread_pool)
+    if (!thread_pool)
     {
         OIC_LOG(ERROR, TAG, "Invalid parameter thread_pool was NULL");
         return;
     }
 
-    ca_mutex_lock(thread_pool->details->list_lock);
+    oc_mutex_lock(thread_pool->details->list_lock);
 
-    for(uint32_t i = 0; i<u_arraylist_length(thread_pool->details->threads_list); ++i)
+    for (uint32_t i = 0; i < u_arraylist_length(thread_pool->details->threads_list); ++i)
     {
-        pthread_t tid = (pthread_t)u_arraylist_get(thread_pool->details->threads_list, i);
-#if defined(_WIN32)
-        DWORD joinres = WaitForSingleObject(tid, INFINITE);
-        if (WAIT_OBJECT_0 != joinres)
-        {
-            OIC_LOG_V(ERROR, TAG, "Failed to join thread at index %u with error %d", i, joinres);
-        }
-        CloseHandle(tid);
-#else
-        int joinres = pthread_join(tid, NULL);
-        if(0 != joinres)
+        ca_thread_pool_thread_info_t *threadInfo = (ca_thread_pool_thread_info_t *)
+                u_arraylist_get(thread_pool->details->threads_list, i);
+        if (threadInfo)
         {
-            OIC_LOG_V(ERROR, TAG, "Failed to join thread at index %u with error %d", i, joinres);
-        }
+            if (threadInfo->thread)
+            {
+#ifdef __TIZEN__
+                OIC_LOG_V(INFO, TAG, "canceling.. thread: %p", threadInfo->thread);
+                oc_thread_cancel(threadInfo->thread);
 #endif
+                OIC_LOG_V(INFO, TAG, "waiting.. thread: %p", threadInfo->thread);
+                oc_thread_wait(threadInfo->thread);
+                oc_thread_free(threadInfo->thread);
+            }
+            OICFree(threadInfo);
+        }
     }
 
     u_arraylist_free(&(thread_pool->details->threads_list));
 
-    ca_mutex_unlock(thread_pool->details->list_lock);
-    ca_mutex_free(thread_pool->details->list_lock);
+    oc_mutex_unlock(thread_pool->details->list_lock);
+    oc_mutex_free(thread_pool->details->list_lock);
 
     OICFree(thread_pool->details);
     OICFree(thread_pool);
 
-    OIC_LOG(DEBUG, TAG, "OUT");
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
 }
index b6aef02..b795f10 100644 (file)
@@ -66,7 +66,7 @@ void u_arraylist_free(u_arraylist_t **list)
     *list = NULL;
 }
 
-void u_arraylist_reserve(u_arraylist_t *list, size_t count)
+bool u_arraylist_reserve(u_arraylist_t *list, size_t count)
 {
     if (list && (count > list->capacity))
     {
@@ -74,7 +74,7 @@ void u_arraylist_reserve(u_arraylist_t *list, size_t count)
         if (!tmp)
         {
             OIC_LOG(DEBUG, TAG, "Memory reallocation failed.");
-            // Note that this is considered non-fatal.
+            return false;
         }
         else
         {
@@ -82,6 +82,7 @@ void u_arraylist_reserve(u_arraylist_t *list, size_t count)
             list->capacity = count;
         }
     }
+    return true;
 }
 
 void u_arraylist_shrink_to_fit(u_arraylist_t *list)
@@ -124,6 +125,25 @@ void *u_arraylist_get(const u_arraylist_t *list, uint32_t index)
     return NULL;
 }
 
+bool u_arraylist_get_index(const u_arraylist_t *list, const void *data, uint32_t *index)
+{
+    if (!list || !data)
+    {
+        return false;
+    }
+
+    for (uint32_t i = 0; i < list->length; i++)
+    {
+        if (data == list->data[i])
+        {
+            *index = i;
+            return true;
+        }
+    }
+
+    return false;
+}
+
 bool u_arraylist_add(u_arraylist_t *list, void *data)
 {
     if (!list)
index 5464ea8..3124234 100644 (file)
@@ -245,3 +245,58 @@ u_queue_message_t *u_queue_get_head(u_queue_t *queue)
     return queue->element->message;
 }
 
+CAResult_t u_queue_remove_req_elements(u_queue_t *queue,
+                                       QueueContextDataDestroy callback, void *ctx,
+                                       QueueDataDestroyFunction destroy)
+{
+    if (NULL == queue)
+    {
+        OIC_LOG(DEBUG, TAG, "QueueRemoveReqElement FAIL, Invalid Queue");
+        return CA_STATUS_FAILED;
+    }
+
+    if (NULL == callback)
+    {
+        OIC_LOG(DEBUG, TAG, "QueueRemoveReqElement FAIL, NULL callback");
+        return CA_STATUS_FAILED;
+    }
+
+    u_queue_element *cur = queue->element;
+    u_queue_element *prev = NULL;
+    u_queue_element *remove = NULL;
+
+    while (NULL != cur)
+    {
+        if (cur->message && callback(cur->message->msg, cur->message->size, ctx))
+        {
+            remove = cur;
+            if (NULL != prev)
+            {
+                prev->next = cur->next;
+            }
+            else
+            {
+                queue->element = cur->next;
+            }
+            cur = cur->next;
+            if (NULL != destroy)
+            {
+                destroy(remove->message->msg, remove->message->size);
+            }
+            else
+            {
+                OICFree(remove->message->msg);
+            }
+            OICFree(remove->message);
+            OICFree(remove);
+            queue->count--;
+        }
+        else
+        {
+            prev = cur;
+            cur = cur->next;
+        }
+    }
+    return CA_STATUS_OK;
+}
+
index d189fb3..cc9e8d5 100644 (file)
 extern "C" {
 #endif //__cplusplus
 
-#include "caadapterutils.h"
-#include "cainterface.h"
+#include "cacommon.h"
+#include "casecurityinterface.h"
 
 /**
- * Currently TLS supported adapters(2) WIFI and ETHENET for linux platform.
+ * Currently TLS supported adapters(3) WIFI, ETHENET and BLE for linux platform.
  */
-#define MAX_SUPPORTED_ADAPTERS 2
+#define MAX_SUPPORTED_ADAPTERS 3
 
-typedef void (*CAPacketReceivedCallback)(const CASecureEndpoint_t *sep,
+typedef CAResult_t (*CAPacketReceivedCallback)(const CASecureEndpoint_t *sep,
                                          const void *data, size_t dataLength);
 
 typedef ssize_t (*CAPacketSendCallback)(CAEndpoint_t *endpoint,
@@ -42,9 +42,16 @@ typedef ssize_t (*CAPacketSendCallback)(CAEndpoint_t *endpoint,
  * Select the cipher suite for dtls handshake
  *
  * @param[in] cipher    cipher suite
- *                             0xC018 : TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256
- *                             0xC0A8 : TLS_PSK_WITH_AES_128_CCM_8
- *                             0xC0AE : TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
+ *                        TLS_RSA_WITH_AES_256_CBC_SHA256          0x3D
+ *                        TLS_RSA_WITH_AES_128_GCM_SHA256          0x009C
+ *                        TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256  0xC02B
+ *                        TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8       0xC0AE
+ *                        TLS_ECDHE_ECDSA_WITH_AES_128_CCM         0xC0AC
+ *                        TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256  0xC023
+ *                        TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384  0xC024
+ *                        TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384  0xC02C
+ *                        TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256    0xC037
+ *                        TLS_ECDH_anon_WITH_AES_128_CBC_SHA       0xC018
  *
  * @retval  ::CA_STATUS_OK for success, otherwise some error value
  */
@@ -172,7 +179,7 @@ CAResult_t CAsslGenerateOwnerPsk(const CAEndpoint_t *endpoint,
                     const uint8_t* provServerDeviceId, const size_t provServerDeviceIdLen,
                     uint8_t* ownerPsk, const size_t ownerPskSize);
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 /**
  * Gets CA secure endpoint info corresponding for endpoint.
  *
@@ -183,6 +190,8 @@ CAResult_t CAsslGenerateOwnerPsk(const CAEndpoint_t *endpoint,
 const CASecureEndpoint_t *GetCASecureEndpointData(const CAEndpoint_t* peer);
 #endif
 
+bool CAIsExistSslPeer(const CAEndpoint_t *peer);
+
 #ifdef __cplusplus
 }
 #endif //__cplusplus
index 90a53cc..f9999a8 100644 (file)
@@ -112,13 +112,13 @@ typedef int32_t (*CAAdapterSendMulticastData)(const CAEndpoint_t *endpoint,
  * Get Network Information.
  * @param[out]   info           Local connectivity information structures
  * @param[out]   size           Number of local connectivity structures.
- * @return ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h)
+ * @return ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
  */
 typedef CAResult_t (*CAAdapterGetNetworkInfo)(CAEndpoint_t **info, uint32_t *size);
 
 /**
  * Read Synchronous API callback.
- * @return ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h)
+ * @return ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
  */
 typedef CAResult_t (*CAAdapterReadData)();
 
@@ -185,10 +185,11 @@ typedef void (*CARegisterConnectivityCallback)(CAConnectivityHandler_t handler);
 
 /**
  * This will be used during the receive of network requests and response.
+ * @return ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
  * @see SendUnicastData(), SendMulticastData()
  */
-typedef void (*CANetworkPacketReceivedCallback)(const CASecureEndpoint_t *sep,
-                                            const void *data, size_t dataLen);
+typedef CAResult_t (*CANetworkPacketReceivedCallback)(const CASecureEndpoint_t *sep,
+                                                      const void *data, size_t dataLen);
 
 /**
  * This will be used to notify network changes to the connectivity common logic layer.
index 98d74f7..cbe19db 100644 (file)
 
 #include "dtls.h"
 #include "uarraylist.h"
-#include "camutex.h"
+#include "octhread.h"
 #include "caadapterutils.h"
 #include "cainterface.h"
 #include "cacommon.h"
 
 /**
- * Currently DTLS supported adapters(2) WIFI and ETHENET for linux platform.
+ * Currently DTLS supported adapters(3) WIFI, ETHENET and BLE for linux platform.
  */
-#define MAX_SUPPORTED_ADAPTERS 2
+#define MAX_SUPPORTED_ADAPTERS 3
 
 typedef void (*CAPacketReceivedCallback)(const CASecureEndpoint_t *sep,
                                          const void *data, size_t dataLength);
index 1f2d113..cb9692f 100644 (file)
@@ -277,6 +277,13 @@ jmethodID CAGetJNIMethodID(JNIEnv *env, const char* className,
                            const char* methodFormat);
 
 /**
+ * check JNI exception occurrence
+ * @param[in]   env              JNI interface pointer.
+ * @return  true(occurrence) or false(no occurrence).
+ */
+bool CACheckJNIException(JNIEnv *env);
+
+/**
  * To Delete other Global References
  * Called during CATerminate to remove global references
  */
@@ -284,6 +291,34 @@ void CADeleteGlobalReferences();
 
 #endif
 
+#ifndef WITH_ARDUINO
+/**
+ * print send state in the adapter.
+ * @param[in]   adapter          transport adapter type.
+ * @param[in]   addr             remote address.
+ * @param[in]   port             port.
+ * @param[in]   sentLen          sent data length.
+ * @param[in]   isSuccess        sent state.
+ * @param[in]   message          detailed message.
+ */
+void CALogSendStateInfo(CATransportAdapter_t adapter,
+                        const char *addr, uint16_t port, ssize_t sentLen,
+                        bool isSuccess, const char* message);
+
+/**
+ * print adapter state in the adapter.
+ * @param[in]   adapter          transport adapter type.
+ * @param[in]   state            adapter state.
+ */
+void CALogAdapterStateInfo(CATransportAdapter_t adapter, CANetworkStatus_t state);
+
+/**
+ * print adapter type name in the adapter.
+ * @param[in]   adapter          transport adapter type.
+ */
+void CALogAdapterTypeInfo(CATransportAdapter_t adapter);
+#endif
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
index 3b848cc..47cbdaa 100644 (file)
@@ -30,7 +30,7 @@
 
 #include <coap/coap.h>
 #include "cathreadpool.h"
-#include "camutex.h"
+#include "octhread.h"
 #include "uarraylist.h"
 #include "cacommon.h"
 #include "caprotocolmessage.h"
@@ -68,10 +68,10 @@ typedef struct
     u_arraylist_t *dataList;
 
     /** data list mutex for synchronization. **/
-    ca_mutex blockDataListMutex;
+    oc_mutex blockDataListMutex;
 
     /** sender mutex for synchronization. **/
-    ca_mutex blockDataSenderMutex;
+    oc_mutex blockDataSenderMutex;
 } CABlockWiseContext_t;
 
 /**
@@ -91,11 +91,12 @@ typedef struct
     coap_block_t block1;                /**< block1 option. */
     coap_block_t block2;                /**< block2 option. */
     uint16_t type;                      /**< block option type. */
-    CABlockDataID_t* blockDataId;        /**< ID set of CABlockData. */
+    CABlockDataID_t* blockDataId;       /**< ID set of CABlockData. */
     CAData_t *sentData;                 /**< sent request or response data information. */
     CAPayload_t payload;                /**< payload buffer. */
     size_t payloadLength;               /**< the total payload length to be received. */
     size_t receivedPayloadLen;          /**< currently received payload length. */
+    uint64_t ttl;                       /** The TTL for this blockData. */
 } CABlockData_t;
 
 /**
@@ -496,7 +497,7 @@ CAData_t *CAGetDataSetFromBlockDataList(const CABlockDataID_t *blockID);
  * Update the block data from block-wise transfer list.
  * @param[in]   blockID     ID set of CABlockData.
  * @param[in]   sendData    New block date should be sent.
- * @return CABlockData_t structure.
+ * @return CAData structure.
  */
 CABlockData_t *CAUpdateDataSetFromBlockDataList(const CABlockDataID_t *blockID,
                                                 const CAData_t *sendData);
@@ -575,6 +576,17 @@ CAResult_t CARemoveAllBlockDataFromList();
 CAResult_t CARemoveBlockDataFromListWithSeed(const CAToken_t token, uint8_t tokenLength,
                                              uint16_t portNumber);
 
+/**
+ * Reset TTL for a blockData.
+ *
+ * @param[in]   blockID     ID set of CABlockData.
+ */
+void CAResetBlockDataTTL(const CABlockDataID_t *blockID);
+
+/**
+ * Checks if the blockData is past its time to live and deletes it if timed-out.
+ */
+void CACheckAndDeleteTimedOutBlockData();
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
index 92de500..45a5afb 100644 (file)
@@ -89,10 +89,11 @@ typedef struct
  * @param[in] data          Data received.
  * @param[in] dataLength    Length of the Data received.
  * @param[out] sentLength    Length of the sent data.
+ * @return ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
  * @pre Callback must be registered using CAEDRSetPacketReceivedCallback().
  */
-typedef void (*CAEDRDataReceivedCallback)(const char *remoteAddress, const uint8_t *data,
-                                          uint32_t dataLength, uint32_t *sentLength);
+typedef CAResult_t (*CAEDRDataReceivedCallback)(const char *remoteAddress, const uint8_t *data,
+                                                uint32_t dataLength, uint32_t *sentLength);
 
 /**
  * This will be used during change in network status.
index 0aff468..be96caf 100644 (file)
 #include "logger.h"
 
 /**
- * The MTU supported for BLE adapter
- */
-#define CA_SUPPORTED_BLE_MTU_SIZE  20
-
-/**
  * The maximum port value for BLE packet format
  */
 #define CA_SUPPORTED_BLE_MAX_PORT  127
@@ -127,7 +122,8 @@ typedef enum {
 CAResult_t CAGenerateVariableForFragmentation(size_t dataLength,
                                               uint32_t *midPacketCount,
                                               size_t *remainingLen,
-                                              size_t *totalLength);
+                                              size_t *totalLength,
+                                              uint16_t mtuSize);
 
 /**
  * This function is used to generate the CA BLE header to
@@ -214,16 +210,18 @@ CAResult_t CAMakeFirstDataSegment(uint8_t *dataSegment,
  * to maintain the fragmentation logic. start data segment is included
  * 2 bytes header and transmit data.
  *
- * @param[out]  dataSegment    Pointer to the octet array that will
- *                             contain the generated data packet.
- * @param[in]   data           Data to the octet array that required
- *                             transmittin to remote device. it will
- *                             be embedded in 7th byte to data length.
- * @param[in]   dataLength     The length of data size.
- * @param[in]   index          Index to determine whether some of the
- *                             total data
- * @param[in]   dataHeader     Pointer to the octet array that contain
- *                             data header.
+ * @param[out]  dataSegment            Pointer to the octet array that will
+ *                                     contain the generated data packet.
+ * @param[in]   segmentPayloadLength   The length of data segment payload.
+ * @param[in]   sourceData             Data to the octet array that required
+ *                                     transmission to remote device. it will
+ *                                     be embedded in 7th byte to data length.
+ * @param[in]   sourceDataLength       The length of total data.
+ * @param[in]   segmentNum             Index to determine whether some of the
+ *                                     total data
+ * @param[in]   dataHeader             Pointer to the octet array that contain
+ *                                     data header.
+ * @param[in]   mtuSize                MTU size.
  *
  * @return ::CA_STATUS_OK on success. One of the CA_STATUS_FAILED
  *           or other error values on error.
@@ -232,10 +230,12 @@ CAResult_t CAMakeFirstDataSegment(uint8_t *dataSegment,
  * @retval ::CA_STATUS_FAILED         Operation failed
  */
 CAResult_t CAMakeRemainDataSegment(uint8_t *dataSegment,
-                                   const uint8_t *data,
-                                   const uint32_t dataLength,
-                                   const uint32_t index,
-                                   const uint8_t *dataHeader);
+                                   const uint32_t segmentPayloadLength,
+                                   const uint8_t *sourceData,
+                                   const uint32_t sourceDataLength,
+                                   const uint32_t segmentNum,
+                                   const uint8_t *dataHeader,
+                                   uint16_t mtuSize);
 
 /**
  * This function is used to parse the header in the receiver end. This
index 4f48452..fedc1a7 100644 (file)
@@ -50,8 +50,9 @@ void CAInitializeAdapters();
  * Initializes different adapters based on the compilation flags.
  * @param[in]   handle           thread pool handle created by message handler
  *                               for different adapters.
+ * @param[in]   transportType    transport type to initialize.
  */
-void CAInitializeAdapters(ca_thread_pool_t handle);
+void CAInitializeAdapters(ca_thread_pool_t handle, CATransportAdapter_t transportType);
 #endif
 
 /**
@@ -170,6 +171,41 @@ void CATerminateAdapters();
 CAResult_t CAReadData();
 #endif
 
+#ifdef IP_ADAPTER
+/**
+ * Set multicast time to live value to control the scope of the multicasts.
+ * @param[in]  ttl         To be set to any value from 0 to 255.
+ *
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CASetMulticastTTL(size_t ttl);
+
+/**
+ * Get multicast time to live value.
+ * @param[out]  ttl        TTL pointer to get the stored multicast time to live.
+ *
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CAGetMulticastTTL(size_t *ttl);
+#endif
+
+#ifdef TCP_ADAPTER
+/**
+ * Disconnect TCP session.
+ * When there is no transmission for a long time.
+ * Some carrier vendor is blocking data.
+ * Thur, TCP Session is cleaned through this function.
+ * @param[in]   endpoint       endpoint information to disconnect.
+ */
+CAResult_t CADisconnectSession(const CAEndpoint_t *endpoint);
+#endif
+
+#ifdef LE_ADAPTER
+void CAStartGattServer();
+
+void CAStopGattServer();
+#endif
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
index 5cf683a..62eb0fd 100644 (file)
@@ -53,11 +53,12 @@ typedef enum
  * @param[in]  sep         network endpoint description.
  * @param[in]  data          Data received from remote OIC device.
  * @param[in]  dataLength    Length of data in bytes.
+ * @return ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
  * @pre  Callback must be registered using CAIPSetPacketReceiveCallback().
  */
-typedef void (*CAIPPacketReceivedCallback)(const CASecureEndpoint_t *sep,
-                                           const void *data,
-                                           uint32_t dataLength);
+typedef CAResult_t (*CAIPPacketReceivedCallback)(const CASecureEndpoint_t *sep,
+                                                 const void *data,
+                                                 uint32_t dataLength);
 
 /**
   * Callback to notify error in the IP adapter.
@@ -172,17 +173,37 @@ void CAIPPullData();
 int CAGetPollingInterval(int interval);
 
 /**
- * Tell the IP server an interface has been added.
- */
-void CAWakeUpForChange();
-
-/**
  * Set callback for error handling.
  *
  * @param[in]  errorHandleCallback  callback to notify error to the ipadapter.
  */
 void CAIPSetErrorHandler(CAIPErrorHandleCallback errorHandleCallback);
 
+/**
+ * Set udp multicast time to live value to control the scope of the multicasts.
+ * @param[in]  ttl         To be set to any value from 0 to 255.
+ *
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CAIPSetMulticastTTL(size_t ttl);
+
+/**
+ * Get udp multicast time to live value.
+ * @param[out]  ttl         TTL pointer to get the stored multicast time to live.
+ *
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CAIPGetMulticastTTL(size_t *ttl);
+
+/**
+ * Create multicast socket to receive multicast message from remote device.
+ */
+void CreateMulticastSocket();
+
+/**
+ * Close multicast socket to stop receiving multicast message.
+ */
+void CloseMulticastSocket();
 #ifdef __cplusplus
 }
 #endif
index 11a0b79..4560d32 100644 (file)
@@ -57,6 +57,8 @@ CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
                           CAErrorHandleCallback errorCallback,
                           ca_thread_pool_t handle);
 
+void CALEStartGattServer();
+void CALEStopGattServer();
 
 #ifdef __cplusplus
 } /* extern "C" */
index 6e78bc9..c354ee3 100644 (file)
@@ -72,6 +72,24 @@ typedef struct
 } CALEData_t;
 
 /**
+ * The MTU supported for BLE adapter
+ */
+#ifdef __APPLE__
+#define CA_DEFAULT_BLE_MTU_SIZE  152
+#else
+#define CA_DEFAULT_BLE_MTU_SIZE  20
+#endif
+/**
+ * The MTU supported for BLE spec
+ */
+#define CA_SUPPORTED_BLE_MTU_SIZE  517
+
+/**
+ * The Header of the MTU supported for BLE spec
+ */
+#define CA_BLE_MTU_HEADER_SIZE  5
+
+/**
  * This will be used to notify device status changes to the LE adapter layer.
  * @param[in]  adapter_state State of the adapter.
  */
index 5596039..10203b9 100644 (file)
@@ -45,6 +45,7 @@ typedef struct
     CARequestInfo_t *requestInfo;
     CAResponseInfo_t *responseInfo;
     CAErrorInfo_t *errorInfo;
+    CAConnectEvent_t eventInfo;
     CADataType_t dataType;
 } CAData_t;
 
@@ -65,6 +66,17 @@ CAResult_t CADetachSendMessage(const CAEndpoint_t *endpoint,
                                CADataType_t dataType);
 
 /**
+ * Detaches control from the caller for sending message to adapter.
+ * @param[in] endpoint    endpoint information where the data has to be sent.
+ * @param[in] event       command to request disconect or connect.
+ * @param[in] dataType    type of the message(request/response).
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CADetachSendNetworkReqMessage(const CAEndpoint_t *endpoint,
+                                         CAConnectEvent_t event,
+                                         CADataType_t dataType);
+
+/**
  * Setting the request and response callbacks for network packets.
  * @param[in] ReqHandler      callback for receiving the requests.
  * @param[in] RespHandler     callback for receiving the response.
@@ -76,9 +88,16 @@ void CASetInterfaceCallbacks(CARequestCallback ReqHandler, CAResponseCallback Re
 /**
  * Initialize the message handler by starting thread pool and initializing the
  * send and receive queue.
+ * @param[in]   transportType  transport type to initialize.
  * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
  */
-CAResult_t CAInitializeMessageHandler();
+CAResult_t CAInitializeMessageHandler(CATransportAdapter_t transportType);
+
+/**
+ * Clears the message handler queue data.
+ * @param[in]   transportType  transport type to initialize.
+ */
+void CAClearMessageHandler(CATransportAdapter_t transportType);
 
 /**
  * Terminate the message handler by stopping  the thread pool and destroying the queues.
@@ -96,13 +115,6 @@ void CAHandleRequestResponseCallbacks();
  */
 void CASetNetworkMonitorCallback(CANetworkMonitorCallback nwMonitorHandler);
 
-/**
- * To log the PDU data.
- * @param[in] pdu    pdu data.
- * @param[in] endpoint  endpoint
- */
-void CALogPDUInfo(coap_pdu_t *pdu, const CAEndpoint_t *endpoint);
-
 #ifdef WITH_BWT
 /**
  * Add the data to the send queue thread.
index 8cbd642..3a906ee 100644 (file)
@@ -52,9 +52,10 @@ typedef enum
  * @param[in]  endpoint    network endpoint description\r
  * @param[in]  data        Data received from remote OIC device.\r
  * @param[in]  dataLength  Length of data in bytes.\r
+ * @return ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).\r
  */\r
-typedef void (*CANFCPacketReceivedCallback)(const CASecureEndpoint_t *endpoint, const void *data,\r
-                                            uint32_t dataLength);\r
+typedef CAResult_t (*CANFCPacketReceivedCallback)(const CASecureEndpoint_t *endpoint,\r
+                                                  const void *data, uint32_t dataLength);\r
 \r
 /**\r
   * Callback to notify error in the NFC adapter.\r
index 89efec1..91deeda 100644 (file)
@@ -30,7 +30,7 @@
 #include <stdint.h>
 
 #include "cathreadpool.h"
-#include "camutex.h"
+#include "octhread.h"
 #include "uqueue.h"
 #include "cacommon.h"
 #ifdef __cplusplus
@@ -44,14 +44,17 @@ typedef void (*CAThreadTask)(void *threadData);
 /** Data destroy function. **/
 typedef void (*CADataDestroyFunction)(void *data, uint32_t size);
 
+/** Context based Data destroy function. **/
+typedef bool (*CAContextDataDestroy)(void *data, uint32_t size, void *ctx);
+
 typedef struct
 {
     /** Thread pool of the thread started. **/
     ca_thread_pool_t threadPool;
     /** mutex for synchronization. **/
-    ca_mutex threadMutex;
+    oc_mutex threadMutex;
     /** conditional mutex for synchronization. **/
-    ca_cond threadCond;
+    oc_cond threadCond;
     /** Thread function to be invoked. **/
     CAThreadTask threadTask;
     /** Data destroy function. **/
@@ -78,8 +81,11 @@ CAResult_t CAQueueingThreadInitialize(CAQueueingThread_t *thread, ca_thread_pool
  * @param[in]   thread        thread data that needs to be started.
  * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h).
  */
+#ifndef __TIZENRT__
 CAResult_t CAQueueingThreadStart(CAQueueingThread_t *thread);
-
+#else
+CAResult_t CAQueueingThreadStart(CAQueueingThread_t *thread, const char *thread_name);
+#endif
 /**
  * Add queuing thread data for new thread.
  * @param[in]   thread       thread data for new thread control.
@@ -90,6 +96,23 @@ CAResult_t CAQueueingThreadStart(CAQueueingThread_t *thread);
 CAResult_t CAQueueingThreadAddData(CAQueueingThread_t *thread, void *data, uint32_t size);
 
 /**
+ * Clears queue thread data.
+ * @param[in]   thread       thread data for new thread control.
+ * @return  ::CA_STATUS_OK or Appropriate error code.
+ */
+CAResult_t CAQueueingThreadClearData(CAQueueingThread_t *thread);
+
+/**
+ * Clears queue thread data of specific context.
+ * @param[in]   thread           thread data for new thread control.
+ * @param[in]   callback         Function which should return true if the data
+ *                               needs to be deleted, else returns false
+ * @param[in]   ctx              Data to pass to callback
+ */
+CAResult_t CAQueueingThreadClearContextData(CAQueueingThread_t *thread,
+                                            CAContextDataDestroy callback, void *ctx);
+
+/**
  * Stop the queuing thread.
  * @param[in]   thread       thread data that needs to be started.
  * @return  CA_STATUS_OK or ERROR CODES (CAResult_t error codes in cacommon.h).
index d764e51..a43ecd2 100644 (file)
@@ -29,7 +29,7 @@
 #include <stdint.h>
 
 #include "cathreadpool.h"
-#include "camutex.h"
+#include "octhread.h"
 #include "uarraylist.h"
 #include "cacommon.h"
 
@@ -74,10 +74,10 @@ typedef struct
     ca_thread_pool_t threadPool;
 
     /** mutex for synchronization. **/
-    ca_mutex threadMutex;
+    oc_mutex threadMutex;
 
     /** conditional mutex for synchronization. **/
-    ca_cond threadCond;
+    oc_cond threadCond;
 
     /** send method for retransmission data. **/
     CADataSendMethod_t dataSendMethod;
@@ -154,6 +154,14 @@ CAResult_t CARetransmissionReceivedData(CARetransmission_t *context,
                                         uint32_t size, void **retransmissionPdu);
 
 /**
+ * Clears queue data.
+ * @param[in]   context              context for retransmission.
+ * @param[in]   type                 Adapter type.
+ * @return  ::CA_STATUS_OK or Appropriate error code.
+ */
+CAResult_t CARetransmissionClearAdapterData(CARetransmission_t *context, CATransportAdapter_t type);
+
+/**
  * Stopping the retransmission context.
  * @param[in]   context         context for retransmission.
  * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
index cb2a740..536f8f6 100644 (file)
@@ -64,10 +64,11 @@ typedef struct
     unsigned char* data;                /**< received data from remote device */
     size_t len;                         /**< received data length */
     size_t totalLen;                    /**< total coap data length required to receive */
-    unsigned char tlsdata[18437];     /**< tls data(rfc5246: TLSCiphertext max (2^14+2048+5)) */
-    size_t tlsLen;                         /**< received tls data length */
+    unsigned char tlsdata[18437];       /**< tls data(rfc5246: TLSCiphertext max (2^14+2048+5)) */
+    size_t tlsLen;                      /**< received tls data length */
     CAProtocol_t protocol;              /**< application-level protocol */
     CATCPConnectionState_t state;       /**< current tcp session state */
+    bool isClient;                      /**< Host Mode of Operation. */
 } CATCPSessionInfo_t;
 
 /**
@@ -99,6 +100,16 @@ CAResult_t CAInitializeTCP(CARegisterConnectivityCallback registerCallback,
 CAResult_t CAStartTCP();
 
 /**
+ * Disconnect TCP session.
+ * When there is no transmission for a long time.
+ * Some carrier Vendor is blocking data.
+ * Thur, TCP Session is cleaned through this function.
+ * @param[in]   endpoint       Remote Endpoint information (like ipaddress,
+ *                             port)
+ */
+CAResult_t CATCPDisconnectSession(const CAEndpoint_t *endpoint);
+
+/**
  * Start listening server for receiving connect requests.
  * Transport Specific Behavior:
  * TCP Starts Listening Server on a particular interface and prefixed port
index dc86e0f..201dd26 100644 (file)
@@ -44,11 +44,12 @@ extern "C"
  * @param[in]  endpoint      network endpoint description.
  * @param[in]  data          Data received from remote OIC device.
  * @param[in]  dataLength    Length of data in bytes.
+ * @return ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
  * @pre  Callback must be registered using CAIPSetPacketReceiveCallback().
  */
-typedef void (*CATCPPacketReceivedCallback)(const CASecureEndpoint_t *endpoint,
-                                            const void *data,
-                                            size_t dataLength);
+typedef CAResult_t (*CATCPPacketReceivedCallback)(const CASecureEndpoint_t *endpoint,
+                                                  const void *data,
+                                                  size_t dataLength);
 
 /**
   * Callback to notify error in the TCP adapter.
@@ -67,9 +68,11 @@ typedef void (*CATCPErrorHandleCallback)(const CAEndpoint_t *endpoint, const voi
   *
   * @param[in]  endpoint        network endpoint description.
   * @param[in]  isConnected     Whether keepalive message needs to be sent.
+  * @param[in]  isClient        Host Mode of Operation.
   * @see  Callback must be registered using CATCPSetKeepAliveCallback().
  */
-typedef void (*CATCPConnectionHandleCallback)(const CAEndpoint_t *endpoint, bool isConnected);
+typedef void (*CATCPConnectionHandleCallback)(const CAEndpoint_t *endpoint, bool isConnected,
+                                              bool isClient);
 
 /**
  * set error callback to notify error in TCP adapter.
@@ -259,6 +262,30 @@ CAResult_t CAConstructCoAP(CATCPSessionInfo_t *svritem, unsigned char **data,
  */
 void CACleanData(CATCPSessionInfo_t *svritem);
 
+/**
+ * Create a mutex object.
+ *
+ * @return  ::CA_STATUS_OK or Appropriate error code.
+ */
+CAResult_t CATCPCreateMutex();
+
+/**
+ * Close a mutex object.
+ */
+void CATCPDestroyMutex();
+
+/**
+ * Initialize a condition variable.
+ *
+ * @return  ::CA_STATUS_OK or Appropriate error code.
+ */
+CAResult_t CATCPCreateCond();
+
+/**
+ * Destroy condition variable state.
+ */
+void CATCPDestroyCond();
+
 #ifdef __cplusplus
 }
 #endif
index c26784c..65c4259 100644 (file)
@@ -135,8 +135,11 @@ _coap_is_mcast_impl(const coap_address_t *a)
     {
         case AF_INET:
         return IN_MULTICAST(a->addr.sin.sin_addr.s_addr);
+/* TODO - Enable this once IPv6 comes in TizenRT */
+#ifndef __TIZENRT__
         case AF_INET6:
         return IN6_IS_ADDR_MULTICAST(&a->addr.sin6.sin6_addr);
+#endif
         default: /* fall through and signal error */
         ;
     }
index 292055c..5a27a31 100644 (file)
@@ -32,6 +32,9 @@
 /* Define to 1 if you have the <netinet/in.h> header file. */
 #if !defined(WITH_ARDUINO) && !defined(_WIN32)
 #define HAVE_NETINET_IN_H 1
+#if defined (__TIZENRT__)
+#define HAVE_ARPA_INET_H 1
+#endif
 #endif
 
 /* Define to 1 if you have the `select' function. */
index a7a8888..0ca2069 100644 (file)
@@ -9,7 +9,7 @@
 #ifndef _COAP_ENCODE_H_
 #define _COAP_ENCODE_H_
 
-#if (BSD >= 199103) || defined(WITH_CONTIKI)
+#if (BSD >= 199103) || defined(WITH_CONTIKI) || defined(__TIZENRT__)
 # include <string.h>
 #else
 #if !defined(WITH_ARDUINO) && !defined(_MSC_VER)
index bd86b19..a841279 100644 (file)
@@ -34,6 +34,10 @@ extern "C"
 #ifdef HAVE_NETINET_IN_H
 #include <netinet/in.h>
 #endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
 #ifdef HAVE_TIME_H
 #include <time.h>
 #endif
index dc619e2..4909dbe 100644 (file)
@@ -105,7 +105,7 @@ coap_free_subscription(coap_subscription_t *subscription)
     }                                   \
   }
 
-int match(const str *text, const str *pattern, int match_prefix, int match_substring)
+static int match(const str *text, const str *pattern, int match_prefix, int match_substring)
 {
     assert(text);
     assert(pattern);
index c229051..1abd0ce 100644 (file)
@@ -8,6 +8,7 @@ Import('env')
 ca_os = env.get('TARGET_OS')
 ca_transport = env.get('TARGET_TRANSPORT')
 secured = env.get('SECURED')
+with_mbedtls_static = env.get('WITH_MBEDTLS_STATIC_LIB');
 multiple_owner = env.get('MULTIPLE_OWNER')
 with_ra = env.get ('WITH_RA')
 with_ra_ibb = env.get('WITH_RA_IBB')
@@ -34,9 +35,12 @@ else:
        env.AppendUnique(CPPPATH = [ os.path.join(root_dir, 'lib', 'libcoap-4.1.1', 'include')])
 
 env.AppendUnique(CPPPATH = [ os.path.join(root_dir, 'inc'),
+                             os.path.join(src_dir, 'resource', 'csdk', 'stack', 'include'),
                              os.path.join(src_dir, 'resource', 'csdk', 'logger', 'include'),
                              os.path.join(root_dir, 'common', 'inc'),
-                             os.path.join(root_dir, 'util', 'inc') ])
+                             os.path.join(root_dir, '/usr', 'include','glib-2.0'),
+                             os.path.join(root_dir, '/usr', 'lib','glib-2.0', 'include'),
+                             os.path.join(root_dir, 'util', 'inc')])
 
 if ca_os not in ['arduino', 'windows']:
        env.AppendUnique(CPPDEFINES = ['WITH_POSIX'])
@@ -53,9 +57,6 @@ env.SConscript(os.path.join(root_dir, 'common', 'SConscript'))
 # Getting util source files
 env.SConscript(os.path.join(root_dir, 'util', 'SConscript'))
 
-# The tinydtls library is found in '#extlibs/tinydtls', where the '#'
-# is interpreted by SCons as the top-level iotivity directory where
-# the SConscruct file is found.
 build_dir = env.get('BUILD_DIR')
 
 env.AppendUnique(CA_SRC = [os.path.join(ca_path,
@@ -66,8 +67,6 @@ if (('BLE' in ca_transport) or ('ALL' in ca_transport)):
                                           'adapter_util/cafragmentation.c')])
 
 if env.get('SECURED') == '1':
-       env.SConscript(build_dir + 'extlibs/tinydtls/SConscript')
-       env.AppendUnique(CPPPATH = ['#extlibs/tinydtls'])
        env.SConscript(build_dir + 'extlibs/timer/SConscript')
        env.AppendUnique(CPPPATH = ['#extlibs/timer'])
        env.AppendUnique(CPPPATH = [src_dir + '/resource/csdk/security/include'])
@@ -79,7 +78,7 @@ if env.get('SECURED') == '1':
                env.SConscript(os.path.join(root_dir, tls_path + '/SConscript'))
                env.AppendUnique(CPPPATH = [os.path.join(root_dir, tls_path + '/' + tls_headers_path)])
        else:
-               if ca_os != 'android':
+               if ca_os != 'android' and env.get('PLATFORM_TLS') == '0':
                        env.SConscript('#' + tls_path + '/SConscript')
                env.AppendUnique(CPPPATH = ['#' + tls_path + '/' + tls_headers_path])
                env.AppendUnique(CA_SRC = [os.path.join(ca_path, 'adapter_util/ca_adapter_net_ssl.c')])
@@ -88,7 +87,7 @@ if ((secured == '1') and (with_tcp == True)):
        env.AppendUnique(CPPDEFINES = ['__WITH_TLS__'])
 
 if (multiple_owner == '1'):
-       env.AppendUnique(CPPDEFINES=['_ENABLE_MULTIPLE_OWNER_'])
+       env.AppendUnique(CPPDEFINES=['MULTIPLE_OWNER'])
 
 
 ca_common_src = None
@@ -180,7 +179,7 @@ if 'BLE' in ca_transport:
 if 'NFC' in ca_transport:
        env.SConscript(os.path.join(ca_path, 'nfc_adapter/SConscript'))
 
-if ca_os in ['linux', 'tizen', 'android', 'ios']:
+if ca_os in ['linux', 'tizen', 'android', 'ios', 'tizenrt']:
        if with_tcp == True:
                env.SConscript(os.path.join(ca_path, 'tcp_adapter/SConscript'))
                env.AppendUnique(CPPDEFINES = ['WITH_TCP'])
@@ -201,24 +200,29 @@ if env.get('LOGGING'):
 if ca_os == 'android':
        lib_env.AppendUnique(LINKFLAGS = ['-Wl,-soname,libconnectivity_abstraction.so'])
 
-if ca_os in ['android', 'tizen', 'linux']:
-       lib_env.AppendUnique(LIBS = ['coap'])
-       if lib_env.get('SECURED') == '1':
+if lib_env.get('SECURED') == '1':
+       if ca_os in ['windows', 'msys_nt', 'ios']:
                lib_env.AppendUnique(LIBS = ['mbedtls','mbedx509','mbedcrypto'])
                lib_env.AppendUnique(LIBS = ['timer'])
-       if ca_os != 'android':
-               lib_env.AppendUnique(LIBS = ['rt'])
-               if ((lib_env.get('SECURED') == '1') and ((lib_env.get('WITH_TCP')) or (lib_env.get('WITH_CLOUD')))):
+       else:
+               if with_mbedtls_static == '1':
                        lib_env.AppendUnique(LIBS = ['mbedtls','mbedx509','mbedcrypto'])
                        lib_env.AppendUnique(LIBS = ['timer'])
+               else:
+                       lib_env.AppendUnique(LIBPATH = [lib_env.get('BUILD_DIR')])
+                       lib_env.AppendUnique(RPATH = [lib_env.get('BUILD_DIR')])
+                       lib_env.PrependUnique(LIBS = ['mbedtls','mbedx509','mbedcrypto'])
+                       lib_env.PrependUnique(LIBS = ['timer'])
+
+if ca_os in ['android', 'tizen', 'linux']:
+       lib_env.AppendUnique(LIBS = ['coap'])
+       if ca_os != 'android':
+               lib_env.AppendUnique(LIBS = ['rt'])
        static_calib = lib_env.StaticLibrary('connectivity_abstraction', env.get('CA_SRC'))
        shared_calib = lib_env.SharedLibrary('connectivity_abstraction', lib_env.get('CA_SRC'))
        calib = Flatten([static_calib, shared_calib])
 elif ca_os in ['msys_nt', 'windows']:
        lib_env.AppendUnique(LIBS = ['coap', 'mswsock', 'ws2_32', 'iphlpapi', 'logger'])
-       if lib_env.get('SECURED') == '1':
-               lib_env.AppendUnique(LIBS = ['mbedtls','mbedx509','mbedcrypto'])
-               lib_env.AppendUnique(LIBS = ['timer'])
        calib = lib_env.StaticLibrary('connectivity_abstraction', env.get('CA_SRC'))
 else:
        calib = lib_env.StaticLibrary('connectivity_abstraction', lib_env.get('CA_SRC'))
index b490c8a..7b8f60e 100644 (file)
  *
  ******************************************************************/
 
+#define MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE
+
+#ifndef _GNU_SOURCE
 #define _GNU_SOURCE
+#endif // _GNU_SOURCE
 
 #include <stddef.h>
+#include <stdint.h>
 #include <stdbool.h>
 #include "ca_adapter_net_ssl.h"
 #include "cacommon.h"
+#include "caadapterutils.h"
+#include "cainterface.h"
 #include "caipinterface.h"
 #include "oic_malloc.h"
 #include "ocrandom.h"
 #include "byte_array.h"
-#include "camutex.h"
+#include "octhread.h"
 #include "timer.h"
 
 
@@ -44,6 +51,7 @@
 #include "mbedtls/timing.h"
 #include "mbedtls/ssl_cookie.h"
 #endif
+#include "pkix_interface.h"
 
 #if !defined(NDEBUG) || defined(TB_LOG)
 #include "mbedtls/debug.h"
  * @def TLS_MSG_BUF_LEN
  * @brief Buffer size for TLS record. A single TLS record may be up to 16384 octets in length
  */
-
+#if defined (__TIZENRT__)
+#define TLS_MSG_BUF_LEN (2048)
+#else
 #define TLS_MSG_BUF_LEN (16384)
+#endif
+
 /**
  * @def PSK_LENGTH
  * @brief PSK keys max length
  */
 #define RANDOM_LEN (32)
 /**
- * @def RANDOM_LEN
- * @brief PSK generated keyblock length
+ * @def SHA384_MAC_KEY_LENGTH
+ * @brief MAC key length for SHA384 cipher suites
  */
-#define KEY_BLOCK_LEN (96)
-
-/**@def SSL_CLOSE_NOTIFY(peer, ret)
- *
- * Notifies of existing \a peer about closing TLS connection.
- *
- * @param[in] peer remote peer
- * @param[in] ret used internaly
+#define SHA384_MAC_KEY_LENGTH (48)
+/**
+ * @def SHA256_MAC_KEY_LENGTH
+ * @brief MAC key length for SHA256 cipher suites
+ */
+#define SHA256_MAC_KEY_LENGTH (32)
+/**
+ * @def CCM_MAC_KEY_LENGTH
+ * @brief MAC key length for CCM cipher suites
+ */
+#define CCM_MAC_KEY_LENGTH (0)
+/**
+ * @def AES256_KEY_LENGTH
+ * @brief key material length for AES256 cipher suites
+ */
+#define AES256_KEY_LENGTH (32)
+/**
+ * @def AES128_KEY_LENGTH
+ * @brief key material length for AES128 cipher suites
+ */
+#define AES128_KEY_LENGTH (16)
+/**
+ * @def GCM_IV_LENGTH
+ * @brief length of nonce for GCM cipher suites
+ */
+#define GCM_IV_LENGTH (12)
+/**
+ * @def CCM_IV_LENGTH
+ * @brief length of nonce for CCM cipher suites
  */
+#define CCM_IV_LENGTH (4)
+/**
+ * @def CBC_IV_LENGTH
+ * @brief length of nonce for CBC cipher suites
+ */
+#define CBC_IV_LENGTH (0)
 
 /**
  * @var RETRANSMISSION_TIME
  */
 #define RETRANSMISSION_TIME 1
 
+/**@def SSL_CLOSE_NOTIFY(peer, ret)
+ *
+ * Notifies of existing \a peer about closing TLS connection.
+ *
+ * @param[in] peer remote peer
+ * @param[in] ret used internaly
+ */
 #define SSL_CLOSE_NOTIFY(peer, ret)                                                                \
 do                                                                                                 \
 {                                                                                                  \
@@ -168,40 +214,62 @@ if (g_sslCallback)
  * @param[in] ret error code
  * @param[in] str debug string
  * @param[in] mutex ca mutex
- * @param[in] if code does not equal to -1 returns error code
+ * @param[in] error if code does not equal to -1 returns error code
  * @param[in] msg allert message
  */
 #define SSL_CHECK_FAIL(peer, ret, str, mutex, error, msg)                                          \
-if (0 != (ret) && MBEDTLS_ERR_SSL_WANT_READ != (int) (ret) &&                                      \
-    MBEDTLS_ERR_SSL_WANT_WRITE != (int) (ret) &&                                                   \
+if (0 != (ret) && MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY != (int) (ret) &&                              \
     MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED != (int) (ret) &&                                        \
-    MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY != (int) (ret))                                              \
+    MBEDTLS_ERR_SSL_WANT_READ != (int) (ret) &&                                                    \
+    MBEDTLS_ERR_SSL_WANT_WRITE != (int) (ret) &&                                                   \
+    MBEDTLS_ERR_SSL_NON_FATAL != (int) (ret) &&                                                    \
+    MBEDTLS_SSL_ALERT_MSG_USER_CANCELED != (int) (ret) &&                                          \
+    MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION != (int) (ret) &&                                       \
+    MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_EXT != (int) (ret) &&                                        \
+    MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY != (int) (ret) &&                                           \
+    MBEDTLS_SSL_ALERT_MSG_NO_CERT != (int) (ret) &&                                                \
+    MBEDTLS_SSL_ALERT_MSG_BAD_CERT != (int) (ret) &&                                               \
+    MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT != (int) (ret) &&                                       \
+    MBEDTLS_SSL_ALERT_MSG_CERT_REVOKED != (int) (ret) &&                                           \
+    MBEDTLS_SSL_ALERT_MSG_CERT_EXPIRED != (int) (ret) &&                                           \
+    MBEDTLS_SSL_ALERT_MSG_CERT_UNKNOWN != (int) (ret) &&                                           \
+    MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK != (int) (ret) &&                                  \
+    MBEDTLS_SSL_ALERT_MSG_UNRECOGNIZED_NAME != (int) (ret) &&                                      \
+    MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY != (int) (ret) &&                                   \
+    MBEDTLS_SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL != (int) (ret))                                  \
 {                                                                                                  \
     OIC_LOG_V(ERROR, NET_SSL_TAG, "%s: -0x%x", (str), -(ret));                                     \
     if ((int) MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE != (int) (ret) &&                                \
-       (int) MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO != (int) (ret))                                   \
+        (int) MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO != (int) (ret))                                  \
     {                                                                                              \
         mbedtls_ssl_send_alert_message(&(peer)->ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, (msg));        \
     }                                                                                              \
-    if ((int) MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE == (int) (ret) &&                                \
-        ((int) MBEDTLS_SSL_ALERT_MSG_DECRYPTION_FAILED == (peer)->ssl.in_msg[1] ||                 \
-         (int) MBEDTLS_SSL_ALERT_MSG_DECRYPT_ERROR == (peer)->ssl.in_msg[1] ||                     \
-         (int) MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE == (peer)->ssl.in_msg[1] ||                 \
-         (int) MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC == (peer)->ssl.in_msg[1]))                     \
-    {                                                                                              \
-        SSL_RES((peer), CA_DTLS_AUTHENTICATION_FAILURE);                                           \
-    }                                                                                              \
     RemovePeerFromList(&(peer)->sep.endpoint);                                                     \
     if (mutex)                                                                                     \
     {                                                                                              \
-        ca_mutex_unlock(g_sslContextMutex);                                                        \
+        oc_mutex_unlock(g_sslContextMutex);                                                        \
+    }                                                                                              \
+    if ((int) MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO != (int)(ret))                                   \
+    {                                                                                              \
+        SSL_RES((peer), CA_DTLS_AUTHENTICATION_FAILURE);                                           \
     }                                                                                              \
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);                                             \
-    if (-1 != error)                                                                               \
+    if (-1 != (intptr_t)error)                                                                               \
     {                                                                                              \
         return (error);                                                                            \
     }                                                                                              \
 }
+
+/**@def CONF_SSL(clientConf, serverConf, fn, ...)
+ *
+ * Calls \a fn for \a clientConf and \a serverConf.
+ *
+ */
+#define CONF_SSL(clientConf, serverConf, fn, ...) do {                                             \
+fn((clientConf), __VA_ARGS__);                                                                     \
+fn((serverConf), __VA_ARGS__);                                                                     \
+} while (0)
+
 /** @def CHECK_MBEDTLS_RET(f, ...)
  * A macro that checks \a f function return code
  *
@@ -214,18 +282,25 @@ int ret = (f)(__VA_ARGS__);
 if (0 != ret) {                                                                                    \
     OIC_LOG_V(ERROR, NET_SSL_TAG, "%s returned -0x%04x\n", __func__, -(ret));                      \
     goto exit;                                                                                     \
-} } while(0)
+} } while (0)
 
 typedef enum
 {
-    ADAPTER_TLS_RSA_WITH_AES_256_CBC_SHA,
-    ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
-    ADAPTER_TLS_ECDH_ANON_WITH_AES_128_CBC_SHA_256,
-    ADAPTER_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
-    ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CCM,
-    ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
-    ADAPTER_CIPHER_MAX
-} AdapterCipher_t;
+    SSL_RSA_WITH_AES_256_CBC_SHA256,
+    SSL_RSA_WITH_AES_128_GCM_SHA256,
+    SSL_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+    SSL_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+    SSL_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+    SSL_ECDHE_ECDSA_WITH_AES_128_CCM_8,
+    SSL_ECDHE_ECDSA_WITH_AES_128_CCM,
+    SSL_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+    SSL_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
+    SSL_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+    SSL_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
+    SSL_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+    SSL_ECDH_ANON_WITH_AES_128_CBC_SHA256,
+    SSL_CIPHER_MAX
+} SslCipher_t;
 
 typedef enum
 {
@@ -233,17 +308,35 @@ typedef enum
     ADAPTER_CURVE_MAX
 } AdapterCurve_t;
 
-int tlsCipher[ADAPTER_CIPHER_MAX][2] =
+static const int tlsCipher[SSL_CIPHER_MAX][2] =
 {
-    {MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA, 0},
+    {MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256, 0},
+    {MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256, 0},
+    {MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
+    {MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0},
+    {MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
     {MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, 0},
-    {MBEDTLS_TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256, 0},
-    {MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, 0},
     {MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, 0},
-    {MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 0}
+    {MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 0},
+    {MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, 0},
+    {MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 0},
+    {MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, 0},
+    {MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 0},
+    {MBEDTLS_TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256, 0}
 };
 
-static int g_cipherSuitesList[ADAPTER_CIPHER_MAX];
+static int g_cipherSuitesList[SSL_CIPHER_MAX];
+
+static int g_ssl_ordered_default_hashes[] = {
+#if defined(MBEDTLS_SHA256_C)
+    MBEDTLS_MD_SHA256,
+    MBEDTLS_MD_SHA224,
+#endif
+#if defined(MBEDTLS_SHA1_C)
+    MBEDTLS_MD_SHA1,
+#endif
+    MBEDTLS_MD_NONE
+};
 
 mbedtls_ecp_group_id curve[ADAPTER_CURVE_MAX][2] =
 {
@@ -316,7 +409,7 @@ static void DebugSsl(void *ctx, int level, const char *file, int line, const cha
 }
 #endif
 
-#if defined(_WIN32)
+#if defined(_WIN32) || defined (__TIZENRT__)
 /*
  * Finds the first occurrence of the byte string s in byte string l.
  */
@@ -386,16 +479,16 @@ typedef struct SslContext
     mbedtls_ssl_config clientDtlsConf;
     mbedtls_ssl_config serverDtlsConf;
 
-    AdapterCipher_t cipher;
+    SslCipher_t cipher;
     SslCallbacks_t adapterCallbacks[MAX_SUPPORTED_ADAPTERS];
     mbedtls_x509_crl crl;
     bool cipherFlag[2];
     int selectedCipher;
 
 #ifdef __WITH_DTLS__
+    mbedtls_ssl_cookie_ctx cookieCtx;
     int timerId;
 #endif
-
 } SslContext_t;
 
 /**
@@ -404,6 +497,10 @@ typedef struct SslContext
  */
 static SslContext_t * g_caSslContext = NULL;
 
+static SslExportKeysCallback_t gTlsExportKeysCallback = NULL;
+
+static SslExportKeysCallback_t gDtlsExportKeysCallback = NULL;
+
 /**
  * @var g_getCredentialsCallback
  * @brief callback to get TLS credentials (same as for DTLS)
@@ -422,10 +519,17 @@ static CAgetCredentialTypesHandler g_getCredentialTypesCallback = NULL;
 static CAgetPkixInfoHandler g_getPkixInfoCallback = NULL;
 
 /**
+ * @var g_setupPkContextCallback
+ *
+ * @brief callback to setup PK context handler for H/W based Public Key Infrastructure
+ */
+static CAsetupPkContextHandler g_setupPkContextCallback = NULL;
+
+/**
  * @var g_dtlsContextMutex
  * @brief Mutex to synchronize access to g_caSslContext.
  */
-static ca_mutex g_sslContextMutex = NULL;
+static oc_mutex g_sslContextMutex = NULL;
 
 /**
  * @var g_sslCallback
@@ -434,6 +538,28 @@ static ca_mutex g_sslContextMutex = NULL;
 static CAErrorCallback g_sslCallback = NULL;
 
 /**
+ * Data structure for PeerCertCallback.
+ */
+typedef struct
+{
+    PeerCertCallback cb;
+    void *ctx;
+} PeerCertCallback_t;
+
+/**
+ * @var g_peerCertCallback
+ *
+ * @brief callback to utilize peer certificate information
+ */
+static PeerCertCallback_t g_peerCertCallback = {NULL, NULL};
+
+/**
+ * @var g_decryptBuffer
+ * @brief decrypt buffer which will be used for decryption
+ */
+static uint8_t *g_decryptBuffer = NULL;
+
+/**
  * Data structure for holding the data to be received.
  */
 typedef struct SslRecBuf
@@ -455,7 +581,6 @@ typedef struct SslEndPoint
     uint8_t master[MASTER_SECRET_LEN];
     uint8_t random[2*RANDOM_LEN];
 #ifdef __WITH_DTLS__
-    mbedtls_ssl_cookie_ctx cookieCtx;
     mbedtls_timing_delay_context timer;
 #endif // __WITH_DTLS__
 } SslEndPoint_t;
@@ -474,6 +599,14 @@ void CAsetPkixInfoCallback(CAgetPkixInfoHandler infoCallback)
     g_getPkixInfoCallback = infoCallback;
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
 }
+
+void CAsetSetupPkContextCallback(CAsetupPkContextHandler setupPkCtxCallback)
+{
+    OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
+    g_setupPkContextCallback = setupPkCtxCallback;
+    OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
+}
+
 void CAsetCredentialTypesCallback(CAgetCredentialTypesHandler credTypesCallback)
 {
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
@@ -489,6 +622,8 @@ static int GetAdapterIndex(CATransportAdapter_t adapter)
             return 0;
         case CA_ADAPTER_TCP:
             return 1;
+        case CA_ADAPTER_GATT_BTLE:
+            return 2;
         default:
             OIC_LOG(ERROR, NET_SSL_TAG, "Unsupported adapter");
             return -1;
@@ -505,30 +640,37 @@ static int GetAdapterIndex(CATransportAdapter_t adapter)
  */
 static int SendCallBack(void * tep, const unsigned char * data, size_t dataLen)
 {
-    OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
+    OIC_LOG_V(INFO, NET_SSL_TAG, "In %s", __func__);
     VERIFY_NON_NULL_RET(tep, NET_SSL_TAG, "secure endpoint is NULL", -1);
     VERIFY_NON_NULL_RET(data, NET_SSL_TAG, "data is NULL", -1);
+    VERIFY_NON_NULL_RET(g_caSslContext, NET_SSL_TAG, "SSL Context is NULL", -1);
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "Data len: %zu", dataLen);
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "Adapter: %u", ((SslEndPoint_t * )tep)->sep.endpoint.adapter);
     ssize_t sentLen = 0;
     int adapterIndex = GetAdapterIndex(((SslEndPoint_t * )tep)->sep.endpoint.adapter);
-    if (0 == adapterIndex || 1 == adapterIndex)
+    if (0 <= adapterIndex && MAX_SUPPORTED_ADAPTERS > adapterIndex)
     {
         CAPacketSendCallback sendCallback = g_caSslContext->adapterCallbacks[adapterIndex].sendCallback;
         sentLen = sendCallback(&(((SslEndPoint_t * )tep)->sep.endpoint), (const void *) data, dataLen);
-        if (sentLen != dataLen)
+        if (sentLen < 0)
+        {
+            OIC_LOG_V(ERROR, NET_SSL_TAG, "sendCallback() is Failed(%zd)", sentLen);
+            return -1;
+        }
+        else if ((size_t)sentLen != dataLen)
         {
             OIC_LOG_V(DEBUG, NET_SSL_TAG,
-                      "Packet was partially sent - total/sent/remained bytes : %d/%d/%d",
-                      sentLen, dataLen, (dataLen - sentLen));
+                    "Packet was partially sent - total/sent/remained bytes : %zd/%zu/%lu",
+                    sentLen, dataLen, (dataLen - sentLen));
         }
     }
     else
     {
         OIC_LOG(ERROR, NET_SSL_TAG, "Unsupported adapter");
+        return -1;
     }
 
-    OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
+    OIC_LOG_V(INFO, NET_SSL_TAG, "Out %s", __func__);
     return sentLen;
 }
 /**
@@ -557,27 +699,138 @@ static int RecvCallBack(void * tep, unsigned char * data, size_t dataLen)
     return (int)retLen;
 }
 
+static int CASslExportKeysHandler(void *p_expkey,
+                                const unsigned char *ms,
+                                const unsigned char *kb,
+                                size_t maclen,
+                                size_t keylen,
+                                size_t ivlen)
+{
+    OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
+
+    if (NULL == g_caSslContext)
+    {
+        OIC_LOG(ERROR, NET_SSL_TAG, "SSL Context is not initialized.");
+        return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+    }
+    if (NULL == p_expkey)
+    {
+        OIC_LOG(ERROR, NET_SSL_TAG, "Can not find the protocol information from 'p_expkey'.");
+        return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+    }
+
+    CASslEkcbProtocol_t* protocol = (CASslEkcbProtocol_t*)p_expkey;
+
+    if (gTlsExportKeysCallback && CA_SSL_EKCB_TLS == (*protocol))
+    {
+        OIC_LOG(DEBUG, NET_SSL_TAG, "Invoking TLS export key callback.");
+        gTlsExportKeysCallback(ms, kb, maclen, keylen, ivlen);
+    }
+    else if (gDtlsExportKeysCallback && CA_SSL_EKCB_DTLS == (*protocol))
+    {
+        OIC_LOG(DEBUG, NET_SSL_TAG, "Invoking DTLS export key callback.");
+        gDtlsExportKeysCallback(ms, kb, maclen, keylen, ivlen);
+    }
+    else
+    {
+        OIC_LOG(ERROR, NET_SSL_TAG, "Failed to Invoke (D)TLS export key callback.");
+        return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+    }
+
+    OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
+    return 0;
+}
+
+CAResult_t CASetSslExportKeysCallback(SslExportKeysCallback_t exportKeysCb,
+                                      CASslEkcbProtocol_t protocol, CASslEkcbRole_t role)
+{
+    OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
+    mbedtls_ssl_config* sslConf = NULL;
+    static CASslEkcbProtocol_t protocolCtx = CA_SSL_EKCB_TLS;
+
+    if (CA_SSL_EKCB_TLS != protocol && CA_SSL_EKCB_DTLS != protocol)
+    {
+        OIC_LOG(ERROR, NET_SSL_TAG, "Invaild protocol.");
+        return CA_STATUS_INVALID_PARAM;
+    }
+    if (CA_SSL_EKCB_CLIENT != role && CA_SSL_EKCB_SERVER != role)
+    {
+        OIC_LOG(ERROR, NET_SSL_TAG, "Invaild role.");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    OIC_LOG_V(DEBUG, NET_SSL_TAG, "TLS Export Key Callback Type : [%s] [%s]",
+              (CA_SSL_EKCB_TLS == protocol ? "TLS" : "DTLS"),
+              (CA_SSL_EKCB_CLIENT == role ? "Client" : "Server"));
+
+    oc_mutex_lock(g_sslContextMutex);
+    if (NULL == g_caSslContext)
+    {
+        OIC_LOG(ERROR, NET_SSL_TAG, "SSL Context is not initialized.");
+        oc_mutex_unlock(g_sslContextMutex);
+        return CA_STATUS_NOT_INITIALIZED;
+    }
+
+    if (CA_SSL_EKCB_TLS == protocol)
+    {
+        gTlsExportKeysCallback = exportKeysCb;
+        if (CA_SSL_EKCB_CLIENT == role)
+        {
+            sslConf = &g_caSslContext->clientTlsConf;
+        }
+        else
+        {
+            sslConf = &g_caSslContext->serverTlsConf;
+        }
+    }
+    else
+    {
+        gDtlsExportKeysCallback = exportKeysCb;
+        if (CA_SSL_EKCB_CLIENT == role)
+        {
+            sslConf = &g_caSslContext->clientDtlsConf;
+        }
+        else
+        {
+            sslConf = &g_caSslContext->serverDtlsConf;
+        }
+    }
+    protocolCtx = protocol;
+
+    if (NULL == exportKeysCb)
+    {
+        mbedtls_ssl_conf_export_keys_cb(sslConf, NULL, NULL);
+        OIC_LOG(DEBUG, NET_SSL_TAG, "Export key callback unregistered.");
+    }
+    else
+    {
+        mbedtls_ssl_conf_export_keys_cb(sslConf, CASslExportKeysHandler, (void*)(&protocolCtx));
+        OIC_LOG(DEBUG, NET_SSL_TAG, "Export key callback registered.");
+    }
+    oc_mutex_unlock(g_sslContextMutex);
+
+    OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
+
+    return CA_STATUS_OK;
+}
+
 /**
  * Parse chain of X.509 certificates.
  *
  * @param[out] crt     container for X.509 certificates
  * @param[in]  data    buffer with X.509 certificates. Certificates may be in either in PEM
-                       or DER format in a jumble. Each PEM certificate must be NULL-terminated.
+                       or DER format in a jumble, delimiting symbols does not matter.
  * @param[in]  bufLen  buffer length
+ * @param[in]  errNum  number certificates that failed to parse
  *
- * @return  0 on success, -1 on error
+ * @return  number of successfully parsed certificates or -1 on error
  */
-static int ParseChain(mbedtls_x509_crt * crt, const unsigned char * buf, int bufLen)
+static int ParseChain(mbedtls_x509_crt * crt, unsigned char * buf, size_t bufLen, int * errNum)
 {
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
     VERIFY_NON_NULL_RET(crt, NET_SSL_TAG, "Param crt is NULL" , -1);
     VERIFY_NON_NULL_RET(buf, NET_SSL_TAG, "Param buf is NULL" , -1);
 
-    int pos = 0;
-    int ret = 0;
-    size_t len = 0;
-    unsigned char * tmp = NULL;
-
     char pemCertHeader[] = {
         0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52,
         0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d
@@ -589,6 +842,13 @@ static int ParseChain(mbedtls_x509_crt * crt, const unsigned char * buf, int buf
     size_t pemCertHeaderLen = sizeof(pemCertHeader);
     size_t pemCertFooterLen = sizeof(pemCertFooter);
 
+    size_t len = 0;
+    unsigned char * tmp = NULL;
+    int count = 0;
+    int ret = 0;
+    size_t pos = 0;
+
+    *errNum = 0;
     while (pos < bufLen)
     {
         if (buf[pos] == 0x30 && buf[pos + 1] == 0x82)
@@ -597,11 +857,21 @@ static int ParseChain(mbedtls_x509_crt * crt, const unsigned char * buf, int buf
             CHECK_MBEDTLS_RET(mbedtls_asn1_get_len, &tmp, buf + bufLen, &len);
             if (pos + len < bufLen)
             {
-                CHECK_MBEDTLS_RET(mbedtls_x509_crt_parse_der, crt, buf + pos, len + 4);
+                ret = mbedtls_x509_crt_parse_der(crt, buf + pos, len + 4);
+                if (0 == ret)
+                {
+                    count++;
+                }
+                else
+                {
+                    (*errNum)++;
+                    OIC_LOG_V(ERROR, NET_SSL_TAG, "mbedtls_x509_crt_parse_der returned -0x%04x\n", -(ret));
+                }
             }
             pos += len + 4;
         }
-        else if (0 == memcmp(buf + pos, pemCertHeader, pemCertHeaderLen))
+        else if ((buf + pos + pemCertHeaderLen < buf + bufLen) &&
+                 (0 == memcmp(buf + pos, pemCertHeader, pemCertHeaderLen)))
         {
             void * endPos = NULL;
             endPos = memmem(&(buf[pos]), bufLen - pos, pemCertFooter, pemCertFooterLen);
@@ -611,47 +881,124 @@ static int ParseChain(mbedtls_x509_crt * crt, const unsigned char * buf, int buf
                 OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
                 return -1;
             }
-            if ((*((char*)endPos + pemCertFooterLen + 0) == 0x0d) &&
-                (*((char*)endPos + pemCertFooterLen + 1) == 0x0a) &&
-                (*((char*)endPos + pemCertFooterLen + 2) == 0x00))
-            {
-                len = (char*)endPos - ((char*)buf + pos) + pemCertFooterLen + 3;
-            }
-            else if ((*((char*)endPos + pemCertFooterLen + 0) == 0x0a) &&
-                     (*((char*)endPos + pemCertFooterLen + 1) == 0x00))
+            len = (char*)endPos - ((char*)buf + pos) + pemCertFooterLen;
+            if (pos + len + 1 <= bufLen)
             {
-                len = (char*)endPos - ((char*)buf + pos) + pemCertFooterLen + 2;
+                char con = buf[pos + len];
+                buf[pos + len] = 0x00;
+                ret = mbedtls_x509_crt_parse(crt, buf + pos, len + 1);
+                if (0 == ret)
+                {
+                    count++;
+                }
+                else
+                {
+                    (*errNum)++;
+                    OIC_LOG_V(ERROR, NET_SSL_TAG, "mbedtls_x509_crt_parse returned -0x%04x\n", -(ret));
+                }
+                buf[pos + len] = con;
             }
             else
             {
-                OIC_LOG_V(ERROR, NET_SSL_TAG, "Incorrect PEM certificate ending");
-                OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
-                return -1;
+                unsigned char * lastCert = (unsigned char *)OICMalloc((len + 1) * sizeof(unsigned char));
+                memcpy(lastCert, buf + pos, len);
+                lastCert[len] = 0x00;
+                ret = mbedtls_x509_crt_parse(crt, lastCert, len + 1);
+                if (0 == ret)
+                {
+                    count++;
+                }
+                else
+                {
+                    (*errNum)++;
+                    OIC_LOG_V(ERROR, NET_SSL_TAG, "mbedtls_x509_crt_parse returned -0x%04x\n", -(ret));
+                }
+                OICFree(lastCert);
             }
-            CHECK_MBEDTLS_RET(mbedtls_x509_crt_parse, crt, buf + pos, len);
             pos += len;
         }
         else
         {
-             OIC_LOG_BUFFER(DEBUG, NET_SSL_TAG, buf, bufLen);
-             OIC_LOG_V(ERROR, NET_SSL_TAG, "parseChain returned -0x%x", -ret);
-             OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
-             return -1;
+            pos++;
         }
     }
+    OIC_LOG_V(INFO, NET_SSL_TAG, "%s successfully parsed %d certificates", __func__, count);
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
-    return 0;
+    return count;
 
 exit:
     return -1;
 }
 
+static int VerifyCertificateCallback(void *p_vrfy, mbedtls_x509_crt *crt, int depth,
+        uint32_t *flags)
+{
+    (void)p_vrfy;
+    char buf[1024] = {0};
+
+    if (0 != *flags) // Invalid Cerificate
+    {
+        int ret;
+        ret = mbedtls_x509_crt_verify_info(buf, sizeof(buf), "", *flags);
+        if (0 < ret)
+        {
+            OIC_LOG_V(ERROR, NET_SSL_TAG, "%s(%d)", buf, *flags);
+        }
+        return 1;
+    }
+
+    if (NULL == g_peerCertCallback.cb)
+    {
+        OIC_LOG(DEBUG, NET_SSL_TAG, "NOT SET g_peerCertCallback");
+        return 0;
+    }
+
+    /*
+     * e.g.
+     * depth = 0 : Own Cert.
+     * depth = 1 : Sub CA Cert.
+     * depth = 2 : Root CA Cert.
+     */
+    OIC_LOG_V(INFO, NET_SSL_TAG, "Depth : %d", depth);
+
+    mbedtls_x509_crt_info(buf, sizeof(buf) - 1, "", crt);
+    OIC_LOG_V(DEBUG, NET_SSL_TAG, "crt : %s", buf);
+
+    g_peerCertCallback.cb(g_peerCertCallback.ctx, crt, depth);
+
+    return 0;
+}
+
+CAResult_t CAsetPeerCertCallback(void *ctx, PeerCertCallback peerCertCallback)
+{
+#ifndef __WITH_DTLS__
+    UNUSED(ctx);
+    UNUSED(peerCertCallback);
+    OIC_LOG(ERROR, NET_SSL_TAG, "Not Supported");
+    return CA_NOT_SUPPORTED;
+#endif
+
+    if (peerCertCallback)
+    {
+        OIC_LOG(DEBUG, NET_SSL_TAG, "SET peerCertCallback");
+        g_peerCertCallback.cb = peerCertCallback;
+        g_peerCertCallback.ctx = ctx;
+    }
+    else
+    {
+        OIC_LOG(DEBUG, NET_SSL_TAG, "UNSET peerCertCallback");
+        g_peerCertCallback.cb = NULL;
+        g_peerCertCallback.ctx = NULL;
+    }
+    return CA_STATUS_OK;
+}
+
 //Loads PKIX related information from SRM
 static int InitPKIX(CATransportAdapter_t adapter)
 {
-    OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
+    OIC_LOG_V(INFO, NET_SSL_TAG, "In %s", __func__);
     VERIFY_NON_NULL_RET(g_getPkixInfoCallback, NET_SSL_TAG, "PKIX info callback is NULL", -1);
-    g_getPkixInfoCallback(&g_pkiInfo);
+    VERIFY_NON_NULL_RET(g_caSslContext, NET_SSL_TAG, "SSL Context is NULL", -1);
 
     mbedtls_x509_crt_free(&g_caSslContext->ca);
     mbedtls_x509_crt_free(&g_caSslContext->crt);
@@ -663,19 +1010,88 @@ static int InitPKIX(CATransportAdapter_t adapter)
     mbedtls_pk_init(&g_caSslContext->pkey);
     mbedtls_x509_crl_init(&g_caSslContext->crl);
 
-    mbedtls_ssl_config * serverConf = (adapter == CA_ADAPTER_IP ?
+    mbedtls_ssl_config * serverConf = (adapter == CA_ADAPTER_IP ||
+                                   adapter == CA_ADAPTER_GATT_BTLE ?
                                    &g_caSslContext->serverDtlsConf : &g_caSslContext->serverTlsConf);
-    mbedtls_ssl_config * clientConf = (adapter == CA_ADAPTER_IP ?
+    mbedtls_ssl_config * clientConf = (adapter == CA_ADAPTER_IP ||
+                                   adapter == CA_ADAPTER_GATT_BTLE ?
                                    &g_caSslContext->clientDtlsConf : &g_caSslContext->clientTlsConf);
-    // optional
-    int ret = ParseChain(&g_caSslContext->crt, g_pkiInfo.crt.data, g_pkiInfo.crt.len);
-    if (0 != ret)
+
+#ifdef __WITH_DTLS__
+    /*
+     * Conf. is initialized in CAinitSslAdapter()
+     */
+    mbedtls_ssl_conf_verify(&g_caSslContext->clientDtlsConf, VerifyCertificateCallback, NULL);
+#endif
+
+    // load pk key, cert, trust chain and crl
+    if (g_getPkixInfoCallback)
+    {
+        OIC_LOG(INFO, NET_SSL_TAG, "g_getPkixInfoCallback will be invoked");
+        g_getPkixInfoCallback(&g_pkiInfo);
+    }
+
+    // parse own certficate (optional)
+    int ret;
+    int errNum;
+    int count = ParseChain(&g_caSslContext->crt, g_pkiInfo.crt.data, g_pkiInfo.crt.len, &errNum);
+    if (0 >= count)
     {
         OIC_LOG(WARNING, NET_SSL_TAG, "Own certificate chain parsing error");
         goto required;
     }
-    ret =  mbedtls_pk_parse_key(&g_caSslContext->pkey, g_pkiInfo.key.data, g_pkiInfo.key.len,
-                                                                               NULL, 0);
+    if (0 != errNum)
+    {
+        OIC_LOG_V(WARNING, NET_SSL_TAG, "Own certificate chain parsing error: %d certs failed to parse", errNum);
+        goto required;
+    }
+
+    // parse private key if hw is not supported (optional)
+    if(NULL == g_setupPkContextCallback)
+    {
+        OIC_LOG(INFO, NET_SSL_TAG, "g_setupPkContextCallback is NULL");
+        ret =  mbedtls_pk_parse_key(&g_caSslContext->pkey, g_pkiInfo.key.data, g_pkiInfo.key.len,
+                                                                                   NULL, 0);
+    }
+    else
+    {
+        OIC_LOG(INFO, NET_SSL_TAG, "g_setupPkContextCallback will be invoked");
+        // setup hw pk context (optional)
+        ret = g_setupPkContextCallback(&g_caSslContext->pkey);
+        if (0 == ret)
+        {
+            // setup public parameter
+            mbedtls_pk_type_t ktype = mbedtls_pk_get_type(&g_caSslContext->pkey);
+            if (MBEDTLS_PK_ECKEY == ktype || MBEDTLS_PK_ECKEY_DH == ktype
+                || MBEDTLS_PK_ECDSA == ktype)
+            {
+                OIC_LOG_V(DEBUG, NET_SSL_TAG, "Copy ecp public param from cert, keytype [%d]", ktype);
+                mbedtls_ecp_keypair *eckey = (mbedtls_ecp_keypair*)g_caSslContext->crt.pk.pk_ctx;
+                mbedtls_ecdsa_context *ecdsa = (mbedtls_ecdsa_context*)g_caSslContext->pkey.pk_ctx;
+                if (ecdsa && eckey)
+                {
+                    ret = mbedtls_ecdsa_from_keypair(ecdsa, eckey);
+                    if(0 != ret )
+                    {
+                        OIC_LOG_V(ERROR, NET_SSL_TAG, "Fail to copy public param [0x%x]", ret);
+                    }
+                }
+                else
+                {
+                    OIC_LOG_V(WARNING, NET_SSL_TAG, "key-ctx(%p), cert-ctx(%p)", ecdsa, eckey);
+                    goto required;
+                }
+            }
+            else
+            {
+                OIC_LOG_V(INFO, NET_SSL_TAG, "loaded key is not one of eckey type [%d]", ktype);
+            }
+        }
+        else
+        {
+            OIC_LOG_V(ERROR, NET_SSL_TAG, "Fail to call g_setupPkContextCallback [%d]", ret);
+        }
+    }
     if (0 != ret)
     {
         OIC_LOG(WARNING, NET_SSL_TAG, "Key parsing error");
@@ -696,28 +1112,32 @@ static int InitPKIX(CATransportAdapter_t adapter)
     }
 
     required:
-    ret = ParseChain(&g_caSslContext->ca, g_pkiInfo.ca.data, g_pkiInfo.ca.len);
-    if(0 != ret)
+    count = ParseChain(&g_caSslContext->ca, g_pkiInfo.ca.data, g_pkiInfo.ca.len, &errNum);
+    if(0 >= count)
     {
-        OIC_LOG(ERROR, NET_SSL_TAG, "CA chain parsing error");
+        OIC_LOG(WARNING, NET_SSL_TAG, "CA chain in svr db was not parsed");
+        OIC_LOG(WARNING, NET_SSL_TAG, "    but if working as server, chain not required");
         OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
         return -1;
     }
+    if(0 != errNum)
+    {
+        OIC_LOG_V(WARNING, NET_SSL_TAG, "CA chain parsing warning: %d certs failed to parse", errNum);
+    }
 
     ret = mbedtls_x509_crl_parse_der(&g_caSslContext->crl, g_pkiInfo.crl.data, g_pkiInfo.crl.len);
     if(0 != ret)
     {
-        OIC_LOG(WARNING, NET_SSL_TAG, "CRL parsing error");
-        mbedtls_ssl_conf_ca_chain(clientConf, &g_caSslContext->ca, NULL);
-        mbedtls_ssl_conf_ca_chain(serverConf, &g_caSslContext->ca, NULL);
+        OIC_LOG(WARNING, NET_SSL_TAG, "CRL in svr db was not parsed");
+        CONF_SSL(clientConf, serverConf, mbedtls_ssl_conf_ca_chain, &g_caSslContext->ca, NULL);
     }
     else
     {
-        mbedtls_ssl_conf_ca_chain(clientConf, &g_caSslContext->ca, &g_caSslContext->crl);
-        mbedtls_ssl_conf_ca_chain(serverConf, &g_caSslContext->ca, &g_caSslContext->crl);
+        CONF_SSL(clientConf, serverConf, mbedtls_ssl_conf_ca_chain,
+                 &g_caSslContext->ca, &g_caSslContext->crl);
     }
 
-    OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
+    OIC_LOG_V(INFO, NET_SSL_TAG, "Out %s", __func__);
     return 0;
 }
 
@@ -761,6 +1181,7 @@ static int GetPskCredentialsCallback(void * notUsed, mbedtls_ssl_context * ssl,
     OIC_LOG_V(WARNING, NET_SSL_TAG, "Out %s", __func__);
     return -1;
 }
+
 /**
  * Gets session corresponding for endpoint.
  *
@@ -774,6 +1195,7 @@ static SslEndPoint_t *GetSslPeer(const CAEndpoint_t *peer)
     uint32_t listLength = 0;
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
     VERIFY_NON_NULL_RET(peer, NET_SSL_TAG, "TLS peer is NULL", NULL);
+    VERIFY_NON_NULL_RET(g_caSslContext, NET_SSL_TAG, "SSL Context is NULL", NULL);
 
     SslEndPoint_t *tep = NULL;
     listLength = u_arraylist_length(g_caSslContext->peerList);
@@ -784,21 +1206,98 @@ static SslEndPoint_t *GetSslPeer(const CAEndpoint_t *peer)
         {
             continue;
         }
-        OIC_LOG_V(DEBUG, NET_SSL_TAG, "Compare [%s:%d] and [%s:%d]",
-                  peer->addr, peer->port, tep->sep.endpoint.addr, tep->sep.endpoint.port);
-        if((0 == strncmp(peer->addr, tep->sep.endpoint.addr, MAX_ADDR_STR_SIZE_CA))
-                && (peer->port == tep->sep.endpoint.port))
+
+        OIC_LOG_V(DEBUG, NET_SSL_TAG, "Compare [%s:%d] and [%s:%d] for %d adapter",
+                  peer->addr, peer->port, tep->sep.endpoint.addr, tep->sep.endpoint.port,
+                  peer->adapter);
+
+        if((peer->adapter == tep->sep.endpoint.adapter)
+                && (0 == strncmp(peer->addr, tep->sep.endpoint.addr, MAX_ADDR_STR_SIZE_CA))
+                && (peer->port == tep->sep.endpoint.port || CA_ADAPTER_GATT_BTLE == peer->adapter))
         {
+            OIC_LOG_V(DEBUG, NET_SSL_TAG, "Found Peer:[%s:%d] for %d adapter",
+                    peer->addr, peer->port, peer->adapter);
             OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
             return tep;
         }
     }
-    OIC_LOG(DEBUG, NET_SSL_TAG, "Return NULL");
+    OIC_LOG_V(INFO, NET_SSL_TAG, "Peer not found:[%s:%d] for %d adapter",
+            peer->addr, peer->port, peer->adapter);
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
     return NULL;
 }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+bool CAIsExistSslPeer(const CAEndpoint_t *peer)
+{
+    oc_mutex_lock(g_sslContextMutex);
+    if (NULL == g_caSslContext)
+    {
+        OIC_LOG(ERROR, NET_SSL_TAG, "Context is NULL");
+        oc_mutex_unlock(g_sslContextMutex);
+        return false;
+    }
+
+    if (GetSslPeer(peer))
+    {
+        OIC_LOG_V(DEBUG, NET_SSL_TAG, "Exist Peer");
+        oc_mutex_unlock(g_sslContextMutex);
+        return true;
+    }
+    else
+    {
+        OIC_LOG_V(DEBUG, NET_SSL_TAG, "Not Exist Peer");
+        oc_mutex_unlock(g_sslContextMutex);
+        return false;
+    }
+}
+
+/**
+ * Gets session corresponding for endpoint.
+ *
+ * @param[in]  peer    remote address
+ *
+ * @return  TLS session or NULL
+ */
+static SslEndPoint_t *GetSslPeerUsingUuid(const uint8_t *identity, size_t idLength)
+{
+    uint32_t listIndex = 0;
+    uint32_t listLength = 0;
+    OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
+    VERIFY_NON_NULL_RET(identity, NET_SSL_TAG, "Param identity is NULL", NULL);
+    VERIFY_NON_NULL_RET(g_caSslContext, NET_SSL_TAG, "SSL Context is NULL", NULL);
+
+    OIC_LOG(INFO, NET_SSL_TAG, "[Target UUID]");
+    OIC_LOG_BUFFER(INFO, NET_SSL_TAG, identity, idLength);
+
+    SslEndPoint_t *tep = NULL;
+    listLength = u_arraylist_length(g_caSslContext->peerList);
+    for (listIndex = 0; listIndex < listLength; listIndex++)
+    {
+        tep = (SslEndPoint_t *) u_arraylist_get(g_caSslContext->peerList, listIndex);
+        if (NULL == tep)
+        {
+            continue;
+        }
+
+        OIC_LOG_V(DEBUG, NET_SSL_TAG, "Compare UUID for [%s:%d]",
+                  tep->sep.endpoint.addr, tep->sep.endpoint.port);
+
+        if ((tep->sep.identity.id_length == idLength)
+            && (0 == memcmp(identity, tep->sep.identity.id, idLength)))
+        {
+            OIC_LOG_V(INFO, NET_SSL_TAG, "Found matched UUID in [%s:%d]",
+                      tep->sep.endpoint.addr, tep->sep.endpoint.port);
+            OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
+            return tep;
+        }
+    }
+    OIC_LOG(INFO, NET_SSL_TAG, "Peer not found");
+    OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
+    return NULL;
+}
+
+
+#ifdef MULTIPLE_OWNER
 /**
  * Gets CA secure endpoint info corresponding for endpoint.
  *
@@ -811,13 +1310,13 @@ const CASecureEndpoint_t *GetCASecureEndpointData(const CAEndpoint_t* peer)
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
 
     // TODO: Added as workaround, need to debug
-    ca_mutex_unlock(g_sslContextMutex);
+    oc_mutex_unlock(g_sslContextMutex);
 
-    ca_mutex_lock(g_sslContextMutex);
+    oc_mutex_lock(g_sslContextMutex);
     if (NULL == g_caSslContext)
     {
         OIC_LOG(ERROR, NET_SSL_TAG, "Context is NULL");
-        ca_mutex_unlock(g_sslContextMutex);
+        oc_mutex_unlock(g_sslContextMutex);
         return NULL;
     }
 
@@ -825,13 +1324,13 @@ const CASecureEndpoint_t *GetCASecureEndpointData(const CAEndpoint_t* peer)
     if(sslPeer)
     {
         OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
-        ca_mutex_unlock(g_sslContextMutex);
+        oc_mutex_unlock(g_sslContextMutex);
         return &sslPeer->sep;
     }
 
     OIC_LOG(DEBUG, NET_SSL_TAG, "Return NULL");
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
-    ca_mutex_unlock(g_sslContextMutex);
+    oc_mutex_unlock(g_sslContextMutex);
     return NULL;
 }
 #endif
@@ -887,9 +1386,6 @@ static void DeleteSslEndPoint(SslEndPoint_t * tep)
     VERIFY_NON_NULL_VOID(tep, NET_SSL_TAG, "tep");
 
     mbedtls_ssl_free(&tep->ssl);
-#ifdef __WITH_DTLS__
-    mbedtls_ssl_cookie_free(&tep->cookieCtx);
-#endif
     DeleteCacheList(tep->cacheList);
     OICFree(tep);
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
@@ -899,10 +1395,12 @@ static void DeleteSslEndPoint(SslEndPoint_t * tep)
  *
  * @param[in]  endpoint    remote address
  */
-static void RemovePeerFromList(CAEndpoint_t * endpoint)
+static void RemovePeerFromList(const CAEndpoint_t * endpoint)
 {
-    uint32_t listLength = u_arraylist_length(g_caSslContext->peerList);
+    OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
+    VERIFY_NON_NULL_VOID(g_caSslContext, NET_SSL_TAG, "SSL Context is NULL");
     VERIFY_NON_NULL_VOID(endpoint, NET_SSL_TAG, "endpoint");
+    uint32_t listLength = u_arraylist_length(g_caSslContext->peerList);
     for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
     {
         SslEndPoint_t * tep = (SslEndPoint_t *)u_arraylist_get(g_caSslContext->peerList,listIndex);
@@ -911,19 +1409,28 @@ static void RemovePeerFromList(CAEndpoint_t * endpoint)
             continue;
         }
         if(0 == strncmp(endpoint->addr, tep->sep.endpoint.addr, MAX_ADDR_STR_SIZE_CA)
-                && (endpoint->port == tep->sep.endpoint.port))
+                && (endpoint->port == tep->sep.endpoint.port || CA_ADAPTER_GATT_BTLE == endpoint->adapter))
         {
             u_arraylist_remove(g_caSslContext->peerList, listIndex);
             DeleteSslEndPoint(tep);
+            OIC_LOG_V(INFO, NET_SSL_TAG, "Remove Peer:[%s:%d] for %d adapter",
+                    endpoint->addr, endpoint->port, endpoint->adapter);
+            OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
             return;
         }
     }
+    OIC_LOG_V(INFO, NET_SSL_TAG, "Peer not found:[%s:%d] for %d adapter",
+            endpoint->addr, endpoint->port, endpoint->adapter);
+    OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
 }
 /**
  * Deletes session list.
  */
 static void DeletePeerList()
 {
+    OIC_LOG_V(DEBUG, NET_SSL_TAG, "%s", __func__);
+    VERIFY_NON_NULL_VOID(g_caSslContext, NET_SSL_TAG, "SSL Context is NULL");
+
     uint32_t listLength = u_arraylist_length(g_caSslContext->peerList);
     for (uint32_t listIndex = 0; listIndex < listLength; listIndex++)
     {
@@ -932,30 +1439,75 @@ static void DeletePeerList()
         {
             continue;
         }
+        if (MBEDTLS_SSL_HANDSHAKE_OVER == tep->ssl.state)
+        {
+            int ret = 0;
+            do
+            {
+                ret = mbedtls_ssl_close_notify(&tep->ssl);
+            }
+            while (MBEDTLS_ERR_SSL_WANT_WRITE == ret);
+        }
         DeleteSslEndPoint(tep);
     }
     u_arraylist_free(&g_caSslContext->peerList);
 }
 
-CAResult_t CAcloseSslConnection(const CAEndpoint_t *endpoint)
+CAResult_t CAcloseSslConnection(const CAEndpoint_t *endpoint)
+{
+    OIC_LOG_V(INFO, NET_SSL_TAG, "In %s", __func__);
+    VERIFY_NON_NULL_RET(endpoint, NET_SSL_TAG, "Param endpoint is NULL" , CA_STATUS_INVALID_PARAM);
+
+    oc_mutex_lock(g_sslContextMutex);
+    if (NULL == g_caSslContext)
+    {
+        OIC_LOG(ERROR, NET_SSL_TAG, "Context is NULL");
+        oc_mutex_unlock(g_sslContextMutex);
+        return CA_STATUS_FAILED;
+    }
+    SslEndPoint_t * tep = GetSslPeer(endpoint);
+    if (NULL == tep)
+    {
+        OIC_LOG(ERROR, NET_SSL_TAG, "Session does not exist");
+        oc_mutex_unlock(g_sslContextMutex);
+        return CA_STATUS_FAILED;
+    }
+    /* No error checking, the connection might be closed already */
+    int ret = 0;
+    do
+    {
+        ret = mbedtls_ssl_close_notify(&tep->ssl);
+    }
+    while (MBEDTLS_ERR_SSL_WANT_WRITE == ret);
+
+    RemovePeerFromList(&tep->sep.endpoint);
+    oc_mutex_unlock(g_sslContextMutex);
+
+    OIC_LOG_V(INFO, NET_SSL_TAG, "Out %s", __func__);
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAcloseSslConnectionUsingUuid(const uint8_t *identity, size_t idLength)
 {
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
-    VERIFY_NON_NULL_RET(endpoint, NET_SSL_TAG, "Param endpoint is NULL" , CA_STATUS_INVALID_PARAM);
+    VERIFY_NON_NULL_RET(identity, NET_SSL_TAG, "Param identity is NULL" , CA_STATUS_INVALID_PARAM);
 
-    ca_mutex_lock(g_sslContextMutex);
+    oc_mutex_lock(g_sslContextMutex);
     if (NULL == g_caSslContext)
     {
         OIC_LOG(ERROR, NET_SSL_TAG, "Context is NULL");
-        ca_mutex_unlock(g_sslContextMutex);
+        oc_mutex_unlock(g_sslContextMutex);
         return CA_STATUS_FAILED;
     }
-    SslEndPoint_t * tep = GetSslPeer(endpoint);
+
+    SslEndPoint_t* tep = GetSslPeerUsingUuid(identity, idLength);
     if (NULL == tep)
     {
         OIC_LOG(ERROR, NET_SSL_TAG, "Session does not exist");
-        ca_mutex_unlock(g_sslContextMutex);
+        oc_mutex_unlock(g_sslContextMutex);
         return CA_STATUS_FAILED;
     }
+
     /* No error checking, the connection might be closed already */
     int ret = 0;
     do
@@ -965,33 +1517,42 @@ CAResult_t CAcloseSslConnection(const CAEndpoint_t *endpoint)
     while (MBEDTLS_ERR_SSL_WANT_WRITE == ret);
 
     RemovePeerFromList(&tep->sep.endpoint);
-    ca_mutex_unlock(g_sslContextMutex);
+    oc_mutex_unlock(g_sslContextMutex);
 
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
     return CA_STATUS_OK;
 }
 
-void CAcloseSslConnectionAll()
+void CAcloseSslConnectionAll(CATransportAdapter_t transportType)
 {
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
-    ca_mutex_lock(g_sslContextMutex);
+    oc_mutex_lock(g_sslContextMutex);
     if (NULL == g_caSslContext)
     {
         OIC_LOG(ERROR, NET_SSL_TAG, "Context is NULL");
-        ca_mutex_unlock(g_sslContextMutex);
+        oc_mutex_unlock(g_sslContextMutex);
         return;
     }
 
     uint32_t listLength = u_arraylist_length(g_caSslContext->peerList);
+    OIC_LOG_V(INFO, NET_SSL_TAG,
+            "Required transport [%d], peer count [%d]", transportType, listLength);
     for (uint32_t i = listLength; i > 0; i--)
     {
-        SslEndPoint_t *tep = (SslEndPoint_t *)u_arraylist_remove(g_caSslContext->peerList, i - 1);
+        SslEndPoint_t *tep = (SslEndPoint_t *)u_arraylist_get(g_caSslContext->peerList, i - 1);
         if (NULL == tep)
         {
             continue;
         }
-        OIC_LOG_V(DEBUG, NET_SSL_TAG, "SSL Connection [%s:%d]",
-                  tep->sep.endpoint.addr, tep->sep.endpoint.port);
+        OIC_LOG_V(INFO, NET_SSL_TAG, "SSL Connection [%s:%d], Transport [%d]",
+                  tep->sep.endpoint.addr, tep->sep.endpoint.port, tep->sep.endpoint.adapter);
+
+        // check transport matching
+        if (0 == (tep->sep.endpoint.adapter & transportType))
+        {
+            OIC_LOG(DEBUG, NET_SSL_TAG, "Skip the un-matched transport session");
+            continue;
+        }
 
         // TODO: need to check below code after socket close is ensured.
         /*int ret = 0;
@@ -1001,9 +1562,11 @@ void CAcloseSslConnectionAll()
         }
         while (MBEDTLS_ERR_SSL_WANT_WRITE == ret);*/
 
+        // delete from list
+        u_arraylist_remove(g_caSslContext->peerList, i - 1);
         DeleteSslEndPoint(tep);
     }
-    ca_mutex_unlock(g_sslContextMutex);
+    oc_mutex_unlock(g_sslContextMutex);
 
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
     return;
@@ -1019,9 +1582,10 @@ void CAcloseSslConnectionAll()
 static SslEndPoint_t * NewSslEndPoint(const CAEndpoint_t * endpoint, mbedtls_ssl_config * config)
 {
     SslEndPoint_t * tep = NULL;
-    OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
+    OIC_LOG_V(INFO, NET_SSL_TAG, "In %s", __func__);
     VERIFY_NON_NULL_RET(endpoint, NET_SSL_TAG, "endpoint", NULL);
     VERIFY_NON_NULL_RET(config, NET_SSL_TAG, "config", NULL);
+    VERIFY_NON_NULL_RET(g_caSslContext, NET_SSL_TAG, "SSL Context is NULL", NULL);
 
     tep = (SslEndPoint_t *) OICCalloc(1, sizeof (SslEndPoint_t));
     if (NULL == tep)
@@ -1037,7 +1601,7 @@ static SslEndPoint_t * NewSslEndPoint(const CAEndpoint_t * endpoint, mbedtls_ssl
     {
         OIC_LOG(ERROR, NET_SSL_TAG, "Setup failed");
         OICFree(tep);
-        OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
+        OIC_LOG_V(INFO, NET_SSL_TAG, "Out %s", __func__);
         return NULL;
     }
 
@@ -1048,20 +1612,11 @@ static SslEndPoint_t * NewSslEndPoint(const CAEndpoint_t * endpoint, mbedtls_ssl
                                   mbedtls_timing_set_delay, mbedtls_timing_get_delay);
         if (MBEDTLS_SSL_IS_SERVER == config->endpoint)
         {
-            if (0 != mbedtls_ssl_cookie_setup(&tep->cookieCtx, mbedtls_ctr_drbg_random,
-                                              &g_caSslContext->rnd))
-            {
-                OIC_LOG(ERROR, NET_SSL_TAG, "Cookie setup failed!");
-                OICFree(tep);
-                OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
-                return NULL;
-            }
-            mbedtls_ssl_conf_dtls_cookies(config, mbedtls_ssl_cookie_write, mbedtls_ssl_cookie_check,
-                                          &tep->cookieCtx);
             if (0 != mbedtls_ssl_set_client_transport_id(&tep->ssl,
                                     (const unsigned char *) endpoint->addr, sizeof(endpoint->addr)))
             {
                 OIC_LOG(ERROR, NET_SSL_TAG, "Transport id setup failed!");
+                mbedtls_ssl_free(&tep->ssl);
                 OICFree(tep);
                 OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
                 return NULL;
@@ -1077,6 +1632,9 @@ static SslEndPoint_t * NewSslEndPoint(const CAEndpoint_t * endpoint, mbedtls_ssl
         OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
         return NULL;
     }
+    OIC_LOG_V(INFO, NET_SSL_TAG, "New [%s role] endpoint added [%s:%d]",
+            (MBEDTLS_SSL_IS_SERVER==config->endpoint ? "server" : "client"),
+            endpoint->addr, endpoint->port);
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
     return tep;
 }
@@ -1089,17 +1647,20 @@ static SslEndPoint_t * NewSslEndPoint(const CAEndpoint_t * endpoint, mbedtls_ssl
  */
 static int InitPskIdentity(mbedtls_ssl_config * config)
 {
+    uint8_t keyBuf[PSK_LENGTH] = {0};
     uint8_t idBuf[UUID_LENGTH] = {0};
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
     VERIFY_NON_NULL_RET(config, NET_SSL_TAG, "Param config is NULL" , -1);
 
+    //Retrieve PSK identity from SVR DB
     if (0 > g_getCredentialsCallback(CA_DTLS_PSK_IDENTITY, NULL, 0, idBuf, UUID_LENGTH))
     {
         OIC_LOG(ERROR, NET_SSL_TAG, "Identity not found");
         OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
         return -1;
     }
-    if (0 != mbedtls_ssl_conf_psk(config, idBuf, 0, idBuf, UUID_LENGTH))
+    //Store PSK ideneity in mbedtls_ssl_config
+    if (0 != mbedtls_ssl_conf_psk(config, keyBuf, PSK_LENGTH, idBuf, UUID_LENGTH))
     {
         OIC_LOG(ERROR, NET_SSL_TAG, "Identity initialization failed!");
         OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
@@ -1112,22 +1673,23 @@ static void SetupCipher(mbedtls_ssl_config * config, CATransportAdapter_t adapte
 {
     int index = 0;
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
-    if (NULL == g_getCredentialTypesCallback)
-    {
-        OIC_LOG(ERROR, NET_SSL_TAG, "Param callback is null");
-        return;
-    }
+    VERIFY_NON_NULL_VOID(config, NET_SSL_TAG, "Invaild param");
+    VERIFY_NON_NULL_VOID(g_caSslContext, NET_SSL_TAG, "SSL Context is NULL");
+    VERIFY_NON_NULL_VOID(g_getCredentialTypesCallback, NET_SSL_TAG, "Param callback is null");
+
+    //Resetting cipherFlag
+    g_caSslContext->cipherFlag[0] = false;
+    g_caSslContext->cipherFlag[1] = false;
 
     g_getCredentialTypesCallback(g_caSslContext->cipherFlag);
     // Retrieve the PSK credential from SRM
-    // PIN OTM if (true == g_caSslContext->cipherFlag[0] && 0 != InitPskIdentity(config))
     if (0 != InitPskIdentity(config))
     {
         OIC_LOG(ERROR, NET_SSL_TAG, "PSK identity initialization failed!");
     }
 
-    // Retrieve the ECC credential from SRM
-    if (true == g_caSslContext->cipherFlag[1] || ADAPTER_TLS_RSA_WITH_AES_256_CBC_SHA == g_caSslContext->cipher)
+    // Retrieve the Cert credential from SRM
+    if (true == g_caSslContext->cipherFlag[1])
     {
         int ret = InitPKIX(adapter);
         if (0 != ret)
@@ -1137,19 +1699,47 @@ static void SetupCipher(mbedtls_ssl_config * config, CATransportAdapter_t adapte
     }
 
     memset(g_cipherSuitesList, 0, sizeof(g_cipherSuitesList));
-    if (ADAPTER_CIPHER_MAX != g_caSslContext->cipher)
+
+    // Add the preferred ciphersuite first
+    if (SSL_CIPHER_MAX != g_caSslContext->cipher)
     {
         g_cipherSuitesList[index] = tlsCipher[g_caSslContext->cipher][0];
-        index ++;
+        OIC_LOG_V(DEBUG, NET_SSL_TAG, "Preferred ciphersuite added");
+        index++;
     }
+
+    // Add PSK ciphersuite
+    if (true == g_caSslContext->cipherFlag[0] &&
+                MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 != tlsCipher[g_caSslContext->cipher][0])
+    {
+       g_cipherSuitesList[index] = MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256;
+       OIC_LOG(DEBUG, NET_SSL_TAG, "PSK ciphersuite added");
+       index++;
+    }
+
+    // Add all certificate ciphersuites
     if (true == g_caSslContext->cipherFlag[1])
     {
-        g_cipherSuitesList[index] = MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8;
-        index ++;
+        for (unsigned int i = 0; i < SSL_CIPHER_MAX - 1; i++)
+        {
+            if (MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 != tlsCipher[i][0] &&
+                i != g_caSslContext->cipher)
+            {
+                g_cipherSuitesList[index] = tlsCipher[i][0];
+                index ++;
+            }
+        }
+
+        if (MBEDTLS_SSL_IS_SERVER == config->endpoint)
+        {
+            mbedtls_ssl_conf_authmode(config, MBEDTLS_SSL_VERIFY_OPTIONAL);
+        }
     }
-    if (true == g_caSslContext->cipherFlag[0])
+
+    OIC_LOG(INFO, NET_SSL_TAG, "Supported ciphersuites:");
+    for (int i = 0; i < index; i++)
     {
-       g_cipherSuitesList[index] = MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256;
+        OIC_LOG_V(INFO, NET_SSL_TAG, "Ciphersuite %04x", g_cipherSuitesList[i]);
     }
 
     mbedtls_ssl_conf_ciphersuites(config, g_cipherSuitesList);
@@ -1168,11 +1758,15 @@ static SslEndPoint_t * InitiateTlsHandshake(const CAEndpoint_t *endpoint)
     int ret = 0;
     SslEndPoint_t * tep = NULL;
 
-    OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
+    OIC_LOG_V(INFO, NET_SSL_TAG, "In %s", __func__);
     VERIFY_NON_NULL_RET(endpoint, NET_SSL_TAG, "Param endpoint is NULL" , NULL);
+    VERIFY_NON_NULL_RET(g_caSslContext, NET_SSL_TAG, "SSL Context is NULL", NULL);
 
+    //Remove previous peer info from peer list.
+    RemovePeerFromList(endpoint);
 
-    mbedtls_ssl_config * config = (endpoint->adapter == CA_ADAPTER_IP ?
+    mbedtls_ssl_config * config = (endpoint->adapter == CA_ADAPTER_IP ||
+                                   endpoint->adapter == CA_ADAPTER_GATT_BTLE ?
                                    &g_caSslContext->clientDtlsConf : &g_caSslContext->clientTlsConf);
     tep = NewSslEndPoint(endpoint, config);
     if (NULL == tep)
@@ -1184,7 +1778,6 @@ static SslEndPoint_t * InitiateTlsHandshake(const CAEndpoint_t *endpoint)
     //Load allowed SVR suites from SVR DB
     SetupCipher(config, endpoint->adapter);
 
-    OIC_LOG_V(DEBUG, NET_SSL_TAG, "Add %s:%d", tep->sep.endpoint.addr, tep->sep.endpoint.port);
     ret = u_arraylist_add(g_caSslContext->peerList, (void *) tep);
     if (!ret)
     {
@@ -1200,9 +1793,15 @@ static SslEndPoint_t * InitiateTlsHandshake(const CAEndpoint_t *endpoint)
         {
             break;
         }
+        else if (-1 == ret)
+        {
+            OIC_LOG(ERROR, NET_SSL_TAG, "Handshake failed due to socket error");
+            RemovePeerFromList(&tep->sep.endpoint);
+            return NULL;
+        }
         SSL_CHECK_FAIL(tep, ret, "Handshake error", 0, NULL, MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
     }
-    OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
+    OIC_LOG_V(INFO, NET_SSL_TAG, "Out %s", __func__);
     return tep;
 }
 #ifdef __WITH_DTLS__
@@ -1214,6 +1813,7 @@ static void StopRetransmit()
     if (g_caSslContext)
     {
         unregisterTimer(g_caSslContext->timerId);
+        g_caSslContext->timerId= -1;
     }
 }
 #endif
@@ -1225,14 +1825,16 @@ void CAdeinitSslAdapter()
     VERIFY_NON_NULL_VOID(g_sslContextMutex, NET_SSL_TAG, "context mutex is NULL");
 
     //Lock tlsContext mutex
-    ca_mutex_lock(g_sslContextMutex);
+    oc_mutex_lock(g_sslContextMutex);
 
     // Clear all lists
     DeletePeerList();
 
     // De-initialize mbedTLS
+    mbedtls_x509_crt_free(&g_caSslContext->ca);
     mbedtls_x509_crt_free(&g_caSslContext->crt);
     mbedtls_pk_free(&g_caSslContext->pkey);
+    mbedtls_x509_crl_free(&g_caSslContext->crl);
 #ifdef __WITH_TLS__
     mbedtls_ssl_config_free(&g_caSslContext->clientTlsConf);
     mbedtls_ssl_config_free(&g_caSslContext->serverTlsConf);
@@ -1240,6 +1842,7 @@ void CAdeinitSslAdapter()
 #ifdef __WITH_DTLS__
     mbedtls_ssl_config_free(&g_caSslContext->clientDtlsConf);
     mbedtls_ssl_config_free(&g_caSslContext->serverDtlsConf);
+    mbedtls_ssl_cookie_free(&g_caSslContext->cookieCtx);
 #endif // __WITH_DTLS__
     mbedtls_ctr_drbg_free(&g_caSslContext->rnd);
     mbedtls_entropy_free(&g_caSslContext->entropy);
@@ -1250,9 +1853,16 @@ void CAdeinitSslAdapter()
     OICFree(g_caSslContext);
     g_caSslContext = NULL;
 
+    // Delete decrypt buffer
+    if (g_decryptBuffer)
+    {
+        OICFree(g_decryptBuffer);
+        g_decryptBuffer = NULL;
+    }
+
     // Unlock tlsContext mutex and de-initialize it
-    ca_mutex_unlock(g_sslContextMutex);
-    ca_mutex_free(g_sslContextMutex);
+    oc_mutex_unlock(g_sslContextMutex);
+    oc_mutex_free(g_sslContextMutex);
     g_sslContextMutex = NULL;
 
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s ", __func__);
@@ -1262,6 +1872,7 @@ static int InitConfig(mbedtls_ssl_config * conf, int transport, int mode)
 {
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
     VERIFY_NON_NULL_RET(conf, NET_SSL_TAG, "Param conf is NULL" , -1);
+    VERIFY_NON_NULL_RET(g_caSslContext, NET_SSL_TAG, "SSL Context is NULL", -1);
     mbedtls_ssl_config_init(conf);
     if (mbedtls_ssl_config_defaults(conf, mode, transport, MBEDTLS_SSL_PRESET_DEFAULT) != 0)
     {
@@ -1275,6 +1886,16 @@ static int InitConfig(mbedtls_ssl_config * conf, int transport, int mode)
     mbedtls_ssl_conf_min_version(conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3);
     mbedtls_ssl_conf_renegotiation(conf, MBEDTLS_SSL_RENEGOTIATION_DISABLED);
     mbedtls_ssl_conf_authmode(conf, MBEDTLS_SSL_VERIFY_REQUIRED);
+    mbedtls_ssl_conf_sig_hashes(conf, g_ssl_ordered_default_hashes);
+
+#ifdef __WITH_DTLS__
+    if (MBEDTLS_SSL_TRANSPORT_DATAGRAM == transport &&
+            MBEDTLS_SSL_IS_SERVER == mode)
+    {
+        mbedtls_ssl_conf_dtls_cookies(conf, mbedtls_ssl_cookie_write, mbedtls_ssl_cookie_check,
+                                      &g_caSslContext->cookieCtx);
+    }
+#endif // __WITH_DTLS__
 
 #if !defined(NDEBUG) || defined(TB_LOG)
     mbedtls_ssl_conf_dbg(conf, DebugSsl, NULL);
@@ -1292,39 +1913,48 @@ static int StartRetransmit()
     uint32_t listIndex = 0;
     uint32_t listLength = 0;
     SslEndPoint_t *tep = NULL;
+
+    oc_mutex_lock(g_sslContextMutex);
     if (NULL == g_caSslContext)
     {
         OIC_LOG(ERROR, NET_SSL_TAG, "Context is NULL. Stop retransmission");
+        oc_mutex_unlock(g_sslContextMutex);
         return -1;
     }
-    ca_mutex_lock(g_sslContextMutex);
     if (g_caSslContext->timerId != -1)
     {
         //clear previous timer
         unregisterTimer(g_caSslContext->timerId);
 
         listLength = u_arraylist_length(g_caSslContext->peerList);
+
         for (listIndex = 0; listIndex < listLength; listIndex++)
         {
             tep = (SslEndPoint_t *) u_arraylist_get(g_caSslContext->peerList, listIndex);
             if (NULL == tep
-                || MBEDTLS_SSL_TRANSPORT_STREAM == tep->ssl.conf->transport
+                || (tep->ssl.conf && MBEDTLS_SSL_TRANSPORT_STREAM == tep->ssl.conf->transport)
                 || MBEDTLS_SSL_HANDSHAKE_OVER == tep->ssl.state)
             {
                 continue;
             }
+            OIC_LOG_V(INFO, NET_SSL_TAG, "peer #%d", (int) listIndex);
+
             int ret = mbedtls_ssl_handshake_step(&tep->ssl);
 
             if (MBEDTLS_ERR_SSL_CONN_EOF != ret)
             {
-                SSL_CHECK_FAIL(tep, ret, "Retransmission", NULL, -1,
+                //start new timer
+                registerTimer(RETRANSMISSION_TIME, &g_caSslContext->timerId, (void *) StartRetransmit);
+                //unlock & return
+                SSL_CHECK_FAIL(tep, ret, "Retransmission", 1, CA_STATUS_FAILED,
                 MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
             }
         }
     }
     //start new timer
     registerTimer(RETRANSMISSION_TIME, &g_caSslContext->timerId, (void *) StartRetransmit);
-    ca_mutex_unlock(g_sslContextMutex);
+    oc_mutex_unlock(g_sslContextMutex);
+
     return 0;
 }
 #endif
@@ -1335,7 +1965,7 @@ CAResult_t CAinitSslAdapter()
     // Initialize mutex for tlsContext
     if (NULL == g_sslContextMutex)
     {
-        g_sslContextMutex = ca_mutex_new();
+        g_sslContextMutex = oc_mutex_new();
         VERIFY_NON_NULL_RET(g_sslContextMutex, NET_SSL_TAG, "malloc failed", CA_MEMORY_ALLOC_FAILED);
     }
     else
@@ -1345,14 +1975,14 @@ CAResult_t CAinitSslAdapter()
     }
 
     // Lock tlsContext mutex and create tlsContext
-    ca_mutex_lock(g_sslContextMutex);
+    oc_mutex_lock(g_sslContextMutex);
     g_caSslContext = (SslContext_t *)OICCalloc(1, sizeof(SslContext_t));
 
     if (NULL == g_caSslContext)
     {
         OIC_LOG(ERROR, NET_SSL_TAG, "Context malloc failed");
-        ca_mutex_unlock(g_sslContextMutex);
-        ca_mutex_free(g_sslContextMutex);
+        oc_mutex_unlock(g_sslContextMutex);
+        oc_mutex_free(g_sslContextMutex);
         g_sslContextMutex = NULL;
         return CA_MEMORY_ALLOC_FAILED;
     }
@@ -1365,8 +1995,8 @@ CAResult_t CAinitSslAdapter()
         OIC_LOG(ERROR, NET_SSL_TAG, "peerList initialization failed!");
         OICFree(g_caSslContext);
         g_caSslContext = NULL;
-        ca_mutex_unlock(g_sslContextMutex);
-        ca_mutex_free(g_sslContextMutex);
+        oc_mutex_unlock(g_sslContextMutex);
+        oc_mutex_free(g_sslContextMutex);
         g_sslContextMutex = NULL;
         return CA_STATUS_FAILED;
     }
@@ -1391,7 +2021,7 @@ CAResult_t CAinitSslAdapter()
     if(urandomFd == -1)
     {
         OIC_LOG(ERROR, NET_SSL_TAG, "Fails open /dev/urandom!");
-        ca_mutex_unlock(g_sslContextMutex);
+        oc_mutex_unlock(g_sslContextMutex);
         CAdeinitSslAdapter();
         return CA_STATUS_FAILED;
     }
@@ -1399,7 +2029,7 @@ CAResult_t CAinitSslAdapter()
     {
         OIC_LOG(ERROR, NET_SSL_TAG, "Fails read from /dev/urandom!");
         close(urandomFd);
-        ca_mutex_unlock(g_sslContextMutex);
+        oc_mutex_unlock(g_sslContextMutex);
         CAdeinitSslAdapter();
         return CA_STATUS_FAILED;
     }
@@ -1412,7 +2042,7 @@ CAResult_t CAinitSslAdapter()
                                   &g_caSslContext->entropy, seed, sizeof(SEED)))
     {
         OIC_LOG(ERROR, NET_SSL_TAG, "Seed initialization failed!");
-        ca_mutex_unlock(g_sslContextMutex);
+        oc_mutex_unlock(g_sslContextMutex);
         CAdeinitSslAdapter();
         return CA_STATUS_FAILED;
     }
@@ -1423,7 +2053,7 @@ CAResult_t CAinitSslAdapter()
                         MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_IS_CLIENT))
     {
         OIC_LOG(ERROR, NET_SSL_TAG, "Client config initialization failed!");
-        ca_mutex_unlock(g_sslContextMutex);
+        oc_mutex_unlock(g_sslContextMutex);
         CAdeinitSslAdapter();
         OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
         return CA_STATUS_FAILED;
@@ -1433,18 +2063,29 @@ CAResult_t CAinitSslAdapter()
                         MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_IS_SERVER))
     {
         OIC_LOG(ERROR, NET_SSL_TAG, "Server config initialization failed!");
-        ca_mutex_unlock(g_sslContextMutex);
+        oc_mutex_unlock(g_sslContextMutex);
         CAdeinitSslAdapter();
         OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
         return CA_STATUS_FAILED;
     }
 #endif // __WITH_TLS__
 #ifdef __WITH_DTLS__
+    mbedtls_ssl_cookie_init(&g_caSslContext->cookieCtx);
+    if (0 != mbedtls_ssl_cookie_setup(&g_caSslContext->cookieCtx, mbedtls_ctr_drbg_random,
+                                      &g_caSslContext->rnd))
+    {
+        OIC_LOG(ERROR, NET_SSL_TAG, "Cookie setup failed!");
+        oc_mutex_unlock(g_sslContextMutex);
+        CAdeinitSslAdapter();
+        OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
+        return CA_STATUS_FAILED;
+    }
+
     if (0 != InitConfig(&g_caSslContext->clientDtlsConf,
                         MBEDTLS_SSL_TRANSPORT_DATAGRAM, MBEDTLS_SSL_IS_CLIENT))
     {
         OIC_LOG(ERROR, NET_SSL_TAG, "Client config initialization failed!");
-        ca_mutex_unlock(g_sslContextMutex);
+        oc_mutex_unlock(g_sslContextMutex);
         CAdeinitSslAdapter();
         OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
         return CA_STATUS_FAILED;
@@ -1454,7 +2095,7 @@ CAResult_t CAinitSslAdapter()
                         MBEDTLS_SSL_TRANSPORT_DATAGRAM, MBEDTLS_SSL_IS_SERVER))
     {
         OIC_LOG(ERROR, NET_SSL_TAG, "Server config initialization failed!");
-        ca_mutex_unlock(g_sslContextMutex);
+        oc_mutex_unlock(g_sslContextMutex);
         CAdeinitSslAdapter();
         OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
         return CA_STATUS_FAILED;
@@ -1462,7 +2103,7 @@ CAResult_t CAinitSslAdapter()
 #endif // __WITH_DTLS__
 
     // set default cipher
-    g_caSslContext->cipher = ADAPTER_CIPHER_MAX;
+    g_caSslContext->cipher = SSL_CIPHER_MAX;
 
     // init X.509
     mbedtls_x509_crt_init(&g_caSslContext->ca);
@@ -1474,7 +2115,18 @@ CAResult_t CAinitSslAdapter()
     g_caSslContext->timerId = -1;
 #endif
 
-   ca_mutex_unlock(g_sslContextMutex);
+    // create decrypt buffer
+    g_decryptBuffer = (uint8_t *)OICCalloc(1, TLS_MSG_BUF_LEN);
+    if (NULL == g_decryptBuffer)
+    {
+        OIC_LOG(ERROR, NET_SSL_TAG, "Decrypt buffer malloc failed");
+        oc_mutex_unlock(g_sslContextMutex);
+        CAdeinitSslAdapter();
+        OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
+        return CA_MEMORY_ALLOC_FAILED;
+    }
+
+    oc_mutex_unlock(g_sslContextMutex);
 #ifdef __WITH_DTLS__
     StartRetransmit();
 #endif
@@ -1522,7 +2174,7 @@ CAResult_t CAencryptSsl(const CAEndpoint_t *endpoint,
 {
     int ret = 0;
 
-    OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s ", __func__);
+    OIC_LOG_V(INFO, NET_SSL_TAG, "In %s ", __func__);
 
     VERIFY_NON_NULL_RET(endpoint, NET_SSL_TAG,"Remote address is NULL", CA_STATUS_INVALID_PARAM);
     VERIFY_NON_NULL_RET(data, NET_SSL_TAG, "Data is NULL", CA_STATUS_INVALID_PARAM);
@@ -1536,11 +2188,11 @@ CAResult_t CAencryptSsl(const CAEndpoint_t *endpoint,
 
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "Data to be encrypted dataLen [%d]", dataLen);
 
-    ca_mutex_lock(g_sslContextMutex);
+    oc_mutex_lock(g_sslContextMutex);
     if(NULL == g_caSslContext)
     {
         OIC_LOG(ERROR, NET_SSL_TAG, "Context is NULL");
-        ca_mutex_unlock(g_sslContextMutex);
+        oc_mutex_unlock(g_sslContextMutex);
         return CA_STATUS_FAILED;
     }
 
@@ -1552,12 +2204,14 @@ CAResult_t CAencryptSsl(const CAEndpoint_t *endpoint,
     if (NULL == tep)
     {
         OIC_LOG(ERROR, NET_SSL_TAG, "TLS handshake failed");
-        ca_mutex_unlock(g_sslContextMutex);
+        oc_mutex_unlock(g_sslContextMutex);
         return CA_STATUS_FAILED;
     }
 
     if (MBEDTLS_SSL_HANDSHAKE_OVER == tep->ssl.state)
     {
+        OIC_LOG(INFO, NET_SSL_TAG, "(MBEDTLS_SSL_HANDSHAKE_OVER == tep->ssl.state)");
+
         unsigned char *dataBuf = (unsigned char *)data;
         size_t written = 0;
 
@@ -1570,7 +2224,7 @@ CAResult_t CAencryptSsl(const CAEndpoint_t *endpoint,
                 {
                     OIC_LOG_V(ERROR, NET_SSL_TAG, "mbedTLS write failed! returned 0x%x", -ret);
                     RemovePeerFromList(&tep->sep.endpoint);
-                    ca_mutex_unlock(g_sslContextMutex);
+                    oc_mutex_unlock(g_sslContextMutex);
                     return CA_STATUS_FAILED;
                 }
                 continue;
@@ -1588,14 +2242,14 @@ CAResult_t CAencryptSsl(const CAEndpoint_t *endpoint,
         if (NULL == msg || !u_arraylist_add(tep->cacheList, (void *) msg))
         {
             OIC_LOG(ERROR, NET_SSL_TAG, "u_arraylist_add failed!");
-            ca_mutex_unlock(g_sslContextMutex);
+            oc_mutex_unlock(g_sslContextMutex);
             return CA_STATUS_FAILED;
         }
     }
 
-    ca_mutex_unlock(g_sslContextMutex);
+    oc_mutex_unlock(g_sslContextMutex);
 
-    OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
+    OIC_LOG_V(INFO, NET_SSL_TAG, "Out %s", __func__);
     return CA_STATUS_OK;
 }
 /**
@@ -1671,15 +2325,15 @@ void CAsetSslHandshakeCallback(CAErrorCallback tlsHandshakeCallback)
 CAResult_t CAdecryptSsl(const CASecureEndpoint_t *sep, uint8_t *data, uint32_t dataLen)
 {
     int ret = 0;
-    OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
+    OIC_LOG_V(INFO, NET_SSL_TAG, "In %s", __func__);
     VERIFY_NON_NULL_RET(sep, NET_SSL_TAG, "endpoint is NULL" , CA_STATUS_INVALID_PARAM);
     VERIFY_NON_NULL_RET(data, NET_SSL_TAG, "Param data is NULL" , CA_STATUS_INVALID_PARAM);
 
-    ca_mutex_lock(g_sslContextMutex);
+    oc_mutex_lock(g_sslContextMutex);
     if (NULL == g_caSslContext)
     {
         OIC_LOG(ERROR, NET_SSL_TAG, "Context is NULL");
-        ca_mutex_unlock(g_sslContextMutex);
+        oc_mutex_unlock(g_sslContextMutex);
         return CA_STATUS_FAILED;
     }
 
@@ -1687,13 +2341,14 @@ CAResult_t CAdecryptSsl(const CASecureEndpoint_t *sep, uint8_t *data, uint32_t d
     SslEndPoint_t * peer = GetSslPeer(&sep->endpoint);
     if (NULL == peer)
     {
-        mbedtls_ssl_config * config = (sep->endpoint.adapter == CA_ADAPTER_IP ?
+        mbedtls_ssl_config * config = (sep->endpoint.adapter == CA_ADAPTER_IP ||
+                                   sep->endpoint.adapter == CA_ADAPTER_GATT_BTLE ?
                                    &g_caSslContext->serverDtlsConf : &g_caSslContext->serverTlsConf);
         peer = NewSslEndPoint(&sep->endpoint, config);
         if (NULL == peer)
         {
             OIC_LOG(ERROR, NET_SSL_TAG, "Malloc failed!");
-            ca_mutex_unlock(g_sslContextMutex);
+            oc_mutex_unlock(g_sslContextMutex);
             return CA_STATUS_FAILED;
         }
         //Load allowed TLS suites from SVR DB
@@ -1704,7 +2359,7 @@ CAResult_t CAdecryptSsl(const CASecureEndpoint_t *sep, uint8_t *data, uint32_t d
         {
             OIC_LOG(ERROR, NET_SSL_TAG, "u_arraylist_add failed!");
             OICFree(peer);
-            ca_mutex_unlock(g_sslContextMutex);
+            oc_mutex_unlock(g_sslContextMutex);
             return CA_STATUS_FAILED;
         }
     }
@@ -1730,12 +2385,15 @@ CAResult_t CAdecryptSsl(const CASecureEndpoint_t *sep, uint8_t *data, uint32_t d
                                                  sizeof(sep->endpoint.addr));
             ret = mbedtls_ssl_handshake_step(&peer->ssl);
         }
-        uint32_t flags = mbedtls_ssl_get_verify_result(&peer->ssl);
-        if (0 != flags)
+        if (MBEDTLS_SSL_IS_CLIENT == peer->ssl.conf->endpoint)
         {
-            OIC_LOG_BUFFER(ERROR, NET_SSL_TAG, (const uint8_t *) &flags, sizeof(flags));
-            SSL_CHECK_FAIL(peer, flags, "Cert verification failed", 1,
-                                                     CA_STATUS_FAILED, GetAlertCode(flags));
+            uint32_t flags = mbedtls_ssl_get_verify_result(&peer->ssl);
+            if (0 != flags)
+            {
+                OIC_LOG_BUFFER(ERROR, NET_SSL_TAG, (const uint8_t *) &flags, sizeof(flags));
+                SSL_CHECK_FAIL(peer, flags, "Cert verification failed", 1,
+                                                         CA_STATUS_FAILED, GetAlertCode(flags));
+            }
         }
         SSL_CHECK_FAIL(peer, ret, "Handshake error", 1, CA_STATUS_FAILED, MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE);
         if (MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC == peer->ssl.state)
@@ -1756,98 +2414,148 @@ CAResult_t CAdecryptSsl(const CASecureEndpoint_t *sep, uint8_t *data, uint32_t d
                 SendCacheMessages(peer);
             }
 
-            if (MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 == g_caSslContext->selectedCipher ||
-                MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA == g_caSslContext->selectedCipher)
+            int selectedCipher = peer->ssl.session->ciphersuite;
+            OIC_LOG_V(DEBUG, NET_SSL_TAG, "(D)TLS Session is connected via ciphersuite [0x%x]", selectedCipher);
+            if (MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 != selectedCipher &&
+                MBEDTLS_TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256 != selectedCipher)
             {
                 char uuid[UUID_LENGTH * 2 + 5] = {0};
                 void * uuidPos = NULL;
                 void * userIdPos = NULL;
                 const mbedtls_x509_crt * peerCert = mbedtls_ssl_get_peer_cert(&peer->ssl);
                 ret = (NULL == peerCert ? -1 : 0);
-                SSL_CHECK_FAIL(peer, ret, "Failed to retrieve cert", 1,
-                                            CA_STATUS_FAILED, MBEDTLS_SSL_ALERT_MSG_NO_CERT);
-                uuidPos = memmem(peerCert->subject_raw.p, peerCert->subject_raw.len,
-                                                 UUID_PREFIX, sizeof(UUID_PREFIX) - 1);
-
-                if (NULL != uuidPos)
+                //SSL_CHECK_FAIL(peer, ret, "Failed to retrieve cert", 1,
+                //                            CA_STATUS_FAILED, MBEDTLS_SSL_ALERT_MSG_NO_CERT);
+                if (0 == ret)
                 {
-                    memcpy(uuid, (char*) uuidPos + sizeof(UUID_PREFIX) - 1, UUID_LENGTH * 2 + 4);
-                    OIC_LOG_V(DEBUG, NET_SSL_TAG, "certificate uuid string: %s" , uuid);
-                    ret = OCConvertStringToUuid(uuid, peer->sep.identity.id);
-                    SSL_CHECK_FAIL(peer, ret, "Failed to convert subject", 1,
+                    uuidPos = memmem(peerCert->subject_raw.p, peerCert->subject_raw.len,
+                                                     UUID_PREFIX, sizeof(UUID_PREFIX) - 1);
+
+                    if (NULL != uuidPos)
+                    {
+                        memcpy(uuid, (char*) uuidPos + sizeof(UUID_PREFIX) - 1, UUID_LENGTH * 2 + 4);
+                        OIC_LOG_V(DEBUG, NET_SSL_TAG, "certificate uuid string: %s" , uuid);
+                        ret = OCConvertStringToUuid(uuid, peer->sep.identity.id);
+                        SSL_CHECK_FAIL(peer, ret, "Failed to convert subject", 1,
+                                              CA_STATUS_FAILED, MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT);
+                    }
+                    else
+                    {
+                        OIC_LOG(WARNING, NET_SSL_TAG, "uuid not found");
+                    }
+
+                    userIdPos = memmem(peerCert->subject_raw.p, peerCert->subject_raw.len,
+                                                 USERID_PREFIX, sizeof(USERID_PREFIX) - 1);
+                    if (NULL != userIdPos)
+                    {
+                        memcpy(uuid, (char*) userIdPos + sizeof(USERID_PREFIX) - 1, UUID_LENGTH * 2 + 4);
+                        ret = OCConvertStringToUuid(uuid, peer->sep.userId.id);
+                        SSL_CHECK_FAIL(peer, ret, "Failed to convert subject alt name", 1,
                                           CA_STATUS_FAILED, MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT);
+                    }
+                    else
+                    {
+                        OIC_LOG(WARNING, NET_SSL_TAG, "Subject alternative name not found");
+                    }
                 }
-                else
-                {
-                    OIC_LOG(WARNING, NET_SSL_TAG, "uuid not found");
-                }
+            }
 
-                userIdPos = memmem(peerCert->subject_raw.p, peerCert->subject_raw.len,
-                                             USERID_PREFIX, sizeof(USERID_PREFIX) - 1);
-                if (NULL != userIdPos)
-                {
-                    memcpy(uuid, (char*) userIdPos + sizeof(USERID_PREFIX) - 1, UUID_LENGTH * 2 + 4);
-                    ret = OCConvertStringToUuid(uuid, peer->sep.userId.id);
-                    SSL_CHECK_FAIL(peer, ret, "Failed to convert subject alt name", 1,
-                                      CA_STATUS_FAILED, MBEDTLS_SSL_ALERT_MSG_UNSUPPORTED_CERT);
-                }
-                else
-                {
-                    OIC_LOG(WARNING, NET_SSL_TAG, "Subject alternative name not found");
-                }
+            if (MBEDTLS_SSL_IS_CLIENT == peer->ssl.conf->endpoint)
+            {
+                SendCacheMessages(peer);
             }
+            mbedtls_ssl_config * config = (sep->endpoint.adapter == CA_ADAPTER_IP ||
+                                       sep->endpoint.adapter == CA_ADAPTER_GATT_BTLE ?
+                                       &g_caSslContext->serverDtlsConf : &g_caSslContext->serverTlsConf);
 
-            ca_mutex_unlock(g_sslContextMutex);
-            OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
+            mbedtls_ssl_conf_authmode(config, MBEDTLS_SSL_VERIFY_REQUIRED);
+
+            oc_mutex_unlock(g_sslContextMutex);
+            OIC_LOG_V(INFO, NET_SSL_TAG, "Out %s", __func__);
             return CA_STATUS_OK;
         }
     }
 
     if (MBEDTLS_SSL_HANDSHAKE_OVER == peer->ssl.state)
     {
-        uint8_t decryptBuffer[TLS_MSG_BUF_LEN] = {0};
+        OIC_LOG(INFO, NET_SSL_TAG, "(MBEDTLS_SSL_HANDSHAKE_OVER == peer->ssl.state)");
+
+        // flag to read again remained data
+        bool read_more = false;
         do
         {
-            ret = mbedtls_ssl_read(&peer->ssl, decryptBuffer, TLS_MSG_BUF_LEN);
-        } while (MBEDTLS_ERR_SSL_WANT_READ == ret);
-
-        if (MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY == ret ||
-            // TinyDTLS sends fatal close_notify alert
-            (MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE == ret &&
-             MBEDTLS_SSL_ALERT_LEVEL_FATAL == peer->ssl.in_msg[0] &&
-             MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY == peer->ssl.in_msg[1]))
-        {
-            OIC_LOG(INFO, NET_SSL_TAG, "Connection was closed gracefully");
-            SSL_CLOSE_NOTIFY(peer, ret);
-            RemovePeerFromList(&peer->sep.endpoint);
-            ca_mutex_unlock(g_sslContextMutex);
-            return CA_STATUS_OK;
-        }
+            if (NULL == g_decryptBuffer)
+            {
+                OIC_LOG(ERROR, NET_SSL_TAG, "decrypt buffer is NULL");
+                oc_mutex_unlock(g_sslContextMutex);
+                return CA_STATUS_FAILED;
+            }
+            memset(g_decryptBuffer, 0, TLS_MSG_BUF_LEN);
+            read_more = false;
 
-        if (0 > ret)
-        {
-            OIC_LOG_V(ERROR, NET_SSL_TAG, "mbedtls_ssl_read returned -0x%x", -ret);
-            //SSL_RES(peer, CA_STATUS_FAILED);
-            RemovePeerFromList(&peer->sep.endpoint);
-            ca_mutex_unlock(g_sslContextMutex);
-            return CA_STATUS_FAILED;
-        }
-        int adapterIndex = GetAdapterIndex(peer->sep.endpoint.adapter);
-        if (0 == adapterIndex || adapterIndex == 1)
-        {
-            g_caSslContext->adapterCallbacks[adapterIndex].recvCallback(&peer->sep, decryptBuffer, ret);
-        }
-        else
-        {
-            OIC_LOG(ERROR, NET_SSL_TAG, "Unsuported adapter");
-            RemovePeerFromList(&peer->sep.endpoint);
-            ca_mutex_unlock(g_sslContextMutex);
-            return CA_STATUS_FAILED;
-        }
+            do
+            {
+                ret = mbedtls_ssl_read(&peer->ssl, g_decryptBuffer, TLS_MSG_BUF_LEN);
+            } while (MBEDTLS_ERR_SSL_WANT_READ == ret);
+
+            if (MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY == ret ||
+                // TinyDTLS sends fatal close_notify alert
+                (MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE == ret &&
+                 MBEDTLS_SSL_ALERT_LEVEL_FATAL == peer->ssl.in_msg[0] &&
+                 MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY == peer->ssl.in_msg[1]))
+            {
+                OIC_LOG(INFO, NET_SSL_TAG, "Connection was closed gracefully");
+                RemovePeerFromList(&peer->sep.endpoint);
+                oc_mutex_unlock(g_sslContextMutex);
+                return CA_STATUS_OK;
+            }
+
+            if (0 > ret)
+            {
+                OIC_LOG_V(ERROR, NET_SSL_TAG, "mbedtls_ssl_read returned -0x%x", -ret);
+                //SSL_RES(peer, CA_STATUS_FAILED);
+                RemovePeerFromList(&peer->sep.endpoint);
+                oc_mutex_unlock(g_sslContextMutex);
+                return CA_STATUS_FAILED;
+            }
+            else if (0 < ret)
+            {
+                int adapterIndex = GetAdapterIndex(peer->sep.endpoint.adapter);
+                if (0 <= adapterIndex && MAX_SUPPORTED_ADAPTERS > adapterIndex)
+                {
+                    CAResult_t res;
+                    res = g_caSslContext->adapterCallbacks[adapterIndex].recvCallback(&peer->sep,
+                            g_decryptBuffer, ret);
+                    if (CA_STATUS_OK != res)
+                    {
+                        OIC_LOG(ERROR, NET_SSL_TAG, "recvCallback is failed");
+                        RemovePeerFromList(&peer->sep.endpoint);
+                        oc_mutex_unlock(g_sslContextMutex);
+                        return CA_STATUS_FAILED;
+                    }
+
+                    // check if decrypted data is remained in stream transport
+                    size_t remained = mbedtls_ssl_get_bytes_avail(&peer->ssl);
+                    if (0 < remained &&
+                        MBEDTLS_SSL_TRANSPORT_STREAM == peer->ssl.conf->transport)
+                    {
+                        OIC_LOG_V(DEBUG, NET_SSL_TAG, "need to read %zu bytes more", remained);
+                        read_more = true;
+                    }
+                }
+                else
+                {
+                    OIC_LOG(ERROR, NET_SSL_TAG, "Unsuported adapter");
+                    RemovePeerFromList(&peer->sep.endpoint);
+                    oc_mutex_unlock(g_sslContextMutex);
+                    return CA_STATUS_FAILED;
+                }
+            }
+        } while (read_more);
     }
 
-    ca_mutex_unlock(g_sslContextMutex);
-    OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
+    oc_mutex_unlock(g_sslContextMutex);
+    OIC_LOG_V(INFO, NET_SSL_TAG, "Out %s", __func__);
     return CA_STATUS_OK;
 }
 
@@ -1858,175 +2566,130 @@ void CAsetSslAdapterCallbacks(CAPacketReceivedCallback recvCallback,
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
     VERIFY_NON_NULL_VOID(sendCallback, NET_SSL_TAG, "sendCallback is NULL");
     VERIFY_NON_NULL_VOID(recvCallback, NET_SSL_TAG, "recvCallback is NULL");
-    ca_mutex_lock(g_sslContextMutex);
+    oc_mutex_lock(g_sslContextMutex);
     if (NULL == g_caSslContext)
     {
         OIC_LOG(ERROR, NET_SSL_TAG, "Context is NULL");
-        ca_mutex_unlock(g_sslContextMutex);
+        oc_mutex_unlock(g_sslContextMutex);
         return;
     }
 
-//    if (MAX_SUPPORTED_ADAPTERS > type)
+    switch (type)
     {
-        switch (type)
-        {
-            case CA_ADAPTER_IP:
-                g_caSslContext->adapterCallbacks[0].recvCallback = recvCallback;
-                g_caSslContext->adapterCallbacks[0].sendCallback = sendCallback;
-                break;
-            case CA_ADAPTER_TCP:
-                g_caSslContext->adapterCallbacks[1].recvCallback = recvCallback;
-                g_caSslContext->adapterCallbacks[1].sendCallback = sendCallback;
-                break;
-            default:
-                OIC_LOG_V(ERROR, NET_SSL_TAG, "Unsupported adapter: %d", type);
-        }
+        case CA_ADAPTER_IP:
+            g_caSslContext->adapterCallbacks[0].recvCallback = recvCallback;
+            g_caSslContext->adapterCallbacks[0].sendCallback = sendCallback;
+            break;
+        case CA_ADAPTER_TCP:
+            g_caSslContext->adapterCallbacks[1].recvCallback = recvCallback;
+            g_caSslContext->adapterCallbacks[1].sendCallback = sendCallback;
+            break;
+        case CA_ADAPTER_GATT_BTLE:
+            g_caSslContext->adapterCallbacks[2].recvCallback = recvCallback;
+            g_caSslContext->adapterCallbacks[2].sendCallback = sendCallback;
+            break;
+        default:
+            OIC_LOG_V(ERROR, NET_SSL_TAG, "Unsupported adapter: %d", type);
     }
 
-    ca_mutex_unlock(g_sslContextMutex);
+    oc_mutex_unlock(g_sslContextMutex);
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
 }
+/**
+ * Gets index of the TLS ciphersuite in the SslCipher_t enum.
+ *
+ * @param[in]  cipher    TLS chiphersuite code
+ *
+ * @return   corresponding enum
+ */
 
-CAResult_t CAsetTlsCipherSuite(const uint32_t cipher)
+static SslCipher_t GetCipherIndex(const uint32_t cipher)
 {
-    OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
-    VERIFY_NON_NULL_RET(g_getCredentialTypesCallback, NET_SSL_TAG, "Param callback is null", CA_STATUS_FAILED);
-    g_getCredentialTypesCallback(g_caSslContext->cipherFlag);
     switch(cipher)
     {
-        case MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA:
+        case MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256:
         {
-#ifdef __WITH_TLS__
-            //todo check that Cred with RSA cert exists
-            mbedtls_ssl_conf_ciphersuites(&g_caSslContext->clientTlsConf,
-                                         tlsCipher[ADAPTER_TLS_RSA_WITH_AES_256_CBC_SHA]);
-            mbedtls_ssl_conf_ciphersuites(&g_caSslContext->serverTlsConf,
-                                         tlsCipher[ADAPTER_TLS_RSA_WITH_AES_256_CBC_SHA]);
-#endif
-#ifdef __WITH_DTLS__
-            //todo check that Cred with RSA cert exists
-            mbedtls_ssl_conf_ciphersuites(&g_caSslContext->clientDtlsConf,
-                                         tlsCipher[ADAPTER_TLS_RSA_WITH_AES_256_CBC_SHA]);
-            mbedtls_ssl_conf_ciphersuites(&g_caSslContext->serverDtlsConf,
-                                         tlsCipher[ADAPTER_TLS_RSA_WITH_AES_256_CBC_SHA]);
-#endif
-            g_caSslContext->cipher = ADAPTER_TLS_RSA_WITH_AES_256_CBC_SHA;
-            break;
+            return SSL_RSA_WITH_AES_256_CBC_SHA256;
         }
-        case MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
+        case MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256:
         {
-            if (false == g_caSslContext->cipherFlag[1])
-            {
-                OIC_LOG(ERROR, NET_SSL_TAG, "No Credential for ECC");
-                return CA_STATUS_FAILED;
-            }
-#ifdef __WITH_TLS__
-            mbedtls_ssl_conf_ciphersuites(&g_caSslContext->clientTlsConf,
-                                         tlsCipher[ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8]);
-            mbedtls_ssl_conf_ciphersuites(&g_caSslContext->serverTlsConf,
-                                         tlsCipher[ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8]);
-#endif
-#ifdef __WITH_DTLS__
-            mbedtls_ssl_conf_ciphersuites(&g_caSslContext->clientDtlsConf,
-                                         tlsCipher[ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8]);
-            mbedtls_ssl_conf_ciphersuites(&g_caSslContext->serverDtlsConf,
-                                         tlsCipher[ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8]);
-#endif
-            g_caSslContext->cipher = ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8;
-            break;
+            return SSL_RSA_WITH_AES_128_GCM_SHA256;
         }
-        case MBEDTLS_TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256:
+        case MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
         {
-#ifdef __WITH_TLS__
-            mbedtls_ssl_conf_ciphersuites(&g_caSslContext->clientTlsConf,
-                                         tlsCipher[ADAPTER_TLS_ECDH_ANON_WITH_AES_128_CBC_SHA_256]);
-            mbedtls_ssl_conf_ciphersuites(&g_caSslContext->serverTlsConf,
-                                         tlsCipher[ADAPTER_TLS_ECDH_ANON_WITH_AES_128_CBC_SHA_256]);
-#endif
-#ifdef __WITH_DTLS__
-            mbedtls_ssl_conf_ciphersuites(&g_caSslContext->clientDtlsConf,
-                                         tlsCipher[ADAPTER_TLS_ECDH_ANON_WITH_AES_128_CBC_SHA_256]);
-            mbedtls_ssl_conf_ciphersuites(&g_caSslContext->serverDtlsConf,
-                                         tlsCipher[ADAPTER_TLS_ECDH_ANON_WITH_AES_128_CBC_SHA_256]);
-#endif
-            g_caSslContext->cipher = ADAPTER_TLS_ECDH_ANON_WITH_AES_128_CBC_SHA_256;
-            break;
+            return SSL_ECDHE_RSA_WITH_AES_128_GCM_SHA256;
         }
-        case MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256:
+        case MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
         {
-#if 0 // PIN OTM
-            if (false == g_caSslContext->cipherFlag[0])
-            {
-                OIC_LOG(ERROR, NET_SSL_TAG, "No Credential for PSK");
-                return CA_STATUS_FAILED;
-            }
-#endif
-#ifdef __WITH_TLS__
-            mbedtls_ssl_conf_ciphersuites(&g_caSslContext->clientTlsConf,
-                                          tlsCipher[ADAPTER_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256]);
-            mbedtls_ssl_conf_ciphersuites(&g_caSslContext->serverTlsConf,
-                                          tlsCipher[ADAPTER_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256]);
-#endif
-#ifdef __WITH_DTLS__
-            mbedtls_ssl_conf_ciphersuites(&g_caSslContext->clientDtlsConf,
-                                          tlsCipher[ADAPTER_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256]);
-            mbedtls_ssl_conf_ciphersuites(&g_caSslContext->serverDtlsConf,
-                                          tlsCipher[ADAPTER_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256]);
-#endif
-            g_caSslContext->cipher = ADAPTER_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256;
-            break;
+            return SSL_ECDHE_RSA_WITH_AES_256_GCM_SHA384;
+        }
+        case MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
+        {
+            return SSL_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256;
+        }
+        case MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8:
+        {
+            return SSL_ECDHE_ECDSA_WITH_AES_128_CCM_8;
         }
         case MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM:
         {
-            if (false == g_caSslContext->cipherFlag[1])
-            {
-                OIC_LOG(ERROR, NET_SSL_TAG, "No Credential for ECC");
-                return CA_STATUS_FAILED;
-            }
-#ifdef __WITH_TLS__
-            mbedtls_ssl_conf_ciphersuites(&g_caSslContext->clientTlsConf,
-                                         tlsCipher[ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CCM]);
-            mbedtls_ssl_conf_ciphersuites(&g_caSslContext->serverTlsConf,
-                                         tlsCipher[ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CCM]);
-#endif
-#ifdef __WITH_DTLS__
-            mbedtls_ssl_conf_ciphersuites(&g_caSslContext->clientDtlsConf,
-                                         tlsCipher[ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CCM]);
-            mbedtls_ssl_conf_ciphersuites(&g_caSslContext->serverDtlsConf,
-                                         tlsCipher[ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CCM]);
-#endif
-            g_caSslContext->cipher = ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CCM;
-            break;
+            return SSL_ECDHE_ECDSA_WITH_AES_128_CCM;
         }
         case MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
         {
-            if (false == g_caSslContext->cipherFlag[1])
-            {
-                OIC_LOG(ERROR, NET_SSL_TAG, "No Credential for ECC");
-                return CA_STATUS_FAILED;
-            }
-#ifdef __WITH_TLS__
-            mbedtls_ssl_conf_ciphersuites(&g_caSslContext->clientTlsConf,
-                                         tlsCipher[ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256]);
-            mbedtls_ssl_conf_ciphersuites(&g_caSslContext->serverTlsConf,
-                                         tlsCipher[ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256]);
-#endif
-#ifdef __WITH_DTLS__
-            mbedtls_ssl_conf_ciphersuites(&g_caSslContext->clientDtlsConf,
-                                         tlsCipher[ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256]);
-            mbedtls_ssl_conf_ciphersuites(&g_caSslContext->serverDtlsConf,
-                                         tlsCipher[ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256]);
-#endif
-            g_caSslContext->cipher = ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256;
-            break;
+            return SSL_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256;
+        }
+        case MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
+        {
+            return SSL_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384;
+        }
+        case MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
+        {
+            return SSL_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384;
+        }
+        case MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256:
+        {
+            return SSL_ECDHE_PSK_WITH_AES_128_CBC_SHA256;
+        }
+        case MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
+        {
+            return SSL_ECDHE_RSA_WITH_AES_128_CBC_SHA256;
+        }
+        case MBEDTLS_TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256:
+        {
+            return SSL_ECDH_ANON_WITH_AES_128_CBC_SHA256;
         }
         default:
         {
-            OIC_LOG(ERROR, NET_SSL_TAG, "Unknown cipher");
-            return CA_STATUS_FAILED;
+            return SSL_CIPHER_MAX;
         }
     }
-    OIC_LOG_V(DEBUG, NET_SSL_TAG, "Selected cipher: 0x%x", cipher);
+}
+
+CAResult_t CAsetTlsCipherSuite(const uint32_t cipher)
+{
+    OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
+    VERIFY_NON_NULL_RET(g_caSslContext, NET_SSL_TAG, "SSL context is not initialized." , CA_STATUS_NOT_INITIALIZED);
+
+    SslCipher_t index = GetCipherIndex(cipher);
+    if (SSL_CIPHER_MAX == index)
+    {
+        OIC_LOG(WARNING, NET_SSL_TAG, "Unknown cipher");
+    }
+    else
+    {
+#ifdef __WITH_TLS__
+        CONF_SSL(&g_caSslContext->clientTlsConf, &g_caSslContext->serverTlsConf,
+        mbedtls_ssl_conf_ciphersuites, tlsCipher[index]);
+#endif
+#ifdef __WITH_DTLS__
+        CONF_SSL(&g_caSslContext->clientDtlsConf, &g_caSslContext->serverDtlsConf,
+        mbedtls_ssl_conf_ciphersuites, tlsCipher[index]);
+#endif
+        OIC_LOG_V(INFO, NET_SSL_TAG, "Selected cipher: 0x%x", cipher);
+    }
+    g_caSslContext->cipher = index;
+
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
     return CA_STATUS_OK;
 }
@@ -2036,13 +2699,13 @@ CAResult_t CAinitiateSslHandshake(const CAEndpoint_t *endpoint)
     CAResult_t res = CA_STATUS_OK;
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
     VERIFY_NON_NULL_RET(endpoint, NET_SSL_TAG, "Param endpoint is NULL" , CA_STATUS_INVALID_PARAM);
-    ca_mutex_lock(g_sslContextMutex);
+    oc_mutex_lock(g_sslContextMutex);
     if (NULL == InitiateTlsHandshake(endpoint))
     {
         OIC_LOG(ERROR, NET_SSL_TAG, "TLS handshake failed");
         res = CA_STATUS_FAILED;
     }
-    ca_mutex_unlock(g_sslContextMutex);
+    oc_mutex_unlock(g_sslContextMutex);
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
     return res;
 }
@@ -2158,14 +2821,11 @@ CAResult_t CAsslGenerateOwnerPsk(const CAEndpoint_t *endpoint,
     VERIFY_NON_NULL_RET(provServerDeviceId, NET_SSL_TAG, "provId is NULL", CA_STATUS_INVALID_PARAM);
     VERIFY_NON_NULL_RET(ownerPsk, NET_SSL_TAG, "ownerPSK is NULL", CA_STATUS_INVALID_PARAM);
 
-    // TODO: Added as workaround, need to debug
-    ca_mutex_unlock(g_sslContextMutex);
-
-    ca_mutex_lock(g_sslContextMutex);
+    oc_mutex_lock(g_sslContextMutex);
     if (NULL == g_caSslContext)
     {
         OIC_LOG(ERROR, NET_SSL_TAG, "Context is NULL");
-        ca_mutex_unlock(g_sslContextMutex);
+        oc_mutex_unlock(g_sslContextMutex);
         OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
         return CA_STATUS_FAILED;
     }
@@ -2173,34 +2833,105 @@ CAResult_t CAsslGenerateOwnerPsk(const CAEndpoint_t *endpoint,
     if (NULL == tep)
     {
         OIC_LOG(ERROR, NET_SSL_TAG, "Session does not exist");
-        ca_mutex_unlock(g_sslContextMutex);
+        oc_mutex_unlock(g_sslContextMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    // keyBlockLen set up according to OIC 1.1 Security Specification Section 7.3.2
+    int macKeyLen = 0;
+    int ivSize = 0;
+    int keySize = 0;
+    int keyBlockLen = 0;
+    if (MBEDTLS_TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256 == g_caSslContext->selectedCipher ||
+        MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 == g_caSslContext->selectedCipher ||
+        MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 == g_caSslContext->selectedCipher ||
+        MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 == g_caSslContext->selectedCipher)
+    {
+        // 2 * ( 32 + 0 + 16 ) = 96
+        macKeyLen = SHA256_MAC_KEY_LENGTH;
+        ivSize = CBC_IV_LENGTH;
+        keySize = AES128_KEY_LENGTH;
+    }
+    else if (MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM == g_caSslContext->selectedCipher ||
+             MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 == g_caSslContext->selectedCipher)
+    {
+        // 2 * ( 0 + 4 + 16 ) = 40
+        macKeyLen = CCM_MAC_KEY_LENGTH;
+        ivSize = CCM_IV_LENGTH;
+        keySize = AES128_KEY_LENGTH;
+    }
+    else if (MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 == g_caSslContext->selectedCipher)
+    {
+        // 2 * ( 32 + 12 + 16 ) = 120
+        macKeyLen = SHA256_MAC_KEY_LENGTH;
+        ivSize = GCM_IV_LENGTH;
+        keySize = AES128_KEY_LENGTH;
+    }
+    else if (MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 == g_caSslContext->selectedCipher)
+    {
+        // 2 * ( 32 + 0 + 32 ) = 128
+        macKeyLen = SHA256_MAC_KEY_LENGTH;
+        ivSize = CBC_IV_LENGTH;
+        keySize = AES256_KEY_LENGTH;
+    }
+    else if (MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 == g_caSslContext->selectedCipher)
+    {
+        // 2 * ( 48 + 0 + 32 ) = 160
+        macKeyLen = SHA384_MAC_KEY_LENGTH;
+        ivSize = CBC_IV_LENGTH;
+        keySize = AES256_KEY_LENGTH;
+    }
+    else if (MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 == g_caSslContext->selectedCipher)
+    {
+        // 2 * ( 48 + 12 + 32 ) = 184
+        macKeyLen = SHA384_MAC_KEY_LENGTH;
+        ivSize = GCM_IV_LENGTH;
+        keySize = AES256_KEY_LENGTH;
+    }
+    else if (MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 == g_caSslContext->selectedCipher)
+    {
+        // 2 * ( 48 + 12 + 32 ) = 184
+        macKeyLen = SHA256_MAC_KEY_LENGTH;
+        ivSize = GCM_IV_LENGTH;
+        keySize = AES128_KEY_LENGTH;
+    }
+    keyBlockLen = 2 * (macKeyLen + keySize + ivSize);
+
+    uint8_t * keyblock = (uint8_t *)OICMalloc(keyBlockLen);
+    if (NULL == keyblock)
+    {
+        OIC_LOG(ERROR, NET_SSL_TAG, "Failed to OICMalloc for keyblock");
+        oc_mutex_unlock(g_sslContextMutex);
         return CA_STATUS_FAILED;
     }
 
-    uint8_t keyblock[KEY_BLOCK_LEN] = {0};
     // "key expansion"
     uint8_t lab[] = {0x6b, 0x65, 0x79, 0x20, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x73, 0x69, 0x6f, 0x6e};
     int ret = pHash(tep->master, sizeof(tep->master), lab, sizeof(lab),
                     (tep->random) + RANDOM_LEN, RANDOM_LEN, tep->random, RANDOM_LEN,
-                    keyblock, KEY_BLOCK_LEN);
+                    keyblock, keyBlockLen);
     if (-1 == ret)
     {
         OIC_LOG(ERROR, NET_SSL_TAG, "PSK not generated");
-        ca_mutex_unlock(g_sslContextMutex);
+        OICFree(keyblock);
+        oc_mutex_unlock(g_sslContextMutex);
         return CA_STATUS_FAILED;
     }
-    ret = pHash(keyblock, sizeof(keyblock), label, labelLen,
+
+    ret = pHash(keyblock, keyBlockLen, label, labelLen,
                 rsrcServerDeviceId, rsrcServerDeviceIdLen,
                 provServerDeviceId, provServerDeviceIdLen,
                 ownerPsk, ownerPskSize);
     if (-1 == ret)
     {
         OIC_LOG(ERROR, NET_SSL_TAG, "PSK not generated");
-        ca_mutex_unlock(g_sslContextMutex);
+        OICFree(keyblock);
+        oc_mutex_unlock(g_sslContextMutex);
         return CA_STATUS_FAILED;
     }
 
-    ca_mutex_unlock(g_sslContextMutex);
+    OICFree(keyblock);
+    oc_mutex_unlock(g_sslContextMutex);
 
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
     return CA_STATUS_OK;
index 8355886..be74098 100644 (file)
@@ -185,6 +185,10 @@ void CAConvertNameToAddr(const char *host, uint16_t port, struct sockaddr_storag
     int r = getaddrinfo(host, NULL, &hints, &addrs);
     if (r)
     {
+        if (NULL != addrs)
+        {
+            freeaddrinfo(addrs);
+        }
 #if defined(EAI_SYSTEM)
         if (EAI_SYSTEM == r)
         {
@@ -296,6 +300,7 @@ jmethodID CAGetJNIMethodID(JNIEnv *env, const char* className,
     if (!jni_cid)
     {
         OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG, "jni_cid [%s] is null", className);
+        CACheckJNIException(env);
         return NULL;
     }
 
@@ -303,6 +308,7 @@ jmethodID CAGetJNIMethodID(JNIEnv *env, const char* className,
     if (!jni_midID)
     {
         OIC_LOG_V(ERROR, CA_ADAPTER_UTILS_TAG, "jni_midID [%s] is null", methodName);
+        CACheckJNIException(env);
         (*env)->DeleteLocalRef(env, jni_cid);
         return NULL;
     }
@@ -311,6 +317,17 @@ jmethodID CAGetJNIMethodID(JNIEnv *env, const char* className,
     return jni_midID;
 }
 
+bool CACheckJNIException(JNIEnv *env)
+{
+    if ((*env)->ExceptionCheck(env))
+    {
+        (*env)->ExceptionDescribe(env);
+        (*env)->ExceptionClear(env);
+        return true;
+    }
+    return false;
+}
+
 void CADeleteGlobalReferences(JNIEnv *env)
 {
     if (g_Context)
@@ -326,3 +343,75 @@ void CADeleteGlobalReferences(JNIEnv *env)
     }
 }
 #endif
+
+#ifndef WITH_ARDUINO
+void CALogAdapterStateInfo(CATransportAdapter_t adapter, CANetworkStatus_t state)
+{
+    OIC_LOG(DEBUG, CA_ADAPTER_UTILS_TAG, "CALogAdapterStateInfo");
+    OIC_LOG(DEBUG, ANALYZER_TAG, "=================================================");
+    CALogAdapterTypeInfo(adapter);
+    if (CA_INTERFACE_UP == state)
+    {
+        OIC_LOG(INFO, ANALYZER_TAG, "adapter status is changed to CA_INTERFACE_UP");
+    }
+    else
+    {
+        OIC_LOG(INFO, ANALYZER_TAG, "adapter status is changed to CA_INTERFACE_DOWN");
+    }
+    OIC_LOG(DEBUG, ANALYZER_TAG, "=================================================");
+}
+
+void CALogSendStateInfo(CATransportAdapter_t adapter,
+                        const char *addr, uint16_t port, ssize_t sentLen,
+                        bool isSuccess, const char* message)
+{
+    OIC_LOG(DEBUG, CA_ADAPTER_UTILS_TAG, "CALogSendStateInfo");
+    OIC_LOG(DEBUG, ANALYZER_TAG, "=================================================");
+
+    if (true == isSuccess)
+    {
+        OIC_LOG_V(INFO, ANALYZER_TAG, "Send Success, sent length = [%d]", sentLen);
+    }
+    else
+    {
+        OIC_LOG_V(INFO, ANALYZER_TAG, "Send Failure, error message  = [%s]",
+                  message != NULL ? message : "no message");
+    }
+
+    CALogAdapterTypeInfo(adapter);
+    OIC_LOG_V(INFO, ANALYZER_TAG, "Address = [%s]:[%d]", addr, port);
+    OIC_LOG(DEBUG, ANALYZER_TAG, "=================================================");
+
+    // samsung log
+    if (true == isSuccess)
+    {
+        OIC_LOG_V(INFO, CA_ADAPTER_UTILS_TAG, "| Analyzer(Retail) | %02x", 1);
+    }
+    else
+    {
+        OIC_LOG_V(INFO, CA_ADAPTER_UTILS_TAG, "| Analyzer(Retail) | %02x", 0);
+    }
+}
+
+void CALogAdapterTypeInfo(CATransportAdapter_t adapter)
+{
+    switch(adapter)
+    {
+        case CA_ADAPTER_IP:
+            OIC_LOG(INFO, ANALYZER_TAG, "Transport Type = [OC_ADAPTER_IP]");
+            break;
+        case CA_ADAPTER_TCP:
+            OIC_LOG(INFO, ANALYZER_TAG, "Transport Type = [OC_ADAPTER_TCP]");
+            break;
+        case CA_ADAPTER_GATT_BTLE:
+            OIC_LOG(INFO, ANALYZER_TAG, "Transport Type = [OC_ADAPTER_GATT_BTLE]");
+            break;
+        case CA_ADAPTER_RFCOMM_BTEDR:
+            OIC_LOG(INFO, ANALYZER_TAG, "Transport Type = [OC_ADAPTER_RFCOMM_BTEDR]");
+            break;
+        default:
+            OIC_LOG_V(INFO, ANALYZER_TAG, "Transport Type = [%d]", adapter);
+            break;
+    }
+}
+#endif
index 67a6aab..67bd00b 100644 (file)
@@ -24,6 +24,7 @@
 #include "cacommon.h"
 #include "caadapterutils.h"
 #include "cafragmentation.h"
+#include "caleinterface.h"
 
 /**
  * Debugging tag for fragmentation module.
@@ -82,13 +83,14 @@ static uint8_t CAGetBits(uint8_t x, unsigned p, unsigned n)
 CAResult_t CAGenerateVariableForFragmentation(size_t dataLength,
                                               uint32_t *midPacketCount,
                                               size_t *remainingLen,
-                                              size_t *totalLength)
+                                              size_t *totalLength,
+                                              uint16_t mtuSize)
 {
-    OIC_LOG_V(DEBUG, TAG, "IN, dataLength = %zu", dataLength);
+    OIC_LOG_V(DEBUG, TAG, "IN, dataLength = %zu, mtu = %zu", dataLength, mtuSize);
 
     size_t remainDataSize = 0;
     size_t dataOnlyLen =
-        CA_SUPPORTED_BLE_MTU_SIZE - (CA_BLE_HEADER_SIZE + CA_BLE_LENGTH_HEADER_SIZE);
+            mtuSize - (CA_BLE_HEADER_SIZE + CA_BLE_LENGTH_HEADER_SIZE);
     //total data size is smaller than 14 byte case.
     if (dataLength < dataOnlyLen)
     {
@@ -99,14 +101,14 @@ CAResult_t CAGenerateVariableForFragmentation(size_t dataLength,
         remainDataSize = dataLength - dataOnlyLen;
     }
 
-    if (CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_HEADER_SIZE <= 0)
+    if (mtuSize - CA_BLE_HEADER_SIZE <= 0)
     {
         OIC_LOG_V(ERROR, TAG, "BLE header size shouldn't be bigger than BLE MTU size.");
         return CA_STATUS_FAILED;
     }
 
-    *midPacketCount = (uint32_t)remainDataSize / (CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_HEADER_SIZE);
-    *remainingLen = (uint32_t)remainDataSize % (CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_HEADER_SIZE);
+    *midPacketCount = (uint32_t)remainDataSize / (mtuSize - CA_BLE_HEADER_SIZE);
+    *remainingLen = (uint32_t)remainDataSize % (mtuSize - CA_BLE_HEADER_SIZE);
     uint32_t remainHeaderSize = CA_BLE_HEADER_SIZE * (*midPacketCount + (*remainingLen == 0 ? 0:1));
     *totalLength = dataLength + (CA_BLE_HEADER_SIZE + CA_BLE_LENGTH_HEADER_SIZE) + remainHeaderSize;
 
@@ -121,8 +123,6 @@ CAResult_t CAGenerateHeader(uint8_t *header,
                             CABLEPacketSecure_t secure,
                             const uint8_t destPort)
 {
-    OIC_LOG(DEBUG, TAG, "IN");
-
     VERIFY_NON_NULL(header, TAG, "header is NULL");
 
     if (sourcePort > CA_SUPPORTED_BLE_MAX_PORT ||
@@ -169,8 +169,6 @@ CAResult_t CAMakeFirstDataSegment(uint8_t *dataSegment,
                                   const uint8_t *dataHeader,
                                   const uint8_t *lengthHeader)
 {
-    OIC_LOG(DEBUG, TAG, "IN");
-
     VERIFY_NON_NULL(dataSegment, TAG, "dataSegment is NULL");
     VERIFY_NON_NULL(dataHeader, TAG, "dataHeader is NULL");
     VERIFY_NON_NULL(lengthHeader, TAG, "lengthHeader is NULL");
@@ -178,37 +176,30 @@ CAResult_t CAMakeFirstDataSegment(uint8_t *dataSegment,
     memcpy(dataSegment, dataHeader, CA_BLE_HEADER_SIZE);
     memcpy(dataSegment + CA_BLE_HEADER_SIZE, lengthHeader, CA_BLE_LENGTH_HEADER_SIZE);
     memcpy(dataSegment + CA_BLE_HEADER_SIZE + CA_BLE_LENGTH_HEADER_SIZE, data, dataLength);
-
-    OIC_LOG(DEBUG, TAG, "OUT");
-
     return CA_STATUS_OK;
 }
 
 CAResult_t CAMakeRemainDataSegment(uint8_t *dataSegment,
-                                   const uint8_t *data,
-                                   const uint32_t dataLength,
-                                   const uint32_t index,
-                                   const uint8_t *dataHeader)
+                                   const uint32_t segmentPayloadLength,
+                                   const uint8_t *sourceData,
+                                   const uint32_t sourceDataLength,
+                                   const uint32_t segmentNum,
+                                   const uint8_t *dataHeader,
+                                   uint16_t mtuSize)
 {
-    OIC_LOG(DEBUG, TAG, "IN");
-
     VERIFY_NON_NULL(dataSegment, TAG, "dataSegment is NULL");
     VERIFY_NON_NULL(dataHeader, TAG, "dataHeader is NULL");
 
-    const uint8_t *cur_pos = data +
-        (CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_HEADER_SIZE - CA_BLE_LENGTH_HEADER_SIZE +
-         (index * (CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_HEADER_SIZE)));
-    if (NULL == cur_pos)
+    uint32_t index = (mtuSize - CA_BLE_HEADER_SIZE - CA_BLE_LENGTH_HEADER_SIZE) +
+            (segmentNum * (mtuSize - CA_BLE_HEADER_SIZE));
+    if (sourceDataLength < index + segmentPayloadLength)
     {
-        OIC_LOG(ERROR, TAG, "data is NULL");
+        OIC_LOG(DEBUG, TAG, "dataSegment will exceed");
         return CA_STATUS_FAILED;
     }
 
     memcpy(dataSegment, dataHeader, CA_BLE_HEADER_SIZE);
-    memcpy(dataSegment + CA_BLE_HEADER_SIZE, cur_pos, dataLength);
-
-    OIC_LOG(DEBUG, TAG, "OUT");
-
+    memcpy(dataSegment + CA_BLE_HEADER_SIZE, sourceData + index, segmentPayloadLength);
     return CA_STATUS_OK;
 }
 
@@ -218,8 +209,6 @@ CAResult_t CAParseHeader(const uint8_t *header,
                          CABLEPacketSecure_t *secureFlag,
                          uint16_t *destPort)
 {
-    OIC_LOG(DEBUG, TAG, "IN");
-
     VERIFY_NON_NULL(header, TAG, "header is NULL");
 
     *startFlag = CAGetBits(header[0], CA_BLE_START_POS, CA_BLE_START_LEN);
@@ -227,8 +216,6 @@ CAResult_t CAParseHeader(const uint8_t *header,
     *secureFlag = CAGetBits(header[1], CA_BLE_SECURE_POS, CA_BLE_SECURE_LEN);
     *destPort = CAGetBits(header[1], CA_BLE_DESTINATION_PORT_POS, CA_BLE_DESTINATION_PORT_LEN);
 
-    OIC_LOG(DEBUG, TAG, "OUT");
-
     return CA_STATUS_OK;
 }
 
@@ -236,7 +223,6 @@ CAResult_t CAParseHeaderPayloadLength(uint8_t *header,
                                       size_t headerLength,
                                       uint32_t *dataLength)
 {
-    OIC_LOG(DEBUG, TAG, "IN");
     VERIFY_NON_NULL(header, TAG, "header is NULL");
 
     if (headerLength != CA_BLE_LENGTH_HEADER_SIZE)
@@ -250,6 +236,5 @@ CAResult_t CAParseHeaderPayloadLength(uint8_t *header,
         *dataLength |= header[CA_BLE_HEADER_SIZE+idx];
     }
 
-    OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
index 5ff9200..d29de99 100644 (file)
@@ -29,7 +29,7 @@
 #include "oic_malloc.h"
 #include "oic_string.h"
 #include "cathreadpool.h" /* for thread pool */
-#include "camutex.h"
+#include "octhread.h"
 #include "uarraylist.h"
 #include "caadapterutils.h"
 #include "caremotehandler.h"
@@ -57,13 +57,13 @@ static jobject g_context;
  * @var g_mutexStateList
  * @brief Mutex to synchronize device state list
  */
-static ca_mutex g_mutexStateList = NULL;
+static oc_mutex g_mutexStateList = NULL;
 
 /**
  * @var g_mutexObjectList
  * @brief Mutex to synchronize device object list
  */
-static ca_mutex g_mutexObjectList = NULL;
+static oc_mutex g_mutexObjectList = NULL;
 
 /**
  * @var g_edrErrorHandler
@@ -281,20 +281,20 @@ static void CAEDRDestroyMutex()
 {
     if (g_mutexStateList)
     {
-        ca_mutex_free(g_mutexStateList);
+        oc_mutex_free(g_mutexStateList);
         g_mutexStateList = NULL;
     }
 
     if (g_mutexObjectList)
     {
-        ca_mutex_free(g_mutexObjectList);
+        oc_mutex_free(g_mutexObjectList);
         g_mutexObjectList = NULL;
     }
 }
 
 static CAResult_t CAEDRCreateMutex()
 {
-    g_mutexStateList = ca_mutex_new();
+    g_mutexStateList = oc_mutex_new();
     if (!g_mutexStateList)
     {
         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
@@ -303,7 +303,7 @@ static CAResult_t CAEDRCreateMutex()
         return CA_STATUS_FAILED;
     }
 
-    g_mutexObjectList = ca_mutex_new();
+    g_mutexObjectList = oc_mutex_new();
     if (!g_mutexObjectList)
     {
         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
@@ -355,13 +355,13 @@ CAResult_t CAEDRInitialize()
     }
     (*env)->DeleteLocalRef(env, jni_address);
 
-    ca_mutex_lock(g_mutexStateList);
+    oc_mutex_lock(g_mutexStateList);
     CAEDRNativeCreateDeviceStateList();
-    ca_mutex_unlock(g_mutexStateList);
+    oc_mutex_unlock(g_mutexStateList);
 
-    ca_mutex_lock(g_mutexObjectList);
+    oc_mutex_lock(g_mutexObjectList);
     CAEDRNativeCreateDeviceSocketList();
-    ca_mutex_unlock(g_mutexObjectList);
+    oc_mutex_unlock(g_mutexObjectList);
 
     if (isAttached)
     {
@@ -854,6 +854,7 @@ CAResult_t CAEDRNativeSendData(JNIEnv *env, const char *address, const uint8_t *
             if ((*env)->ExceptionCheck(env))
             {
                 OIC_LOG(ERROR, TAG, "Failed to write data in outputStram");
+                CALogSendStateInfo(CA_ADAPTER_RFCOMM_BTEDR, address, 0, dataLength, false, NULL);
                 (*env)->ExceptionDescribe(env);
                 (*env)->ExceptionClear(env);
                 return CA_STATUS_FAILED;
@@ -861,12 +862,14 @@ CAResult_t CAEDRNativeSendData(JNIEnv *env, const char *address, const uint8_t *
 
             OIC_LOG_V(INFO, TAG, "EDR sendTo is successful: %u bytes, to %s",
                       dataLength, address);
+            CALogSendStateInfo(CA_ADAPTER_RFCOMM_BTEDR, address, 0, dataLength, true, NULL);
         }
         else
         {
+            OIC_LOG(ERROR, TAG, "error!!");
+            CALogSendStateInfo(CA_ADAPTER_RFCOMM_BTEDR, address, 0, dataLength, false, NULL);
             (*env)->ExceptionDescribe(env);
             (*env)->ExceptionClear(env);
-            OIC_LOG(ERROR, TAG, "error!!");
             return CA_STATUS_FAILED;
         }
     }
@@ -1029,6 +1032,7 @@ CAResult_t CAEDRNativeConnect(JNIEnv *env, const char *address)
 
     if ((*env)->ExceptionCheck(env))
     {
+        CALogSendStateInfo(CA_ADAPTER_RFCOMM_BTEDR, address, 0, 0, false, "Connect has Failed");
         OIC_LOG(ERROR, TAG, "Connect is Failed!!!");
         (*env)->ExceptionDescribe(env);
         (*env)->ExceptionClear(env);
@@ -1043,16 +1047,16 @@ CAResult_t CAEDRNativeConnect(JNIEnv *env, const char *address)
         (*env)->DeleteLocalRef(env, jni_obj_BTSocket);
         return CA_STATUS_FAILED;
     }
-    ca_mutex_lock(g_mutexObjectList);
+    oc_mutex_lock(g_mutexObjectList);
     CAEDRNativeAddDeviceSocketToList(env, jni_socket);
     (*env)->DeleteGlobalRef(env, jni_socket);
     (*env)->DeleteLocalRef(env, jni_obj_BTSocket);
-    ca_mutex_unlock(g_mutexObjectList);
+    oc_mutex_unlock(g_mutexObjectList);
 
     // update state
-    ca_mutex_lock(g_mutexStateList);
+    oc_mutex_lock(g_mutexStateList);
     CAEDRUpdateDeviceState(STATE_CONNECTED, address);
-    ca_mutex_unlock(g_mutexStateList);
+    oc_mutex_unlock(g_mutexStateList);
 
     OIC_LOG(DEBUG, TAG, "successfully connected");
 
@@ -1098,9 +1102,9 @@ void CAEDRNativeSocketClose(JNIEnv *env, const char *address)
     CAEDRNativeRemoveDeviceSocket(env, jni_obj_socket);
 
     // update state
-    ca_mutex_lock(g_mutexStateList);
+    oc_mutex_lock(g_mutexStateList);
     CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
-    ca_mutex_unlock(g_mutexStateList);
+    oc_mutex_unlock(g_mutexStateList);
 
     OIC_LOG_V(DEBUG, TAG, "disconnected with [%s]", address);
 }
index 425469e..c2e17e9 100644 (file)
@@ -27,7 +27,7 @@
 #include "logger.h"
 #include "oic_malloc.h"
 #include "cathreadpool.h" /* for thread pool */
-#include "camutex.h"
+#include "octhread.h"
 #include "uarraylist.h"
 #include "caadapterutils.h"
 #include "caedrserver.h"
index b549ed1..0ef0117 100644 (file)
@@ -28,7 +28,7 @@
 #include "logger.h"
 #include "oic_malloc.h"
 #include "cathreadpool.h" /* for thread pool */
-#include "camutex.h"
+#include "octhread.h"
 #include "uarraylist.h"
 #include "caadapterutils.h"
 #include "org_iotivity_ca_CaEdrInterface.h"
@@ -61,7 +61,7 @@ static bool g_isStartServer = false;
 /**
  * Mutex to synchronize receive server.
  */
-static ca_mutex g_mutexReceiveServer = NULL;
+static oc_mutex g_mutexReceiveServer = NULL;
 
 /**
  * Flag to control the Receive Unicast Data Thread.
@@ -71,7 +71,7 @@ static bool g_stopUnicast = false;
 /**
  * Mutex to synchronize accept server.
  */
-static ca_mutex g_mutexAcceptServer = NULL;
+static oc_mutex g_mutexAcceptServer = NULL;
 
 /**
  * Flag to control the Accept Thread.
@@ -81,7 +81,7 @@ static bool g_stopAccept = false;
 /**
  * Mutex to synchronize server socket.
  */
-static ca_mutex g_mutexServerSocket = NULL;
+static oc_mutex g_mutexServerSocket = NULL;
 
 /**
  * Flag to control the server socket.
@@ -91,17 +91,17 @@ static jobject g_serverSocket = NULL;
 /**
  * Mutex to synchronize device state list.
  */
-static ca_mutex g_mutexStateList = NULL;
+static oc_mutex g_mutexStateList = NULL;
 
 /**
  * Mutex to synchronize device object list.
  */
-static ca_mutex g_mutexObjectList = NULL;
+static oc_mutex g_mutexObjectList = NULL;
 
 /**
  * Mutex to synchronize start server state.
  */
-static ca_mutex g_mutexStartServerState = NULL;
+static oc_mutex g_mutexStartServerState = NULL;
 
 /**
  * Thread context information for unicast, multicast and secured unicast server.
@@ -212,16 +212,16 @@ static void CAAcceptHandler(void *data)
         return;
     }
 
-    ca_mutex_lock(g_mutexServerSocket);
+    oc_mutex_lock(g_mutexServerSocket);
     g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
-    ca_mutex_unlock(g_mutexServerSocket);
+    oc_mutex_unlock(g_mutexServerSocket);
 
     CAAdapterAcceptThreadContext_t *ctx = (CAAdapterAcceptThreadContext_t *) data;
 
     // it should be initialized for restart accept thread
-    ca_mutex_lock(g_mutexAcceptServer);
+    oc_mutex_lock(g_mutexAcceptServer);
     g_stopAccept = false;
-    ca_mutex_unlock(g_mutexAcceptServer);
+    oc_mutex_unlock(g_mutexAcceptServer);
 
     while (true != *(ctx->stopFlag))
     {
@@ -229,12 +229,12 @@ static void CAAcceptHandler(void *data)
         if (!CAEDRNativeIsEnableBTAdapter(env))
         {
             OIC_LOG(INFO, TAG, "BT adapter is not enabled");
-            ca_mutex_lock(g_mutexAcceptServer);
+            oc_mutex_lock(g_mutexAcceptServer);
             g_stopAccept = true;
-            ca_mutex_unlock(g_mutexAcceptServer);
-            ca_mutex_lock(g_mutexServerSocket);
+            oc_mutex_unlock(g_mutexAcceptServer);
+            oc_mutex_lock(g_mutexServerSocket);
             g_serverSocket = NULL;
-            ca_mutex_unlock(g_mutexServerSocket);
+            oc_mutex_unlock(g_mutexServerSocket);
         }
         else
         {
@@ -264,14 +264,14 @@ CAResult_t CAEDRServerStart()
         return CA_STATUS_NOT_INITIALIZED;
     }
 
-    ca_mutex_lock(g_mutexStartServerState);
+    oc_mutex_lock(g_mutexStartServerState);
     if (g_isStartServer)
     {
         OIC_LOG(DEBUG, TAG, "server already started");
-        ca_mutex_unlock(g_mutexStartServerState);
+        oc_mutex_unlock(g_mutexStartServerState);
         return CA_STATUS_OK;
     }
-    ca_mutex_unlock(g_mutexStartServerState);
+    oc_mutex_unlock(g_mutexStartServerState);
 
     CAResult_t res = CAEDRServerStartAcceptThread();
     if (CA_STATUS_OK == res)
@@ -283,9 +283,9 @@ CAResult_t CAEDRServerStart()
             CAEDRServerStop();
             return CA_STATUS_FAILED;
         }
-        ca_mutex_lock(g_mutexStartServerState);
+        oc_mutex_lock(g_mutexStartServerState);
         g_isStartServer = true;
-        ca_mutex_unlock(g_mutexStartServerState);
+        oc_mutex_unlock(g_mutexStartServerState);
     }
 
     return res;
@@ -295,9 +295,9 @@ CAResult_t CAEDRServerStop()
 {
     CAEDRStopReceiveThread();
 
-    ca_mutex_lock(g_mutexAcceptServer);
+    oc_mutex_lock(g_mutexAcceptServer);
     g_stopAccept = true;
-    ca_mutex_unlock(g_mutexAcceptServer);
+    oc_mutex_unlock(g_mutexAcceptServer);
 
     if (!g_jvm)
     {
@@ -322,9 +322,9 @@ CAResult_t CAEDRServerStop()
     }
 
     CAEDRNatvieCloseServerTask(env);
-    ca_mutex_lock(g_mutexStartServerState);
+    oc_mutex_lock(g_mutexStartServerState);
     g_isStartServer = false;
-    ca_mutex_unlock(g_mutexStartServerState);
+    oc_mutex_unlock(g_mutexStartServerState);
 
     if (isAttached)
     {
@@ -343,51 +343,51 @@ static void CAEDRServerDestroyMutex()
 {
     if (g_mutexReceiveServer)
     {
-        ca_mutex_free(g_mutexReceiveServer);
+        oc_mutex_free(g_mutexReceiveServer);
         g_mutexReceiveServer = NULL;
     }
 
     if (g_mutexAcceptServer)
     {
-        ca_mutex_free(g_mutexAcceptServer);
+        oc_mutex_free(g_mutexAcceptServer);
         g_mutexAcceptServer = NULL;
     }
 
     if (g_mutexServerSocket)
     {
-        ca_mutex_free(g_mutexServerSocket);
+        oc_mutex_free(g_mutexServerSocket);
         g_mutexServerSocket = NULL;
     }
 
     if (g_mutexStateList)
     {
-        ca_mutex_free(g_mutexStateList);
+        oc_mutex_free(g_mutexStateList);
         g_mutexStateList = NULL;
     }
 
     if (g_mutexObjectList)
     {
-        ca_mutex_free(g_mutexObjectList);
+        oc_mutex_free(g_mutexObjectList);
         g_mutexObjectList = NULL;
     }
 
     if (g_mutexStartServerState)
     {
-        ca_mutex_free(g_mutexStartServerState);
+        oc_mutex_free(g_mutexStartServerState);
         g_mutexStartServerState = NULL;
     }
 }
 
 static CAResult_t CAEDRServerCreateMutex()
 {
-    g_mutexReceiveServer = ca_mutex_new();
+    g_mutexReceiveServer = oc_mutex_new();
     if (!g_mutexReceiveServer)
     {
         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
         return CA_STATUS_FAILED;
     }
 
-    g_mutexAcceptServer = ca_mutex_new();
+    g_mutexAcceptServer = oc_mutex_new();
     if (!g_mutexAcceptServer)
     {
         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
@@ -396,7 +396,7 @@ static CAResult_t CAEDRServerCreateMutex()
         return CA_STATUS_FAILED;
     }
 
-    g_mutexServerSocket = ca_mutex_new();
+    g_mutexServerSocket = oc_mutex_new();
     if (!g_mutexServerSocket)
     {
         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
@@ -405,7 +405,7 @@ static CAResult_t CAEDRServerCreateMutex()
         return CA_STATUS_FAILED;
     }
 
-    g_mutexStateList = ca_mutex_new();
+    g_mutexStateList = oc_mutex_new();
     if (!g_mutexStateList)
     {
         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
@@ -414,7 +414,7 @@ static CAResult_t CAEDRServerCreateMutex()
         return CA_STATUS_FAILED;
     }
 
-    g_mutexObjectList = ca_mutex_new();
+    g_mutexObjectList = oc_mutex_new();
     if (!g_mutexObjectList)
     {
         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
@@ -423,7 +423,7 @@ static CAResult_t CAEDRServerCreateMutex()
         return CA_STATUS_FAILED;
     }
 
-    g_mutexStartServerState = ca_mutex_new();
+    g_mutexStartServerState = oc_mutex_new();
     if (!g_mutexStartServerState)
     {
         OIC_LOG(ERROR, TAG, "Failed to created mutex!");
@@ -478,13 +478,13 @@ CAResult_t CAEDRServerStartAcceptThread()
         (*env)->ReleaseStringUTFChars(env, jni_address, localAddress);
     }
 
-    ca_mutex_lock(g_mutexStateList);
+    oc_mutex_lock(g_mutexStateList);
     CAEDRNativeCreateDeviceStateList();
-    ca_mutex_unlock(g_mutexStateList);
+    oc_mutex_unlock(g_mutexStateList);
 
-    ca_mutex_lock(g_mutexObjectList);
+    oc_mutex_lock(g_mutexObjectList);
     CAEDRNativeCreateDeviceSocketList();
-    ca_mutex_unlock(g_mutexObjectList);
+    oc_mutex_unlock(g_mutexObjectList);
 
     if (isAttached)
     {
@@ -500,7 +500,8 @@ CAResult_t CAEDRServerStartAcceptThread()
     }
 
     ctx->stopFlag = &g_stopAccept;
-    if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAAcceptHandler, (void *) ctx))
+    if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAAcceptHandler,
+                                                (void *) ctx, NULL))
     {
         OIC_LOG(ERROR, TAG, "Failed to create read thread!");
         OICFree((void *) ctx);
@@ -552,7 +553,7 @@ CAResult_t CAEDRStartReceiveThread(bool isSecured)
 {
     OIC_LOG(DEBUG, TAG, "CAEDRStartReceiveThread");
 
-    ca_mutex_lock(g_mutexReceiveServer);
+    oc_mutex_lock(g_mutexReceiveServer);
 
     /**
      * The task to listen for data from unicast is added to the thread pool.
@@ -566,21 +567,22 @@ CAResult_t CAEDRStartReceiveThread(bool isSecured)
     if (!ctx)
     {
         OIC_LOG(ERROR, TAG, "Out of memory!");
-        ca_mutex_unlock(g_mutexReceiveServer);
+        oc_mutex_unlock(g_mutexReceiveServer);
         return CA_MEMORY_ALLOC_FAILED;
     }
 
     g_stopUnicast = false;
     ctx->stopFlag = &g_stopUnicast;
     ctx->type = isSecured ? CA_SECURED_UNICAST_SERVER : CA_UNICAST_SERVER;
-    if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler, (void *) ctx))
+    if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CAReceiveHandler,
+                                                (void *) ctx, NULL))
     {
         OIC_LOG(ERROR, TAG, "Failed to create read thread!");
-        ca_mutex_unlock(g_mutexReceiveServer);
+        oc_mutex_unlock(g_mutexReceiveServer);
         OICFree((void *) ctx);
         return CA_STATUS_FAILED;
     }
-    ca_mutex_unlock(g_mutexReceiveServer);
+    oc_mutex_unlock(g_mutexReceiveServer);
 
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
@@ -590,9 +592,9 @@ CAResult_t CAEDRStopReceiveThread()
 {
     OIC_LOG(DEBUG, TAG, "CAEDRStopReceiveThread");
 
-    ca_mutex_lock(g_mutexReceiveServer);
+    oc_mutex_lock(g_mutexReceiveServer);
     g_stopUnicast = true;
-    ca_mutex_unlock(g_mutexReceiveServer);
+    oc_mutex_unlock(g_mutexReceiveServer);
 
     return CA_STATUS_OK;
 }
@@ -727,12 +729,12 @@ CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t idx)
         (*env)->ReleaseByteArrayElements(env, jbuf, buf, 0);
         (*env)->DeleteLocalRef(env, jbuf);
 
-        if (!deviceInfo->totalDataLen)
+        if (!deviceInfo->totalDataLen && deviceInfo->recvData)
         {
             coap_transport_t transport = coap_get_tcp_header_type_from_initbyte(
                     ((unsigned char *) deviceInfo->recvData)[0] >> 4);
             size_t headerLen = coap_get_tcp_header_length_for_transport(transport);
-            if (deviceInfo->recvData && deviceInfo->recvDataLen >= headerLen)
+            if (deviceInfo->recvDataLen >= headerLen)
             {
                 deviceInfo->totalDataLen = coap_get_total_message_length(deviceInfo->recvData,
                                                                          deviceInfo->recvDataLen);
@@ -760,9 +762,9 @@ CAResult_t CAEDRNativeReadData(JNIEnv *env, uint32_t idx)
 
                 // update state to disconnect
                 // the socket will be close next read thread routine
-                ca_mutex_lock(g_mutexStateList);
+                oc_mutex_lock(g_mutexStateList);
                 CAEDRUpdateDeviceState(STATE_DISCONNECTED, address);
-                ca_mutex_unlock(g_mutexStateList);
+                oc_mutex_unlock(g_mutexStateList);
 
                 (*env)->ReleaseStringUTFChars(env, jni_str_address, address);
                 (*env)->DeleteLocalRef(env, jni_str_address);
@@ -801,9 +803,9 @@ void CANativeStartListenTask(JNIEnv *env)
         return;
     }
 
-    ca_mutex_lock(g_mutexServerSocket);
+    oc_mutex_lock(g_mutexServerSocket);
     g_serverSocket = (*env)->NewGlobalRef(env, jni_obj_BTServerSocket);
-    ca_mutex_unlock(g_mutexServerSocket);
+    oc_mutex_unlock(g_mutexServerSocket);
 }
 
 jobject CAEDRNativeListen(JNIEnv *env)
@@ -946,9 +948,9 @@ void CAEDRNativeAccept(JNIEnv *env, jobject serverSocketObject)
         OIC_LOG_V(INFO, TAG, "accept a new connection from [%s]", address);
 
         // update state
-        ca_mutex_lock(g_mutexStateList);
+        oc_mutex_lock(g_mutexStateList);
         CAEDRUpdateDeviceState(STATE_CONNECTED, address);
-        ca_mutex_unlock(g_mutexStateList);
+        oc_mutex_unlock(g_mutexStateList);
 
         (*env)->ReleaseStringUTFChars(env, j_str_address, address);
         (*env)->DeleteLocalRef(env, j_str_address);
@@ -962,9 +964,9 @@ void CAEDRNativeAccept(JNIEnv *env, jobject serverSocketObject)
             return;
         }
 
-        ca_mutex_lock(g_mutexObjectList);
+        oc_mutex_lock(g_mutexObjectList);
         CAEDRNativeAddDeviceSocketToList(env, jni_socket);
-        ca_mutex_unlock(g_mutexObjectList);
+        oc_mutex_unlock(g_mutexObjectList);
 
         (*env)->DeleteGlobalRef(env, jni_socket);
         (*env)->DeleteLocalRef(env, jni_obj_BTSocket);
index 6dc604d..5990dc1 100644 (file)
@@ -545,6 +545,7 @@ void CAEDRNativeAddDeviceSocketToList(JNIEnv *env, jobject deviceSocket)
     if (!jni_mid_getInputStream)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_getInputStream is null");
+        OICFree(socketInfo);
         return;
     }
 
@@ -553,6 +554,7 @@ void CAEDRNativeAddDeviceSocketToList(JNIEnv *env, jobject deviceSocket)
     if (!jni_obj_inputStream)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_inputStream is null");
+        OICFree(socketInfo);
         return;
     }
 
index a905e2f..4481499 100644 (file)
@@ -93,8 +93,8 @@ void CAAdapterTerminateQueues();
 void CAAdapterDataSendHandler(void *context);
 void CAAdapterDataReceiverHandler(void *context);
 CAResult_t CAAdapterStopQueue();
-void CAAdapterRecvData(const char *remoteAddress, const uint8_t *data, uint32_t dataLength,
-                       uint32_t *sentLength);
+CAResult_t CAAdapterRecvData(const char *remoteAddress, const uint8_t *data,
+                             uint32_t dataLength, uint32_t *sentLength);
 void CAEDRNotifyNetworkStatus(CANetworkStatus_t status);
 void CAEDROnNetworkStatusChanged(void *context);
 CAResult_t CAAdapterSendData(const char *remoteAddress, const char *serviceUUID,
@@ -634,19 +634,19 @@ CAResult_t CAAdapterStopQueue()
     return CA_STATUS_OK;
 }
 
-void CAAdapterRecvData(const char *remoteAddress, const uint8_t *data, uint32_t dataLength,
-                       uint32_t *sentLength)
+CAResult_t CAAdapterRecvData(const char *remoteAddress, const uint8_t *data,
+                             uint32_t dataLength, uint32_t *sentLength)
 {
     if (false == g_adapterState)
     {
         OIC_LOG_V(ERROR, TAG, "Bluetooth adapter is disabled!");
         *sentLength = 0;
-        return;
+        return CA_ADAPTER_NOT_ENABLED;
     }
 
     // Input validation
-    VERIFY_NON_NULL_VOID(data, TAG, "Data is null");
-    VERIFY_NON_NULL_VOID(sentLength, TAG, "Sent data length holder is null");
+    VERIFY_NON_NULL(data, TAG, "Data is null");
+    VERIFY_NON_NULL(sentLength, TAG, "Sent data length holder is null");
 
     // Create remote endpoint
     CAEndpoint_t *remoteEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
@@ -655,7 +655,7 @@ void CAAdapterRecvData(const char *remoteAddress, const uint8_t *data, uint32_t
     if (NULL == remoteEndpoint)
     {
         OIC_LOG(ERROR, TAG, "Failed to create remote endpoint !");
-        return;
+        return CA_STATUS_FAILED;
     }
 
     // Add message to data queue
@@ -665,6 +665,8 @@ void CAAdapterRecvData(const char *remoteAddress, const uint8_t *data, uint32_t
 
     // Free remote endpoint
     CAFreeEndpoint(remoteEndpoint);
+
+    return CA_STATUS_OK;
 }
 
 void CAEDRErrorHandler(const char *remoteAddress, const uint8_t *data,
@@ -766,6 +768,18 @@ void CAEDRNotifyNetworkStatus(CANetworkStatus_t status)
     else
     {
         g_adapterState = false;
+
+        CAResult_t res = CAQueueingThreadClearData(g_sendQueueHandle);
+        if (res != CA_STATUS_OK)
+        {
+            OIC_LOG_V(ERROR, TAG, "CAQueueingThreadClearData failed[%d]", res);
+        }
+
+        res = CAQueueingThreadClearData(g_recvQueueHandle);
+        if (res != CA_STATUS_OK)
+        {
+            OIC_LOG_V(ERROR, TAG, "CAQueueingThreadClearData failed[%d]", res);
+        }
     }
 
     // Notify to upper layer
@@ -776,7 +790,7 @@ void CAEDRNotifyNetworkStatus(CANetworkStatus_t status)
         if (NULL != event)
         {
             if (CA_STATUS_OK != ca_thread_pool_add_task(g_edrThreadPool,
-                                                        CAEDROnNetworkStatusChanged,event))
+                                                        CAEDROnNetworkStatusChanged, event, NULL))
             {
                 OIC_LOG(ERROR, TAG, "Failed to create threadpool!");
                 return;
index 5d20ca9..0173190 100644 (file)
@@ -30,7 +30,7 @@
 #include <bluetooth_internal.h>
 
 #include "caedrinterface.h"
-#include "camutex.h"
+#include "octhread.h"
 #include "caedrendpoint.h"
 #include "caadapterutils.h"
 #include "caedrutils.h"
@@ -49,7 +49,7 @@
 /**
  * Mutex to synchronize the access to Bluetooth device information list.
  */
-static ca_mutex g_edrDeviceListMutex = NULL;
+static oc_mutex g_edrDeviceListMutex = NULL;
 
 /**
  * Peer Bluetooth device information list.
@@ -75,7 +75,7 @@ static u_arraylist_t *g_multicastDataList = NULL;
 /**
  * Mutex to synchronize the access to Pending multicast data list.
  */
-static ca_mutex g_multicastDataListMutex = NULL;
+static oc_mutex g_multicastDataListMutex = NULL;
 
 /**
  * To Store Adapter Mode information
@@ -174,7 +174,7 @@ void CAEDRSocketConnectionStateCallback(int result, bt_socket_connection_state_e
     {
         case BT_SOCKET_CONNECTED:
             {
-                ca_mutex_lock(g_edrDeviceListMutex);
+                oc_mutex_lock(g_edrDeviceListMutex);
                 CAResult_t res = CAGetEDRDevice(g_edrDeviceList, connection->remote_address,
                                                    &device);
                 if (CA_STATUS_OK != res)
@@ -185,34 +185,34 @@ void CAEDRSocketConnectionStateCallback(int result, bt_socket_connection_state_e
                     if (CA_STATUS_OK != res)
                     {
                         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed add device to list ret[%d]", res);
-                        ca_mutex_unlock(g_edrDeviceListMutex);
+                        oc_mutex_unlock(g_edrDeviceListMutex);
                         return;
                     }
 
                     if(!device)
                     {
                         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "EDRDevice is null!");
-                        ca_mutex_unlock(g_edrDeviceListMutex);
+                        oc_mutex_unlock(g_edrDeviceListMutex);
                         return;
                     }
 
                     device->socketFD = connection->socket_fd;
-                    ca_mutex_unlock(g_edrDeviceListMutex);
+                    oc_mutex_unlock(g_edrDeviceListMutex);
                     return;
                 }
 
                 if(!device)
                 {
                     OIC_LOG(ERROR, EDR_ADAPTER_TAG, "EDRDevice is null!");
-                    ca_mutex_unlock(g_edrDeviceListMutex);
+                    oc_mutex_unlock(g_edrDeviceListMutex);
                     return;
                 }
                 device->socketFD = connection->socket_fd;
                 while (device->pendingDataList)
                 {
                     EDRData *edrData = device->pendingDataList->data;
-                    res = CAEDRSendData(device->socketFD, edrData->data,
-                                        edrData->dataLength);
+                    res = CAEDRSendData(device->socketFD, device->remoteAddress,
+                                        edrData->data, edrData->dataLength);
                     if (CA_STATUS_OK != res)
                     {
                         OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to send pending data [%s]",
@@ -226,15 +226,15 @@ void CAEDRSocketConnectionStateCallback(int result, bt_socket_connection_state_e
                     // Remove the data which send from pending list
                     CARemoveEDRDataFromList(&device->pendingDataList);
                 }
-                ca_mutex_unlock(g_edrDeviceListMutex);
+                oc_mutex_unlock(g_edrDeviceListMutex);
             }
             break;
 
         case BT_SOCKET_DISCONNECTED:
             {
-                ca_mutex_lock(g_edrDeviceListMutex);
+                oc_mutex_lock(g_edrDeviceListMutex);
                 CARemoveEDRDeviceFromList(&g_edrDeviceList, connection->remote_address);
-                ca_mutex_unlock(g_edrDeviceListMutex);
+                oc_mutex_unlock(g_edrDeviceListMutex);
             }
             break;
 
@@ -271,10 +271,10 @@ void CAEDRDeviceDiscoveryCallback(int result, bt_adapter_device_discovery_state_
         case BT_ADAPTER_DEVICE_DISCOVERY_FINISHED:
             {
                 OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Discovery finished!");
-                ca_mutex_lock(g_multicastDataListMutex);
+                oc_mutex_lock(g_multicastDataListMutex);
                 u_arraylist_destroy(g_multicastDataList);
                 g_multicastDataList = NULL;
-                ca_mutex_unlock(g_multicastDataListMutex);
+                oc_mutex_unlock(g_multicastDataListMutex);
             }
             break;
 
@@ -287,18 +287,18 @@ void CAEDRDeviceDiscoveryCallback(int result, bt_adapter_device_discovery_state_
                                                         OIC_EDR_SERVICE_ID))
                 {
                     // Check if the deivce is already in the list
-                    ca_mutex_lock(g_edrDeviceListMutex);
+                    oc_mutex_lock(g_edrDeviceListMutex);
                     if (CA_STATUS_OK == CAGetEDRDevice(g_edrDeviceList,
                                                 discoveryInfo->remote_address, &device))
                     {
                         if(!device)
                         {
                             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "EDRDevice is null!");
-                            ca_mutex_unlock(g_edrDeviceListMutex);
+                            oc_mutex_unlock(g_edrDeviceListMutex);
                             return;
                         }
                         device->serviceSearched = true;
-                        ca_mutex_unlock(g_edrDeviceListMutex);
+                        oc_mutex_unlock(g_edrDeviceListMutex);
                         return;
                     }
 
@@ -308,14 +308,14 @@ void CAEDRDeviceDiscoveryCallback(int result, bt_adapter_device_discovery_state_
                     if (CA_STATUS_OK != res)
                     {
                         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to add device to list!");
-                        ca_mutex_unlock(g_edrDeviceListMutex);
+                        oc_mutex_unlock(g_edrDeviceListMutex);
                         return;
                     }
 
                     if(!device)
                     {
                         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "EDRDevice is null!");
-                        ca_mutex_unlock(g_edrDeviceListMutex);
+                        oc_mutex_unlock(g_edrDeviceListMutex);
                         return;
                     }
 
@@ -352,17 +352,17 @@ void CAEDRDeviceDiscoveryCallback(int result, bt_adapter_device_discovery_state_
                         }
                     }
                     device->serviceSearched = true;
-                    ca_mutex_unlock(g_edrDeviceListMutex);
+                    oc_mutex_unlock(g_edrDeviceListMutex);
                 }
                 else
                 {
-                    OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Device does not support OIC service!");
+                    OIC_LOG(INFO, EDR_ADAPTER_TAG, "Device does not support OIC service!");
                 }
             }
             break;
 
         default:
-            OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Unknown Bluetooth Adapter device discovery state");
+            OIC_LOG(INFO, EDR_ADAPTER_TAG, "Unknown Bluetooth Adapter device discovery state");
     }
 
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
@@ -379,7 +379,7 @@ void CAEDRServiceSearchedCallback(int32_t result,
         return;
     }
 
-    ca_mutex_lock(g_edrDeviceListMutex);
+    oc_mutex_lock(g_edrDeviceListMutex);
 
     EDRDevice *device = NULL;
     CAResult_t res = CAGetEDRDevice(g_edrDeviceList, sdpInfo->remote_address, &device);
@@ -388,7 +388,7 @@ void CAEDRServiceSearchedCallback(int32_t result,
         if (device->serviceSearched)
         {
             OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "Service is already searched for this device!");
-            ca_mutex_unlock(g_edrDeviceListMutex);
+            oc_mutex_unlock(g_edrDeviceListMutex);
             return;
         }
 
@@ -414,7 +414,7 @@ void CAEDRServiceSearchedCallback(int32_t result,
         }
     }
 
-    ca_mutex_unlock(g_edrDeviceListMutex);
+    oc_mutex_unlock(g_edrDeviceListMutex);
 
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
 }
@@ -565,12 +565,12 @@ CAResult_t CAEDRManagerInitializeMutex(void)
 
     if (!g_edrDeviceListMutex)
     {
-        g_edrDeviceListMutex = ca_mutex_new();
+        g_edrDeviceListMutex = oc_mutex_new();
     }
 
     if (!g_multicastDataListMutex)
     {
-        g_multicastDataListMutex = ca_mutex_new();
+        g_multicastDataListMutex = oc_mutex_new();
     }
 
     if (!g_edrDeviceListMutex || !g_multicastDataListMutex)
@@ -589,13 +589,13 @@ void CAEDRManagerTerminateMutex(void)
 
     if (g_edrDeviceListMutex)
     {
-        ca_mutex_free(g_edrDeviceListMutex);
+        oc_mutex_free(g_edrDeviceListMutex);
         g_edrDeviceListMutex = NULL;
     }
 
     if (g_multicastDataListMutex)
     {
-        ca_mutex_free(g_multicastDataListMutex);
+        oc_mutex_free(g_multicastDataListMutex);
         g_multicastDataListMutex = NULL;
     }
 
@@ -617,17 +617,17 @@ void CAEDRClientTerminate()
     // Free EDRDevices list
     if (g_edrDeviceListMutex)
     {
-        ca_mutex_lock(g_edrDeviceListMutex);
+        oc_mutex_lock(g_edrDeviceListMutex);
         CADestroyEDRDeviceList(&g_edrDeviceList);
-        ca_mutex_unlock(g_edrDeviceListMutex);
+        oc_mutex_unlock(g_edrDeviceListMutex);
     }
 
     if (g_multicastDataListMutex)
     {
-        ca_mutex_lock(g_multicastDataListMutex);
+        oc_mutex_lock(g_multicastDataListMutex);
         u_arraylist_destroy(g_multicastDataList);
         g_multicastDataList = NULL;
-        ca_mutex_unlock(g_multicastDataListMutex);
+        oc_mutex_unlock(g_multicastDataListMutex);
     }
 
     // Free the mutex
@@ -639,7 +639,7 @@ void CAEDRClientDisconnectAll(void)
 {
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
 
-    ca_mutex_lock(g_edrDeviceListMutex);
+    oc_mutex_lock(g_edrDeviceListMutex);
 
     EDRDeviceList *cur = g_edrDeviceList;
     while (cur != NULL)
@@ -660,7 +660,7 @@ void CAEDRClientDisconnectAll(void)
         }
     }
 
-    ca_mutex_unlock(g_edrDeviceListMutex);
+    oc_mutex_unlock(g_edrDeviceListMutex);
 
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "OUT");
 }
@@ -685,7 +685,7 @@ CAResult_t CAEDRClientSendUnicastData(const char *remoteAddress,
     }
 
     // Check the connection existence with remote device
-    ca_mutex_lock(g_edrDeviceListMutex);
+    oc_mutex_lock(g_edrDeviceListMutex);
     CAResult_t result = CAGetEDRDevice(g_edrDeviceList, remoteAddress, &device);
     if (CA_STATUS_OK != result)
     {
@@ -696,7 +696,7 @@ CAResult_t CAEDRClientSendUnicastData(const char *remoteAddress,
         {
             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed create device and add to list!");
 
-            ca_mutex_unlock(g_edrDeviceListMutex);
+            oc_mutex_unlock(g_edrDeviceListMutex);
             return CA_STATUS_FAILED;
         }
 
@@ -709,7 +709,7 @@ CAResult_t CAEDRClientSendUnicastData(const char *remoteAddress,
             // Remove device from list
             CARemoveEDRDeviceFromList(&g_edrDeviceList, remoteAddress);
 
-            ca_mutex_unlock(g_edrDeviceListMutex);
+            oc_mutex_unlock(g_edrDeviceListMutex);
             return CA_STATUS_FAILED;
         }
     }
@@ -720,11 +720,11 @@ CAResult_t CAEDRClientSendUnicastData(const char *remoteAddress,
         // Remove device from list
         CARemoveEDRDeviceFromList(&g_edrDeviceList, remoteAddress);
 
-        ca_mutex_unlock(g_edrDeviceListMutex);
+        oc_mutex_unlock(g_edrDeviceListMutex);
         return CA_STATUS_FAILED;
     }
 
-    ca_mutex_unlock(g_edrDeviceListMutex);
+    oc_mutex_unlock(g_edrDeviceListMutex);
 
     if (-1 == device->socketFD)
     {
@@ -753,7 +753,7 @@ CAResult_t CAEDRClientSendUnicastData(const char *remoteAddress,
     }
     else
     {
-        result = CAEDRSendData(device->socketFD, data, dataLength);
+        result = CAEDRSendData(device->socketFD, device->remoteAddress, data, dataLength);
         if (CA_STATUS_OK != result)
         {
             OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Failed to send data!");
@@ -780,7 +780,7 @@ CAResult_t CAEDRClientSendMulticastData(const uint8_t *data,
     }
 
     // Send the packet to all OIC devices
-    ca_mutex_lock(g_edrDeviceListMutex);
+    oc_mutex_lock(g_edrDeviceListMutex);
 
     EDRDeviceList *curList = g_edrDeviceList;
     CAResult_t result = CA_STATUS_FAILED;
@@ -826,7 +826,7 @@ CAResult_t CAEDRClientSendMulticastData(const uint8_t *data,
         }
         else
         {
-            result = CAEDRSendData(device->socketFD, data, dataLength);
+            result = CAEDRSendData(device->socketFD, device->remoteAddress ,data, dataLength);
             if (CA_STATUS_OK != result)
             {
                 OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "Failed to send data to [%s] !",
@@ -835,7 +835,7 @@ CAResult_t CAEDRClientSendMulticastData(const uint8_t *data,
         }
     }
 
-    ca_mutex_unlock(g_edrDeviceListMutex);
+    oc_mutex_unlock(g_edrDeviceListMutex);
 
     if(g_isDiscoveryServer)
     {
@@ -861,13 +861,13 @@ CAResult_t CAEDRClientSendMulticastData(const uint8_t *data,
             multicastData->dataLength = dataLength;
 
             // Add the data to pending multicast data list.
-            ca_mutex_lock(g_multicastDataListMutex);
+            oc_mutex_lock(g_multicastDataListMutex);
             if (NULL == g_multicastDataList)
             {
                 g_multicastDataList = u_arraylist_create();
             }
             u_arraylist_add(g_multicastDataList, (void *)multicastData);
-            ca_mutex_unlock(g_multicastDataListMutex);
+            oc_mutex_unlock(g_multicastDataListMutex);
         }
     }
 
@@ -945,16 +945,16 @@ void CAEDRDataRecvCallback(bt_socket_received_data_s *data, void *userData)
     }
 
     // Get EDR device from list
-    ca_mutex_lock(g_edrDeviceListMutex);
+    oc_mutex_lock(g_edrDeviceListMutex);
     CAResult_t result = CAGetEDRDeviceBySocketId(g_edrDeviceList, data->socket_fd, &device);
     if (CA_STATUS_OK != result)
     {
         OIC_LOG(ERROR, EDR_ADAPTER_TAG, "Could not find the device!");
 
-        ca_mutex_unlock(g_edrDeviceListMutex);
+        oc_mutex_unlock(g_edrDeviceListMutex);
         return;
     }
-    ca_mutex_unlock(g_edrDeviceListMutex);
+    oc_mutex_unlock(g_edrDeviceListMutex);
 
     //: TODO Need to check if 'check required for socket still connected or not'
     if (!device)
index 78af3ff..319af2b 100644 (file)
 #include "caedrutils.h"
 #include "logger.h"
 
-CAResult_t CAEDRSendData(int serverFD, const void *data, uint32_t dataLength)
+CAResult_t CAEDRSendData(int serverFD, const char *addr, const void *data, uint32_t dataLength)
 {
     OIC_LOG(DEBUG, EDR_ADAPTER_TAG, "IN");
 
     VERIFY_NON_NULL(data, EDR_ADAPTER_TAG, "Data is null");
+    VERIFY_NON_NULL(addr, EDR_ADAPTER_TAG, "Addr is null");
 
     if (0 > serverFD)
     {
@@ -42,14 +43,28 @@ CAResult_t CAEDRSendData(int serverFD, const void *data, uint32_t dataLength)
     }
 
     int dataLen = bt_socket_send_data(serverFD, (const char *)data, dataLength);
-    if (dataLen == -1)
+    int errcode = get_last_result();
+
+    if (TIZEN_ERROR_NONE == errcode)
     {
-        OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "sending data failed!, soketid [%d]", serverFD);
-        return CA_SOCKET_OPERATION_FAILED;
+        CALogSendStateInfo(CA_ADAPTER_RFCOMM_BTEDR, addr, 0, dataLength, true, NULL);
     }
-    else if (dataLen == 0)
+    else
     {
-        OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "soketid [%d] may be disconnected?", serverFD);
+        if (dataLen == -1)
+        {
+            OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "sending data failed!, soketid [%d] errmsg [%s]",
+                      serverFD, get_error_message(errcode));
+        }
+        else if (dataLen == 0)
+        {
+            OIC_LOG_V(ERROR, EDR_ADAPTER_TAG, "soketid [%d] may be disconnected? errmsg [%s]",
+                      serverFD, get_error_message(errcode));
+        }
+
+        CALogSendStateInfo(CA_ADAPTER_RFCOMM_BTEDR, addr, 0, dataLength,
+                           false, get_error_message(errcode));
+
         return CA_SOCKET_OPERATION_FAILED;
     }
 
index 63ee31c..b5387fd 100644 (file)
@@ -28,7 +28,7 @@
 #define CA_EDR_ENDPOINT_H_
 
 #include <bluetooth.h>
-
+#include <tizen.h>
 #include "cacommon.h"
 
 #ifdef __cplusplus
@@ -48,7 +48,7 @@ extern "C"
  * @retval ::CA_STATUS_INVALID_PARAM  Invalid input arguments.
  * @retval ::CA_STATUS_FAILED Operation failed.
  */
-CAResult_t CAEDRSendData(int serverFD, const void *data, uint32_t dataLength);
+CAResult_t CAEDRSendData(int serverFD, const char *addr, const void *data, uint32_t dataLength);
 
 #ifdef __cplusplus
 } /* extern "C" */
index de179c3..f527f1d 100644 (file)
@@ -31,7 +31,7 @@
 #include "caadapterutils.h"
 #include "caedrutils.h"
 #include "logger.h"
-#include "camutex.h"
+#include "octhread.h"
 #include "cacommon.h"
 #include "caedrdevicelist.h"
 
index 7ee11e6..a12b289 100644 (file)
@@ -10,6 +10,7 @@ env.PrependUnique(CPPPATH = [ os.path.join(src_dir, 'android') ])
 src_files = [ 'caleclient.c',
               'caleserver.c',
               'calenwmonitor.c',
-              'caleutils.c' ]
+              'caleutils.c',
+              'calestate.c' ]
 
 Return('src_files')
index 96cf9e1..2ac416c 100644 (file)
@@ -23,6 +23,7 @@
 #include <jni.h>
 #include <unistd.h>
 
+#include "calestate.h"
 #include "caleclient.h"
 #include "caleserver.h"
 #include "caleutils.h"
 #include "oic_malloc.h"
 #include "oic_string.h"
 #include "cathreadpool.h" /* for thread pool */
-#include "camutex.h"
+#include "octhread.h"
 #include "uarraylist.h"
 #include "org_iotivity_ca_CaLeClientInterface.h"
 
-#define TAG PCF("OIC_CA_LE_CLIENT")
+//#define TAG PCF("OIC_CA_LE_CLIENT")
+#define TAG BLE_CLIENT_TAG
 
 #define MICROSECS_PER_SEC 1000000
 #define WAIT_TIME_WRITE_CHARACTERISTIC 10 * MICROSECS_PER_SEC
 #define GATT_REQUEST_NOT_SUPPORTED          6
 #define GATT_WRITE_NOT_PERMITTED            3
 
+// samsung
+#define BLE_SCAN_API_LEVEL (100) //(21)
+#define BLE_MIN_API_LEVEL  (18)
+#define HIDDEN_API
+
 static ca_thread_pool_t g_threadPoolHandle = NULL;
 
 JavaVM *g_jvm;
@@ -75,40 +82,45 @@ static jbyteArray g_sendBuffer = NULL;
 static uint32_t g_targetCnt = 0;
 static uint32_t g_currentSentCnt = 0;
 static bool g_isFinishedSendData = false;
-static ca_mutex g_SendFinishMutex = NULL;
-static ca_mutex g_threadMutex = NULL;
-static ca_cond g_threadCond = NULL;
-static ca_cond g_deviceDescCond = NULL;
-
-static ca_mutex g_threadSendMutex = NULL;
-static ca_mutex g_threadWriteCharacteristicMutex = NULL;
-static ca_cond g_threadWriteCharacteristicCond = NULL;
+static oc_mutex g_SendFinishMutex = NULL;
+static oc_mutex g_threadMutex = NULL;
+static oc_cond g_threadCond = NULL;
+static oc_cond g_deviceDescCond = NULL;
+
+static oc_mutex g_threadSendMutex = NULL;
+static oc_mutex g_threadWriteCharacteristicMutex = NULL;
+static oc_cond g_threadWriteCharacteristicCond = NULL;
 static bool g_isSignalSetFlag = false;
 
-static ca_mutex g_bleReqRespClientCbMutex = NULL;
-static ca_mutex g_bleServerBDAddressMutex = NULL;
+static oc_mutex g_bleReqRespClientCbMutex = NULL;
+static oc_mutex g_bleServerBDAddressMutex = NULL;
 
-static ca_mutex g_deviceListMutex = NULL;
-static ca_mutex g_gattObjectMutex = NULL;
-static ca_mutex g_deviceStateListMutex = NULL;
+static oc_mutex g_deviceListMutex = NULL;
+static oc_mutex g_gattObjectMutex = NULL;
+static oc_mutex g_deviceStateListMutex = NULL;
 
-static ca_mutex g_deviceScanRetryDelayMutex = NULL;
-static ca_cond g_deviceScanRetryDelayCond = NULL;
+static oc_mutex g_deviceScanRetryDelayMutex = NULL;
+static oc_cond g_deviceScanRetryDelayCond = NULL;
 
-static ca_mutex g_threadScanIntervalMutex = NULL;
-static ca_cond g_threadScanIntervalCond = NULL;
+static oc_mutex g_threadScanIntervalMutex = NULL;
+static oc_cond g_threadScanIntervalCond = NULL;
 
-static ca_mutex g_threadSendStateMutex = NULL;
+static oc_mutex g_threadSendStateMutex = NULL;
+static oc_mutex g_setValueMutex = NULL;
 
 static int32_t g_scanIntervalTime = WAIT_TIME_SCAN_INTERVAL_DEFAULT;
 static int32_t g_scanIntervalTimePrev = WAIT_TIME_SCAN_INTERVAL_DEFAULT;
 static int32_t g_intervalCount = 0;
 static bool g_isWorkingScanThread = false;
-static CALEScanState_t g_curScanningStep = BLE_SCAN_DISABLE;
+static CALEScanState_t g_curScanningStep = BLE_SCAN_NONE;
 static CALEScanState_t g_nextScanningStep = BLE_SCAN_ENABLE;
 
 static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
+static int32_t g_jniIntSdk = -1;
 
+static bool g_setHighQoS = true;
+static bool g_setFullScanFlag = true;
+jclass g_LEInterface = NULL;
 /**
  * check if retry logic for connection routine has to be stopped or not.
  * in case of error value including this method, connection routine has to be stopped.
@@ -136,6 +148,23 @@ static bool CALECheckConnectionStateValue(jint state)
     }
 }
 
+/**
+ * delete global reference for g_sendBuffer
+ * @param[in]   env                   JNI interface pointer.
+ */
+static void CALEDeleteSendBuffer(JNIEnv *env)
+{
+    OIC_LOG(INFO, TAG, "CALEDeleteSendBuffer");
+    oc_mutex_lock(g_setValueMutex);
+    if (g_sendBuffer)
+    {
+        OIC_LOG(INFO, TAG, "delete send buffer");
+        (*env)->DeleteGlobalRef(env, g_sendBuffer);
+        g_sendBuffer = NULL;
+    }
+    oc_mutex_unlock(g_setValueMutex);
+}
+
 void CALEClientSetScanInterval(int32_t intervalTime, int32_t workingCount,
                                CALEScanState_t nextScanningStep)
 {
@@ -163,8 +192,10 @@ void CALERestartScanWithInterval(int32_t intervalTime, int32_t workingCount,
         return;
     }
 
+    oc_mutex_lock(g_threadScanIntervalMutex);
     CALEClientSetScanInterval(intervalTime, workingCount, nextScanningStep);
-    ca_cond_signal(g_threadScanIntervalCond);
+    oc_cond_signal(g_threadScanIntervalCond);
+    oc_mutex_unlock(g_threadScanIntervalMutex);
 }
 
 static void CALEScanThread(void* object)
@@ -176,7 +207,6 @@ static void CALEScanThread(void* object)
     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
     if (JNI_OK != res)
     {
-        OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
 
         if (JNI_OK != res)
@@ -187,7 +217,7 @@ static void CALEScanThread(void* object)
         isAttached = true;
     }
 
-    ca_mutex_lock(g_threadScanIntervalMutex);
+    oc_mutex_lock(g_threadScanIntervalMutex);
     while(g_isWorkingScanThread)
     {
         OIC_LOG(DEBUG, TAG, "scan waiting time out");
@@ -200,7 +230,7 @@ static void CALEScanThread(void* object)
                 OIC_LOG(INFO, TAG, "CALEClientStopScan has failed");
             }
         }
-        else
+        else if (BLE_SCAN_DISABLE == g_curScanningStep)
         {
             //start scan
             CAResult_t ret = CALEClientStartScan();
@@ -209,9 +239,15 @@ static void CALEScanThread(void* object)
                 OIC_LOG(INFO, TAG, "CALEClientStartScan has failed");
             }
         }
+        else
+        {
+            OIC_LOG(DEBUG, TAG, "scan thread is started");
+            // standby scanning
+            CALEClientSetScanInterval(0, 0, BLE_SCAN_DISABLE);
+        }
 
         OIC_LOG_V(DEBUG, TAG, "wait for Scan Interval Time during %d sec", g_scanIntervalTime);
-        if (CA_WAIT_SUCCESS == ca_cond_wait_for(g_threadScanIntervalCond,
+        if (OC_WAIT_SUCCESS == oc_cond_wait_for(g_threadScanIntervalCond,
                                                 g_threadScanIntervalMutex,
                                                 g_scanIntervalTime * MICROSECS_PER_SEC))
         {
@@ -248,7 +284,7 @@ static void CALEScanThread(void* object)
            }
         }
     }
-    ca_mutex_unlock(g_threadScanIntervalMutex);
+    oc_mutex_unlock(g_threadScanIntervalMutex);
 
     if (isAttached)
     {
@@ -258,8 +294,6 @@ static void CALEScanThread(void* object)
 
 CAResult_t CALEClientStartScanWithInterval()
 {
-    OIC_LOG(DEBUG, TAG, "IN - CALEClientStartScanWithInterval");
-
     if (g_isWorkingScanThread)
     {
         OIC_LOG(DEBUG, TAG, "scan interval logic already running");
@@ -267,28 +301,26 @@ CAResult_t CALEClientStartScanWithInterval()
     }
 
     // initialize scan flags
-    g_curScanningStep = BLE_SCAN_DISABLE;
+    g_curScanningStep = BLE_SCAN_NONE;
     g_isWorkingScanThread = true;
     g_intervalCount = 0;
     g_scanIntervalTime = g_scanIntervalTimePrev;
     g_nextScanningStep = BLE_SCAN_ENABLE;
 
-    if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
-                                                CALEScanThread, NULL))
+    if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CALEScanThread, NULL, NULL))
     {
         OIC_LOG(ERROR, TAG, "Failed to create read thread!");
         g_isWorkingScanThread = false;
         return CA_STATUS_FAILED;
     }
 
-    OIC_LOG(DEBUG, TAG, "OUT - CALEClientStartScanWithInterval");
     return CA_STATUS_OK;
 }
 
 void CALEClientStopScanWithInterval()
 {
     g_isWorkingScanThread = false;
-    ca_cond_signal(g_threadScanIntervalCond);
+    oc_cond_signal(g_threadScanIntervalCond);
 }
 
 //getting jvm
@@ -325,7 +357,6 @@ CAResult_t CALECreateJniInterfaceObject()
     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
     if (JNI_OK != res)
     {
-        OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
 
         if (JNI_OK != res)
@@ -351,7 +382,7 @@ CAResult_t CALECreateJniInterfaceObject()
     if (!jApplicationContext)
     {
         OIC_LOG(ERROR, TAG, "Could not get application context");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jclass jni_LEInterface = (*env)->FindClass(env, "org/iotivity/ca/CaLeClientInterface");
@@ -360,6 +391,7 @@ CAResult_t CALECreateJniInterfaceObject()
         OIC_LOG(ERROR, TAG, "Could not get CaLeClientInterface class");
         goto error_exit;
     }
+    g_LEInterface = (jclass)((*env)->NewGlobalRef(env, jni_LEInterface));
 
     jmethodID LeInterfaceConstructorMethod = (*env)->GetMethodID(env, jni_LEInterface, "<init>",
                                                                  "(Landroid/content/Context;)V");
@@ -380,7 +412,7 @@ CAResult_t CALECreateJniInterfaceObject()
     return CA_STATUS_OK;
 
 error_exit:
-
+    CACheckJNIException(env);
     if (isAttached)
     {
         (*g_jvm)->DetachCurrentThread(g_jvm);
@@ -406,7 +438,6 @@ CAResult_t CALEClientInitialize()
     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
     if (JNI_OK != res)
     {
-        OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
 
         if (JNI_OK != res)
@@ -417,8 +448,8 @@ CAResult_t CALEClientInitialize()
         isAttached = true;
     }
 
-    CAResult_t ret = CALECheckPlatformVersion(env, 18);
-    if (CA_STATUS_OK != ret)
+    g_jniIntSdk = CALEGetBuildVersion(env);
+    if (g_jniIntSdk < BLE_MIN_API_LEVEL)
     {
         OIC_LOG(ERROR, TAG, "it is not supported");
 
@@ -426,11 +457,10 @@ CAResult_t CALEClientInitialize()
         {
             (*g_jvm)->DetachCurrentThread(g_jvm);
         }
-
-        return ret;
+        return CA_STATUS_FAILED;
     }
 
-    ret = CALEClientInitGattMutexVaraibles();
+    CAResult_t ret = CALEClientInitGattMutexVaraibles();
     if (CA_STATUS_OK != ret)
     {
         OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
@@ -444,13 +474,13 @@ CAResult_t CALEClientInitialize()
         return ret;
     }
 
-    g_deviceDescCond = ca_cond_new();
+    g_deviceDescCond = oc_cond_new();
 
     // init mutex for send logic
-    g_threadCond = ca_cond_new();
-    g_threadWriteCharacteristicCond = ca_cond_new();
-    g_deviceScanRetryDelayCond = ca_cond_new();
-    g_threadScanIntervalCond =  ca_cond_new();
+    g_threadCond = oc_cond_new();
+    g_threadWriteCharacteristicCond = oc_cond_new();
+    g_deviceScanRetryDelayCond = oc_cond_new();
+    g_threadScanIntervalCond =  oc_cond_new();
 
     CALEClientCreateDeviceList();
     CALEClientJNISetContext();
@@ -505,7 +535,6 @@ void CALEClientTerminate()
     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
     if (JNI_OK != res)
     {
-        OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
 
         if (JNI_OK != res)
@@ -516,6 +545,13 @@ void CALEClientTerminate()
         isAttached = true;
     }
 
+    // stop scan
+    CAResult_t ret = CALEClientStopScan();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(INFO, TAG, "CALEClientStopScan has failed");
+    }
+
     if (g_leScanCallback)
     {
         (*env)->DeleteGlobalRef(env, g_leScanCallback);
@@ -528,24 +564,32 @@ void CALEClientTerminate()
         g_leGattCallback = NULL;
     }
 
-    if (g_sendBuffer)
+    if (g_LEInterface)
     {
-        (*env)->DeleteGlobalRef(env, g_sendBuffer);
-        g_sendBuffer = NULL;
+        (*env)->DeleteGlobalRef(env, g_LEInterface);
+        g_LEInterface = NULL;
     }
 
+    CALEDeleteSendBuffer(env);
+
     if (g_uuidList)
     {
         (*env)->DeleteGlobalRef(env, g_uuidList);
         g_uuidList = NULL;
     }
 
-    CAResult_t ret = CALEClientRemoveAllDeviceState();
+    ret = CALERemoveAllDeviceState(g_deviceStateList,
+                                   g_deviceStateListMutex);
     if (CA_STATUS_OK != ret)
     {
-        OIC_LOG(ERROR, TAG, "CALEClientRemoveAllDeviceState has failed");
+        OIC_LOG(ERROR, TAG, "CALERemoveAllDeviceState has failed");
     }
 
+    oc_mutex_lock(g_deviceStateListMutex);
+    OICFree(g_deviceStateList);
+    g_deviceStateList = NULL;
+    oc_mutex_unlock(g_deviceStateListMutex);
+
     ret = CALEClientRemoveAllScanDevices(env);
     if (CA_STATUS_OK != ret)
     {
@@ -563,11 +607,11 @@ void CALEClientTerminate()
     CALEClientTerminateGattMutexVariables();
     CALEClientDestroyJniInterface();
 
-    ca_cond_free(g_deviceDescCond);
-    ca_cond_free(g_threadCond);
-    ca_cond_free(g_threadWriteCharacteristicCond);
-    ca_cond_free(g_deviceScanRetryDelayCond);
-    ca_cond_free(g_threadScanIntervalCond);
+    oc_cond_free(g_deviceDescCond);
+    oc_cond_free(g_threadCond);
+    oc_cond_free(g_threadWriteCharacteristicCond);
+    oc_cond_free(g_deviceScanRetryDelayCond);
+    oc_cond_free(g_threadScanIntervalCond);
 
     g_deviceDescCond = NULL;
     g_threadCond = NULL;
@@ -586,6 +630,74 @@ void CALEClientTerminate()
     }
 }
 
+jobject CALEClientHiddenConnectGatt(jobject btDevice, const char* address, jboolean autoconnect)
+{
+    OIC_LOG(INFO, TAG, "IN - CALEClientHiddenConnectGatt");
+
+    if (!g_jvm)
+    {
+        OIC_LOG(ERROR, TAG, "g_jvm is null");
+        return NULL;
+    }
+
+    bool isAttached = false;
+    JNIEnv* env = NULL;
+    jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
+    if (JNI_OK != res)
+    {
+        res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
+
+        if (JNI_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
+            return NULL;
+        }
+        isAttached = true;
+    }
+
+    jstring jni_address = (*env)->NewStringUTF(env, address);
+    jmethodID jni_connectGattHiddenMethod = (*env)->GetStaticMethodID(env, g_LEInterface,
+                                                                     "connectGattforHidden",
+                                                                     "(Landroid/bluetooth/BluetoothDevice;"
+                                                                     "Ljava/lang/String;Z)"
+                                                                     "Landroid/bluetooth/BluetoothGatt;");
+    if (!jni_connectGattHiddenMethod)
+    {
+        OIC_LOG(ERROR, TAG, "Could not get jni_connectGatt Hidden Method");
+        goto error_exit;
+    }
+
+    jobject gatt = (*env)->CallStaticObjectMethod(env, g_LEInterface,
+                                                  jni_connectGattHiddenMethod,
+                                                  btDevice, jni_address, autoconnect);
+
+    if (CACheckJNIException(env))
+    {
+        OIC_LOG(ERROR, TAG, "connectGattforHidden has failed");
+        goto detach_thread;
+    }
+
+    OIC_LOG(INFO, TAG, "OUT - CALEClientHiddenConnectGatt");
+
+    if (isAttached)
+    {
+        (*g_jvm)->DetachCurrentThread(g_jvm);
+    }
+
+    return gatt;
+
+error_exit:
+    CACheckJNIException(env);
+
+detach_thread:
+    if (isAttached)
+    {
+        (*g_jvm)->DetachCurrentThread(g_jvm);
+    }
+
+    return NULL;
+}
+
 CAResult_t CALEClientDestroyJniInterface()
 {
     OIC_LOG(DEBUG, TAG, "CALEClientDestroyJniInterface");
@@ -601,7 +713,6 @@ CAResult_t CALEClientDestroyJniInterface()
     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
     if (JNI_OK != res)
     {
-        OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
 
         if (JNI_OK != res)
@@ -630,12 +741,10 @@ CAResult_t CALEClientDestroyJniInterface()
 
     (*env)->CallStaticVoidMethod(env, jni_LeInterface, jni_InterfaceDestroyMethod);
 
-    if ((*env)->ExceptionCheck(env))
+    if (CACheckJNIException(env))
     {
         OIC_LOG(ERROR, TAG, "destroyLeInterface has failed");
-        (*env)->ExceptionDescribe(env);
-        (*env)->ExceptionClear(env);
-        goto error_exit;
+        goto detach_thread;
     }
 
     OIC_LOG(DEBUG, TAG, "Destroy instance for CaLeClientInterface");
@@ -648,7 +757,9 @@ CAResult_t CALEClientDestroyJniInterface()
     return CA_STATUS_OK;
 
 error_exit:
+    CACheckJNIException(env);
 
+detach_thread:
     if (isAttached)
     {
         (*g_jvm)->DetachCurrentThread(g_jvm);
@@ -673,11 +784,17 @@ void CALEClientSendFinish(JNIEnv *env, jobject gatt)
     CALEClientUpdateSendCnt(env);
 }
 
+CAResult_t CALEClientSendNegotiationMessage(const char* address)
+{
+    VERIFY_NON_NULL(address, TAG, "address is null");
+
+    return CALEClientSendUnicastMessageImpl(address, NULL, 0);
+}
+
 CAResult_t CALEClientSendUnicastMessage(const char* address,
                                         const uint8_t* data,
                                         const uint32_t dataLen)
 {
-    OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessage(%s, %p)", address, data);
     VERIFY_NON_NULL(address, TAG, "address is null");
     VERIFY_NON_NULL(data, TAG, "data is null");
 
@@ -701,7 +818,6 @@ CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
     if (JNI_OK != res)
     {
-        OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
 
         if (JNI_OK != res)
@@ -791,13 +907,14 @@ CAResult_t CALEClientIsThereScannedDevices(JNIEnv *env, const char* address)
         for (size_t i = 0; i < RETRIES; ++i)
         {
             OIC_LOG(DEBUG, TAG, "waiting for target device");
-            if (ca_cond_wait_for(g_deviceDescCond,
+            if (oc_cond_wait_for(g_deviceDescCond,
                                  g_threadSendMutex,
-                                 TIMEOUT) == CA_WAIT_SUCCESS)
+                                 TIMEOUT) == OC_WAIT_SUCCESS)
             {
-                ca_mutex_lock(g_deviceListMutex);
+                OIC_LOG(DEBUG, TAG, "time out");
+                oc_mutex_lock(g_deviceListMutex);
                 size_t scannedDeviceLen = u_arraylist_length(g_deviceList);
-                ca_mutex_unlock(g_deviceListMutex);
+                oc_mutex_unlock(g_deviceListMutex);
 
                 if (0 < scannedDeviceLen)
                 {
@@ -813,16 +930,16 @@ CAResult_t CALEClientIsThereScannedDevices(JNIEnv *env, const char* address)
                         {
                             OIC_LOG(INFO, TAG, "waiting..");
 
-                            ca_mutex_lock(g_deviceScanRetryDelayMutex);
-                            if (ca_cond_wait_for(g_deviceScanRetryDelayCond,
+                            oc_mutex_lock(g_deviceScanRetryDelayMutex);
+                            if (oc_cond_wait_for(g_deviceScanRetryDelayCond,
                                                  g_deviceScanRetryDelayMutex,
-                                                 MICROSECS_PER_SEC) == CA_WAIT_SUCCESS)
+                                                 MICROSECS_PER_SEC) == OC_WAIT_SUCCESS)
                             {
                                 OIC_LOG(INFO, TAG, "finish to waiting for target device");
-                                ca_mutex_unlock(g_deviceScanRetryDelayMutex);
+                                oc_mutex_unlock(g_deviceScanRetryDelayMutex);
                                 break;
                             }
-                            ca_mutex_unlock(g_deviceScanRetryDelayMutex);
+                            oc_mutex_unlock(g_deviceScanRetryDelayMutex);
                             // time out
 
                             // checking whether a target device is found while waiting for time-out.
@@ -858,10 +975,9 @@ CAResult_t CALEClientIsThereScannedDevices(JNIEnv *env, const char* address)
 CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t* data,
                                             const uint32_t dataLen)
 {
-    OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
+    OIC_LOG_V(INFO, TAG, "CALEClientSendUnicastMessageImpl, address: %s, data: %p", address,
               data);
     VERIFY_NON_NULL(address, TAG, "address is null");
-    VERIFY_NON_NULL(data, TAG, "data is null");
 
     if (!g_jvm)
     {
@@ -874,7 +990,6 @@ CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t*
     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
     if (JNI_OK != res)
     {
-        OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
         if (JNI_OK != res)
         {
@@ -884,7 +999,7 @@ CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t*
         isAttached = true;
     }
 
-    ca_mutex_lock(g_threadSendMutex);
+    oc_mutex_lock(g_threadSendMutex);
 
     CALEClientSetSendFinishFlag(false);
 
@@ -918,24 +1033,26 @@ CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t*
             if (!setAddress)
             {
                 OIC_LOG(ERROR, TAG, "setAddress is null");
+                CACheckJNIException(env);
                 goto error_exit;
             }
 
-            OIC_LOG_V(DEBUG, TAG, "remote device address is %s", setAddress);
-
-            if (!strcmp(setAddress, address))
+            if (!strcasecmp(setAddress, address))
             {
                 (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
                 (*env)->DeleteLocalRef(env, jni_setAddress);
 
-                if (g_sendBuffer)
+                CALEDeleteSendBuffer(env);
+
+                if (data && dataLen > 0)
                 {
-                    (*env)->DeleteGlobalRef(env, g_sendBuffer);
-                    g_sendBuffer = NULL;
+                    jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
+                    CACheckJNIException(env);
+                    (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
+                    CACheckJNIException(env);
+                    g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
+                    CACheckJNIException(env);
                 }
-                jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
-                (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
-                g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
 
                 // Target device to send message is just one.
                 g_targetCnt = 1;
@@ -959,38 +1076,52 @@ CAResult_t CALEClientSendUnicastMessageImpl(const char* address, const uint8_t*
 
     // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
     // if there is no connection state.
-    ca_mutex_lock(g_threadMutex);
+    oc_mutex_lock(g_threadMutex);
     if (!g_isFinishedSendData)
     {
         OIC_LOG(DEBUG, TAG, "waiting send finish signal");
-        ca_cond_wait(g_threadCond, g_threadMutex);
-        OIC_LOG(DEBUG, TAG, "the data was sent");
+        oc_cond_wait(g_threadCond, g_threadMutex);
+        OIC_LOG(DEBUG, TAG, "connection / send is finished for unicast");
     }
-    ca_mutex_unlock(g_threadMutex);
+    oc_mutex_unlock(g_threadMutex);
 
     if (isAttached)
     {
         (*g_jvm)->DetachCurrentThread(g_jvm);
     }
 
-    ca_mutex_unlock(g_threadSendMutex);
+    oc_mutex_unlock(g_threadSendMutex);
     OIC_LOG(INFO, TAG, "unicast - send logic has finished");
-    if (CALEClientIsValidState(address, CA_LE_SEND_STATE,
-                               STATE_SEND_SUCCESS))
+    if (CALEIsValidState(address, CA_LE_SEND_STATE,
+                         STATE_SEND_SUCCESS,
+                         g_deviceStateList,
+                         g_deviceStateListMutex))
+    {
+        OIC_LOG(INFO, TAG, "send success");
+        ret = CA_STATUS_OK;
+    }
+    else if (CALEIsValidState(address, CA_LE_SEND_STATE,
+                              STATE_SEND_MTU_NEGO_SUCCESS,
+                              g_deviceStateList,
+                              g_deviceStateListMutex))
     {
+        OIC_LOG(INFO, TAG, "mtu nego success");
         ret = CA_STATUS_OK;
     }
     else
     {
+        OIC_LOG(ERROR, TAG, "send failure");
         ret = CA_SEND_FAILED;
     }
 
     // reset send state
-    CAResult_t resetRet = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
-                                                      STATE_SEND_NONE);
+    CAResult_t resetRet = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
+                                                STATE_SEND_NONE,
+                                                g_deviceStateList,
+                                                g_deviceStateListMutex);
     if (CA_STATUS_OK != resetRet)
     {
-        OIC_LOG_V(ERROR, TAG, "CALEClientUpdateDeviceState has failed (%d)", resetRet);
+        OIC_LOG_V(ERROR, TAG, "CALEUpdateDeviceState has failed (%d)", resetRet);
         ret = CA_SEND_FAILED;
     }
 
@@ -1003,7 +1134,7 @@ error_exit:
         (*g_jvm)->DetachCurrentThread(g_jvm);
     }
 
-    ca_mutex_unlock(g_threadSendMutex);
+    oc_mutex_unlock(g_threadSendMutex);
     return CA_SEND_FAILED;
 }
 
@@ -1020,16 +1151,12 @@ CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
         return CA_STATUS_FAILED;
     }
 
-    ca_mutex_lock(g_threadSendMutex);
+    oc_mutex_lock(g_threadSendMutex);
 
     CALEClientSetSendFinishFlag(false);
 
     OIC_LOG(DEBUG, TAG, "set byteArray for data");
-    if (g_sendBuffer)
-    {
-        (*env)->DeleteGlobalRef(env, g_sendBuffer);
-        g_sendBuffer = NULL;
-    }
+    CALEDeleteSendBuffer(env);
 
     CAResult_t res = CALEClientIsThereScannedDevices(env, NULL);
     if (CA_STATUS_OK != res)
@@ -1064,20 +1191,20 @@ CAResult_t CALEClientSendMulticastMessageImpl(JNIEnv *env, const uint8_t* data,
     OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
 
     // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
-    ca_mutex_lock(g_threadMutex);
+    oc_mutex_lock(g_threadMutex);
     if (!g_isFinishedSendData)
     {
         OIC_LOG(DEBUG, TAG, "waiting send finish signal");
-        ca_cond_wait(g_threadCond, g_threadMutex);
-        OIC_LOG(DEBUG, TAG, "the data was sent");
+        oc_cond_wait(g_threadCond, g_threadMutex);
+        OIC_LOG(DEBUG, TAG, "connection / send is finished for multicast");
     }
-    ca_mutex_unlock(g_threadMutex);
-    ca_mutex_unlock(g_threadSendMutex);
+    oc_mutex_unlock(g_threadMutex);
+    oc_mutex_unlock(g_threadSendMutex);
     OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
     return CA_STATUS_OK;
 
 error_exit:
-    ca_mutex_unlock(g_threadSendMutex);
+    oc_mutex_unlock(g_threadSendMutex);
     OIC_LOG(ERROR, TAG, "OUT - CALEClientSendMulticastMessageImpl");
     return CA_SEND_FAILED;
 }
@@ -1099,11 +1226,28 @@ CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
         if (!address)
         {
             OIC_LOG(ERROR, TAG, "address is not available");
+            CACheckJNIException(env);
             return CA_STATUS_FAILED;
         }
-        ca_mutex_lock(g_deviceStateListMutex);
-        state = CALEClientGetStateInfo(address);
-        ca_mutex_unlock(g_deviceStateListMutex);
+        oc_mutex_lock(g_deviceStateListMutex);
+        state = CALEGetStateInfo(address, g_deviceStateList);
+        oc_mutex_unlock(g_deviceStateListMutex);
+    }
+
+    // Since disconnect event can be caused from BT stack while connection step is running.
+    // DeviceState has to have current status for processing send failure.
+    OIC_LOG(INFO, TAG, "set STATE_SEND_PREPARING");
+    CAResult_t res = CALEClientUpdateDeviceStateWithBtDevice(env, device,
+                                                             CA_LE_SEND_STATE,
+                                                             STATE_SEND_PREPARING);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceStateWithBtDevice has failed");
+        if (address)
+        {
+            (*env)->ReleaseStringUTFChars(env, jni_address, address);
+        }
+        return CA_STATUS_FAILED;
     }
 
     if (!state)
@@ -1137,8 +1281,10 @@ CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
     }
     else
     {
-        if (CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
-                                   STATE_SERVICE_CONNECTED))
+        if (CALEIsValidState(address, CA_LE_CONNECTION_STATE,
+                             STATE_SERVICE_CONNECTED,
+                             g_deviceStateList,
+                             g_deviceStateListMutex))
         {
             OIC_LOG(INFO, TAG, "GATT has already connected");
 
@@ -1159,13 +1305,17 @@ CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
             }
             (*env)->ReleaseStringUTFChars(env, jni_address, address);
         }
-        else if(CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
-                                       STATE_CONNECTED))
+        else if(CALEIsValidState(address, CA_LE_CONNECTION_STATE,
+                                 STATE_CONNECTED,
+                                 g_deviceStateList,
+                                 g_deviceStateListMutex))
         {
             OIC_LOG(INFO, TAG, "service connecting...");
         }
-        else if(CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
-                                       STATE_DISCONNECTED))
+        else if(CALEIsValidState(address, CA_LE_CONNECTION_STATE,
+                                 STATE_DISCONNECTED,
+                                 g_deviceStateList,
+                                 g_deviceStateListMutex))
         {
             OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
 
@@ -1187,8 +1337,10 @@ CAResult_t CALEClientSendData(JNIEnv *env, jobject device)
 
             OIC_LOG(DEBUG, TAG, "start to connect LE");
             jobject gatt = CALEClientConnect(env, device,
-                                             CALEClientGetFlagFromState(env, jni_address,
-                                                                        CA_LE_AUTO_CONNECT_FLAG));
+                                             CALEGetFlagFromState(env, jni_address,
+                                                                  CA_LE_AUTO_CONNECT_FLAG,
+                                                                  g_deviceStateList,
+                                                                  g_deviceStateListMutex));
 
             if (NULL == gatt)
             {
@@ -1218,6 +1370,7 @@ jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
     if (!jni_obj_device)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_device is null");
+        CACheckJNIException(env);
         return NULL;
     }
 
@@ -1225,6 +1378,7 @@ jstring CALEClientGetAddressFromGattObj(JNIEnv *env, jobject gatt)
     if (!jni_address)
     {
         OIC_LOG(ERROR, TAG, "jni_address is null");
+        CACheckJNIException(env);
         return NULL;
     }
 
@@ -1254,11 +1408,9 @@ CAResult_t CALEClientGattClose(JNIEnv *env, jobject bluetoothGatt)
     OIC_LOG(DEBUG, TAG, "request to close GATT");
     (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
 
-    if ((*env)->ExceptionCheck(env))
+    if (CACheckJNIException(env))
     {
         OIC_LOG(ERROR, TAG, "closeGATT has failed");
-        (*env)->ExceptionDescribe(env);
-        (*env)->ExceptionClear(env);
         return CA_STATUS_FAILED;
     }
 
@@ -1284,8 +1436,6 @@ CAResult_t CALEClientStartScan()
     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
     if (JNI_OK != res)
     {
-        OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
-
         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
         if (JNI_OK != res)
         {
@@ -1301,11 +1451,31 @@ CAResult_t CALEClientStartScan()
     // scan gatt server with UUID
     if (g_leScanCallback && g_uuidList)
     {
-#ifdef UUID_SCAN
-        ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
-#else
-        ret = CALEClientStartScanImpl(env, g_leScanCallback);
-#endif
+        if (g_jniIntSdk >= BLE_SCAN_API_LEVEL)
+        {
+            if (!g_setFullScanFlag)
+            {
+                //new uuid scan with callback
+                ret = CALEClientStartScanWithUUIDImplForV21(env, g_uuidList, g_leScanCallback);
+            }
+            else
+            {
+                //new full scan with callback
+                ret = CALEClientStartScanImplForV21(env, g_leScanCallback);
+            }
+        }
+        else
+        {
+            if (!g_setFullScanFlag)
+            {
+                ret = CALEClientStartScanWithUUIDImpl(env, g_uuidList, g_leScanCallback);
+            }
+            else
+            {
+                ret = CALEClientStartScanImpl(env, g_leScanCallback);
+            }
+        }
+
         if (CA_STATUS_OK != ret)
         {
             if (CA_ADAPTER_NOT_ENABLED == ret)
@@ -1329,6 +1499,7 @@ CAResult_t CALEClientStartScan()
 
 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
 {
+    OIC_LOG(DEBUG, TAG, "CALEClientStartScanImpl IN");
     VERIFY_NON_NULL(callback, TAG, "callback is null");
     VERIFY_NON_NULL(env, TAG, "env is null");
 
@@ -1343,6 +1514,7 @@ CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
     if (!jni_cid_BTAdapter)
     {
         OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
+        CACheckJNIException(env);
         return CA_STATUS_FAILED;
     }
 
@@ -1353,6 +1525,7 @@ CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
     if (!jni_mid_getDefaultAdapter)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
+        CACheckJNIException(env);
         (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
         return CA_STATUS_FAILED;
     }
@@ -1364,6 +1537,7 @@ CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
     if (!jni_mid_startLeScan)
     {
         OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
+        CACheckJNIException(env);
         (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
         return CA_STATUS_FAILED;
     }
@@ -1374,6 +1548,7 @@ CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
     if (!jni_obj_BTAdapter)
     {
         OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
+        CACheckJNIException(env);
         (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
         return CA_STATUS_FAILED;
     }
@@ -1385,6 +1560,7 @@ CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
     if (!jni_obj_startLeScan)
     {
         OIC_LOG(INFO, TAG, "startLeScan has failed");
+        CACheckJNIException(env);
     }
     else
     {
@@ -1396,8 +1572,113 @@ CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback)
     return CA_STATUS_OK;
 }
 
+CAResult_t CALEClientStartScanImplForV21(JNIEnv *env, jobject callback)
+{
+    OIC_LOG(DEBUG, TAG, "CALEClientStartScanImplForV21 IN");
+    VERIFY_NON_NULL(callback, TAG, "callback is null");
+    VERIFY_NON_NULL(env, TAG, "env is null");
+
+    if (!CALEIsEnableBTAdapter(env))
+    {
+        OIC_LOG(INFO, TAG, "BT adapter is not enabled");
+        return CA_ADAPTER_NOT_ENABLED;
+    }
+
+    CAResult_t res = CA_STATUS_FAILED;
+    // get default bt adapter class
+    jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
+    if (!jni_cid_BTAdapter)
+    {
+        OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
+        CACheckJNIException(env);
+        return CA_STATUS_FAILED;
+    }
+
+    jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
+                                                                    "getDefaultAdapter",
+                                                                    "()Landroid/bluetooth/"
+                                                                    "BluetoothAdapter;");
+    if (!jni_mid_getDefaultAdapter)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
+        (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+        return CA_STATUS_FAILED;
+    }
+
+    jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
+                                                               jni_mid_getDefaultAdapter);
+    if (!jni_obj_BTAdapter)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
+        (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+        return CA_STATUS_FAILED;
+    }
+
+    // get bluetoothLeScanner class
+    jclass jni_cid_leScanner = (*env)->FindClass(env, CLASSPATH_LE_SCANNER);
+    if (!jni_cid_leScanner)
+    {
+        OIC_LOG(ERROR, TAG, "getState From leScanner: jni_cid_leScanner is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+        (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
+        return CA_STATUS_FAILED;
+    }
+
+    // get remote bt adapter method
+    jmethodID jni_mid_getBluetoothLeScanner = (*env)->GetMethodID(env, jni_cid_BTAdapter,
+                                                                  "getBluetoothLeScanner",
+                                                                  "()Landroid/bluetooth/"
+                                                                  "le/BluetoothLeScanner;");
+    if (!jni_mid_getBluetoothLeScanner)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeScanner is null");
+        CACheckJNIException(env);
+        goto error_exit;
+    }
+
+    // get startScan(ScanCallback callback) method
+    jmethodID jni_mid_startScan = (*env)->GetMethodID(env, jni_cid_leScanner, "startScan",
+                                                      "(Landroid/bluetooth/le/ScanCallback;)V");
+    if (!jni_mid_startScan)
+    {
+        OIC_LOG(ERROR, TAG, "startScan: jni_mid_startScan is null");
+        CACheckJNIException(env);
+        goto error_exit;
+    }
+
+    // gat le scanner object
+    jobject jni_obj_leScanner = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
+                                                         jni_mid_getBluetoothLeScanner);
+    if (!jni_obj_leScanner)
+    {
+        OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_leScanner is null");
+        CACheckJNIException(env);
+        goto error_exit;
+    }
+
+    // call startScan method
+    OIC_LOG(INFO, TAG, "CALL API - startScan(for level21)");
+    (*env)->CallVoidMethod(env, jni_obj_leScanner, jni_mid_startScan, callback);
+    if (CACheckJNIException(env))
+    {
+        OIC_LOG(INFO, TAG, "startScan has failed");
+        (*env)->DeleteLocalRef(env, jni_obj_leScanner);
+        goto error_exit;
+    }
+    res = CA_STATUS_OK;
+    (*env)->DeleteLocalRef(env, jni_obj_leScanner);
+
+error_exit:
+    (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+    (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
+    (*env)->DeleteLocalRef(env, jni_cid_leScanner);
+    return res;
+}
+
 CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
 {
+    OIC_LOG(DEBUG, TAG, "CALEClientStartScanWithUUIDImpl IN");
     VERIFY_NON_NULL(callback, TAG, "callback is null");
     VERIFY_NON_NULL(uuids, TAG, "uuids is null");
     VERIFY_NON_NULL(env, TAG, "env is null");
@@ -1412,6 +1693,7 @@ CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobj
     if (!jni_cid_BTAdapter)
     {
         OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
+        CACheckJNIException(env);
         return CA_STATUS_FAILED;
     }
 
@@ -1422,6 +1704,7 @@ CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobj
     if (!jni_mid_getDefaultAdapter)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
+        CACheckJNIException(env);
         (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
         return CA_STATUS_FAILED;
     }
@@ -1433,6 +1716,7 @@ CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobj
     if (!jni_mid_startLeScan)
     {
         OIC_LOG(ERROR, TAG, "startLeScan: jni_mid_startLeScan is null");
+        CACheckJNIException(env);
         (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
         return CA_STATUS_FAILED;
     }
@@ -1443,6 +1727,7 @@ CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobj
     if (!jni_obj_BTAdapter)
     {
         OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_BTAdapter is null");
+        CACheckJNIException(env);
         (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
         return CA_STATUS_FAILED;
     }
@@ -1454,6 +1739,7 @@ CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobj
     if (!jni_obj_startLeScan)
     {
         OIC_LOG(INFO, TAG, "startLeScan has failed");
+        CACheckJNIException(env);
     }
     else
     {
@@ -1465,87 +1751,474 @@ CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobj
     return CA_STATUS_OK;
 }
 
-jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
+CAResult_t CALEClientStartScanWithUUIDImplForV21(JNIEnv *env, jobjectArray uuids, jobject callback)
 {
-    VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
-    VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
+    OIC_LOG(DEBUG, TAG, "CALEClientStartScanWithUUIDImplForV21 IN");
+    VERIFY_NON_NULL(callback, TAG, "callback is null");
+    VERIFY_NON_NULL(uuids, TAG, "uuids is null");
+    VERIFY_NON_NULL(env, TAG, "env is null");
 
-    // setting UUID
-    jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
-    if (!jni_cid_uuid)
+    if (!CALEIsEnableBTAdapter(env))
     {
-        OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
-        return NULL;
+        OIC_LOG(INFO, TAG, "BT adapter is not enabled");
+        return CA_ADAPTER_NOT_ENABLED;
     }
 
-    jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
-                                                             "(Ljava/lang/String;)"
-                                                             "Ljava/util/UUID;");
-    if (!jni_mid_fromString)
+    // get bluetoothLeScanner class
+    jclass jni_cid_leScanner = (*env)->FindClass(env, CLASSPATH_LE_SCANNER);
+    if (!jni_cid_leScanner)
     {
-        OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
-        return NULL;
+        OIC_LOG(ERROR, TAG, "getState From leScanner: jni_cid_leScanner is null");
+        CACheckJNIException(env);
+        return CA_STATUS_FAILED;
     }
 
-    jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
-    jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
-                                                          jni_uuid);
-    if (!jni_obj_uuid)
+    // get startScan(with UUID) method
+    jmethodID jni_mid_startScan = (*env)->GetMethodID(env, jni_cid_leScanner,
+                                                      "startScan",
+                                                      "(Ljava/util/List;"
+                                                      "Landroid/bluetooth/le/ScanSettings;"
+                                                      "Landroid/bluetooth/le/ScanCallback;"
+                                                      ")V");
+    if (!jni_mid_startScan)
     {
-        OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
-        return NULL;
+        OIC_LOG(ERROR, TAG, "startScan: jni_mid_startScan is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_cid_leScanner);
+        return CA_STATUS_FAILED;
     }
+    (*env)->DeleteLocalRef(env, jni_cid_leScanner);
 
-    return jni_obj_uuid;
-}
-
-CAResult_t CALEClientStopScan()
-{
-    if (!g_jvm)
+    // get scanfilter.Builder class id
+    jclass jni_cid_scanfilterBuilder = (*env)->FindClass(env,
+                                                         "android/bluetooth/le/"
+                                                         "ScanFilter$Builder");
+    if (!jni_cid_scanfilterBuilder)
     {
-        OIC_LOG(ERROR, TAG, "g_jvm is null");
+        OIC_LOG(ERROR, TAG, "scanfilter: jni_cid_scanfilterBuilder is null");
+        CACheckJNIException(env);
         return CA_STATUS_FAILED;
     }
 
-    bool isAttached = false;
-    JNIEnv* env = NULL;
-    jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
-    if (JNI_OK != res)
+    // get scanfilter.Builder(ctor) method id
+    jmethodID jni_mid_scanfilterBuilderCtor = (*env)->GetMethodID(env, jni_cid_scanfilterBuilder,
+                                                                  "<init>", "()V");
+    if (!jni_mid_scanfilterBuilderCtor)
     {
-        OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
-        res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
-        if (JNI_OK != res)
-        {
-            OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
-            return CA_STATUS_FAILED;
-        }
-        isAttached = true;
+        OIC_LOG(ERROR, TAG, "scanfilter: jni_cid_scanfilterBuilderCtor is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
+        return CA_STATUS_FAILED;
     }
 
-    CAResult_t ret = CALEClientStopScanImpl(env, g_leScanCallback);
-    if (CA_STATUS_OK != ret)
+    // call scanfilter.Builder()
+    jobject jni_obj_scanfilterBuilder = (*env)->NewObject(env, jni_cid_scanfilterBuilder,
+                                                          jni_mid_scanfilterBuilderCtor);
+    if (!jni_obj_scanfilterBuilder)
     {
-        if (CA_ADAPTER_NOT_ENABLED == ret)
-        {
-            OIC_LOG(DEBUG, TAG, "Adapter is disabled");
-        }
-        else
-        {
-            OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
-        }
+        OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanfilterBuilder is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
+        return CA_STATUS_FAILED;
     }
 
-    if (isAttached)
+    // get scanfilter.Builder.setServiceUuid method id
+    jmethodID jni_mid_setServiceUuid = (*env)->GetMethodID(env, jni_cid_scanfilterBuilder,
+                                                           "setServiceUuid",
+                                                           "(Landroid/os/ParcelUuid;)Landroid/"
+                                                           "bluetooth/le/ScanFilter$Builder;");
+    if (!jni_mid_setServiceUuid)
     {
-        (*g_jvm)->DetachCurrentThread(g_jvm);
+        OIC_LOG(ERROR, TAG, "scanfilter: jni_mid_setServiceUuid is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
+        return CA_STATUS_FAILED;
     }
 
-    return ret;
-}
+    // get scanfilter.Builder.build method id
+    jmethodID jni_mid_build_scanfilterBuilder = (*env)->GetMethodID(env,
+                                                                    jni_cid_scanfilterBuilder,
+                                                                    "build",
+                                                                    "()Landroid/bluetooth/le/"
+                                                                    "ScanFilter;");
+    if (!jni_mid_build_scanfilterBuilder)
+    {
+        OIC_LOG(ERROR, TAG, "scanfilter: jni_mid_build_scanfilterBuilder is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
+        return CA_STATUS_FAILED;
+    }
+    (*env)->DeleteLocalRef(env, jni_cid_scanfilterBuilder);
+
+    // call ParcelUuid.fromSting(uuid)
+    jobject jni_obj_parcelUuid = CALEGetParcelUuidFromString(env, OIC_GATT_SERVICE_UUID);
+    if (!jni_obj_parcelUuid)
+    {
+        OIC_LOG(ERROR, TAG, "scanSettings: jni_obj_parcelUuid is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
+        return CA_STATUS_FAILED;
+    }
+
+    // call setServiceUuid(uuid)
+    jobject jni_obj_setServiceUuid = (*env)->CallObjectMethod(env,
+                                                              jni_obj_scanfilterBuilder,
+                                                              jni_mid_setServiceUuid,
+                                                              jni_obj_parcelUuid);
+    if (!jni_obj_setServiceUuid)
+    {
+        OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_setServiceUuid is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
+        (*env)->DeleteLocalRef(env, jni_obj_parcelUuid);
+        return CA_STATUS_FAILED;
+    }
+    (*env)->DeleteLocalRef(env, jni_obj_parcelUuid);
+    (*env)->DeleteLocalRef(env, jni_obj_setServiceUuid);
+
+    // call build()
+    jobject jni_obj_scanfilter = (*env)->CallObjectMethod(env,
+                                                          jni_obj_scanfilterBuilder,
+                                                          jni_mid_build_scanfilterBuilder);
+    if (!jni_obj_scanfilter)
+    {
+        OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanfilter is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
+        return CA_STATUS_FAILED;
+    }
+    (*env)->DeleteLocalRef(env, jni_obj_scanfilterBuilder);
+
+    // get scanSettings.Builder class id
+    jclass jni_cid_scanSettingsBuilder = (*env)->FindClass(env,
+                                                          "android/bluetooth/le/"
+                                                          "ScanSettings$Builder");
+    if (!jni_cid_scanSettingsBuilder)
+    {
+        OIC_LOG(ERROR, TAG, "scanSettings: jni_cid_scanSettingsBuilder is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
+        return CA_STATUS_FAILED;
+    }
+
+    // get scanSettings.Builder(ctor) method id
+    jmethodID jni_mid_scanSettingsBuilderCtor = (*env)->GetMethodID(env, jni_cid_scanSettingsBuilder,
+                                                                    "<init>", "()V");
+    if (!jni_mid_scanSettingsBuilderCtor)
+    {
+        OIC_LOG(ERROR, TAG, "scanSettings: jni_mid_scanSettingsBuilderCtor is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
+        (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
+        return CA_STATUS_FAILED;
+    }
+
+    // get scanSettings.Builder.setScanMode method id
+    jmethodID jni_mid_setScanMode = (*env)->GetMethodID(env, jni_cid_scanSettingsBuilder,
+                                                        "setScanMode",
+                                                         "(I)Landroid/"
+                                                         "bluetooth/le/ScanSettings$Builder;");
+    if (!jni_mid_setScanMode)
+    {
+        OIC_LOG(ERROR, TAG, "scanSettings: jni_mid_setScanMode is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
+        (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
+        return CA_STATUS_FAILED;
+    }
+
+    // get scanSettings.Builder.build method id
+    jmethodID jni_mid_build_scanSettings = (*env)->GetMethodID(env,
+                                                               jni_cid_scanSettingsBuilder,
+                                                               "build",
+                                                               "()Landroid/bluetooth/le/"
+                                                               "ScanSettings;");
+    if (!jni_mid_build_scanSettings)
+    {
+        OIC_LOG(ERROR, TAG, "scanSettings: jni_mid_build_scanSettings is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
+        (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
+        return CA_STATUS_FAILED;
+    }
+
+    // call scanSettings.Builder()
+    jobject jni_obj_scanSettingBuilder = (*env)->NewObject(env, jni_cid_scanSettingsBuilder,
+                                                           jni_mid_scanSettingsBuilderCtor);
+    if (!jni_obj_scanSettingBuilder)
+    {
+        OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanSettingBuilder is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
+        (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
+        return CA_STATUS_FAILED;
+    }
+    (*env)->DeleteLocalRef(env, jni_cid_scanSettingsBuilder);
+
+    jclass jni_cid_arrayList = (*env)->FindClass(env, "java/util/ArrayList");
+    if (!jni_cid_arrayList)
+    {
+        OIC_LOG(ERROR, TAG, "ArrayList: jni_cid_arrayList is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
+        (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
+        return CA_STATUS_FAILED;
+    }
+
+    jmethodID jni_mid_arrayListCtor = (*env)->GetMethodID(env, jni_cid_arrayList, "<init>", "()V");
+    if (!jni_mid_arrayListCtor)
+    {
+        OIC_LOG(ERROR, TAG, "ArrayList: jni_mid_arrayListCtor is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
+        (*env)->DeleteLocalRef(env, jni_cid_arrayList);
+        (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
+        return CA_STATUS_FAILED;
+    }
+
+    jmethodID jni_mid_arrayListAdd = (*env)->GetMethodID(env, jni_cid_arrayList,
+                                                         "add", "(Ljava/lang/Object;)Z");
+    if (!jni_mid_arrayListAdd)
+    {
+        OIC_LOG(ERROR, TAG, "ArrayList: jni_mid_arrayListAdd is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
+        (*env)->DeleteLocalRef(env, jni_cid_arrayList);
+        (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
+        return CA_STATUS_FAILED;
+    }
+
+    jobject jni_obj_filterList = (*env)->NewObject(env, jni_cid_arrayList, jni_mid_arrayListCtor);
+    if (!jni_obj_filterList)
+    {
+        OIC_LOG(ERROR, TAG, "ArrayList: jni_obj_filterList is null");
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
+        (*env)->DeleteLocalRef(env, jni_cid_arrayList);
+        (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
+        return CA_STATUS_FAILED;
+    }
+    (*env)->DeleteLocalRef(env, jni_cid_arrayList);
+
+    jboolean jni_bool_arrayListIsAdded = (*env)->CallBooleanMethod(env, jni_obj_filterList,
+                                                                   jni_mid_arrayListAdd,
+                                                                   jni_obj_scanfilter);
+    if (!jni_bool_arrayListIsAdded)
+    {
+        OIC_LOG(ERROR, TAG, "ArrayList: jni_bool_arrayListIsAdded is null");
+        (*env)->DeleteLocalRef(env, jni_obj_filterList);
+        (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
+        (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
+        return CA_STATUS_FAILED;
+    }
+    (*env)->DeleteLocalRef(env, jni_obj_scanfilter);
+
+    // get ScanSettings.SCAN_MODE_BALANCED jint value
+    jint jni_int_scanBalancedMode = CALEGetConstantsValue(env, CLASSPATH_LE_SCANSETTINGS,
+                                                          "SCAN_MODE_BALANCED");
+    CACheckJNIException(env);
+
+    // call setScanMode(SCAN_MODE_BALANCED)
+    jobject jni_obj_setScanMode = (*env)->CallObjectMethod(env, jni_obj_scanSettingBuilder,
+                                                           jni_mid_setScanMode,
+                                                           jni_int_scanBalancedMode);
+    if (!jni_obj_setScanMode)
+    {
+        OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_setScanMode is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
+        (*env)->DeleteLocalRef(env, jni_obj_filterList);
+        return CA_STATUS_FAILED;
+    }
+
+    // call build
+    jobject jni_obj_scanSettings = (*env)->CallObjectMethod(env, jni_obj_scanSettingBuilder,
+                                                                 jni_mid_build_scanSettings);
+    if (!jni_obj_scanSettings)
+    {
+        OIC_LOG(ERROR, TAG, "scanfilter: jni_obj_scanSettings is null");
+        (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
+        (*env)->DeleteLocalRef(env, jni_obj_filterList);
+        return CA_STATUS_FAILED;
+    }
+    (*env)->DeleteLocalRef(env, jni_obj_scanSettingBuilder);
+
+    CAResult_t res = CA_STATUS_FAILED;
+    // get default bt adapter class
+    jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
+    if (!jni_cid_BTAdapter)
+    {
+        OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
+        CACheckJNIException(env);
+        goto error_exit;
+    }
+
+    jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
+                                                                    "getDefaultAdapter",
+                                                                    "()Landroid/bluetooth/"
+                                                                    "BluetoothAdapter;");
+    if (!jni_mid_getDefaultAdapter)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+        goto error_exit;
+    }
+
+    jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
+                                                               jni_mid_getDefaultAdapter);
+    if (!jni_obj_BTAdapter)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+        goto error_exit;
+    }
+
+    // get remote bt adapter method
+    jmethodID jni_mid_getBluetoothLeScanner = (*env)->GetMethodID(env, jni_cid_BTAdapter,
+                                                                  "getBluetoothLeScanner",
+                                                                  "()Landroid/bluetooth/"
+                                                                  "le/BluetoothLeScanner;");
+    if (!jni_mid_getBluetoothLeScanner)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeScanner is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+        (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
+        goto error_exit;
+    }
+
+    // get le scanner object
+    jobject jni_obj_leScanner = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
+                                                         jni_mid_getBluetoothLeScanner);
+    if (!jni_obj_leScanner)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_leScanner is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+        (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
+        goto error_exit;
+    }
+    (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+    (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
+
+    // call startScan method
+    OIC_LOG(INFO, TAG, "CALL API - startScanWithUUID(for level 21)");
+    (*env)->CallVoidMethod(env, jni_obj_leScanner, jni_mid_startScan, jni_obj_filterList,
+                           jni_obj_scanSettings, callback);
+    if (CACheckJNIException(env))
+    {
+        OIC_LOG(INFO, TAG, "startScan has failed");
+    }
+    else
+    {
+        res = CA_STATUS_OK;
+    }
+    (*env)->DeleteLocalRef(env, jni_obj_leScanner);
+
+error_exit:
+    (*env)->DeleteLocalRef(env, jni_obj_scanSettings);
+    (*env)->DeleteLocalRef(env, jni_obj_filterList);
+    return res;
+}
+
+jobject CALEClientGetUUIDObject(JNIEnv *env, const char* uuid)
+{
+    VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
+    VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
+
+    // setting UUID
+    jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
+    if (!jni_cid_uuid)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_uuid is null");
+        goto error_exit;
+    }
+
+    jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString",
+                                                             "(Ljava/lang/String;)"
+                                                             "Ljava/util/UUID;");
+    if (!jni_mid_fromString)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_fromString is null");
+        goto error_exit;
+    }
+
+    jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
+    CACheckJNIException(env);
+    jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString,
+                                                          jni_uuid);
+    if (!jni_obj_uuid)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_uuid is null");
+        goto error_exit;
+    }
+
+    return jni_obj_uuid;
+
+error_exit:
+    CACheckJNIException(env);
+    return NULL;
+}
+
+CAResult_t CALEClientStopScan()
+{
+    if (!g_jvm)
+    {
+        OIC_LOG(ERROR, TAG, "g_jvm is null");
+        return CA_STATUS_FAILED;
+    }
+
+    bool isAttached = false;
+    JNIEnv* env = NULL;
+    jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
+    if (JNI_OK != res)
+    {
+        res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
+        if (JNI_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
+            return CA_STATUS_FAILED;
+        }
+        isAttached = true;
+    }
+
+    CAResult_t ret = CA_STATUS_FAILED;
+
+    if (g_jniIntSdk >= BLE_SCAN_API_LEVEL)
+    {
+        ret = CALEClientStopScanImplForV21(env, g_leScanCallback);
+    }
+    else
+    {
+        ret = CALEClientStopScanImpl(env, g_leScanCallback);
+    }
+
+    if (CA_STATUS_OK != ret)
+    {
+        if (CA_ADAPTER_NOT_ENABLED == ret)
+        {
+            OIC_LOG(DEBUG, TAG, "Adapter is disabled");
+        }
+        else
+        {
+            OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
+        }
+    }
+
+    if (isAttached)
+    {
+        (*g_jvm)->DetachCurrentThread(g_jvm);
+    }
+
+    return ret;
+}
 
 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
 {
-    OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl");
+    OIC_LOG(DEBUG, TAG, "CALEClientStopScanImpl IN");
     VERIFY_NON_NULL(callback, TAG, "callback is null");
     VERIFY_NON_NULL(env, TAG, "env is null");
 
@@ -1560,6 +2233,7 @@ CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
     if (!jni_cid_BTAdapter)
     {
         OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
+        CACheckJNIException(env);
         return CA_STATUS_FAILED;
     }
 
@@ -1570,6 +2244,7 @@ CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
     if (!jni_mid_getDefaultAdapter)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
+        CACheckJNIException(env);
         (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
         return CA_STATUS_FAILED;
     }
@@ -1581,16 +2256,18 @@ CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
     if (!jni_mid_stopLeScan)
     {
         OIC_LOG(ERROR, TAG, "stopLeScan: jni_mid_stopLeScan is null");
+        CACheckJNIException(env);
         (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
         return CA_STATUS_FAILED;
     }
 
-    // gat bt adapter object
+    // get bt adapter object
     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
                                                                jni_mid_getDefaultAdapter);
     if (!jni_obj_BTAdapter)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
+        CACheckJNIException(env);
         (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
         return CA_STATUS_FAILED;
     }
@@ -1598,13 +2275,11 @@ CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
     OIC_LOG(INFO, TAG, "CALL API - stopLeScan");
     // call start le scan method
     (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
-    if ((*env)->ExceptionCheck(env))
+    if (CACheckJNIException(env))
     {
         OIC_LOG(ERROR, TAG, "stopLeScan has failed");
         (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
         (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
-        (*env)->ExceptionDescribe(env);
-        (*env)->ExceptionClear(env);
         return CA_STATUS_FAILED;
     }
 
@@ -1613,94 +2288,111 @@ CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback)
     return CA_STATUS_OK;
 }
 
-CAResult_t CALEClientSetFlagToState(JNIEnv *env, jstring jni_address, jint state_idx, jboolean flag)
+CAResult_t CALEClientStopScanImplForV21(JNIEnv *env, jobject callback)
 {
-    OIC_LOG(DEBUG, TAG, "IN - CALEClientSetFlagToState");
-    VERIFY_NON_NULL(env, TAG, "env");
-    VERIFY_NON_NULL(jni_address, TAG, "jni_address");
+    OIC_LOG(DEBUG, TAG, "CALEClientStopScanImplForV21 IN");
+    VERIFY_NON_NULL(callback, TAG, "callback is null");
+    VERIFY_NON_NULL(env, TAG, "env is null");
 
-    ca_mutex_lock(g_deviceStateListMutex);
+    if (!CALEIsEnableBTAdapter(env))
+    {
+        OIC_LOG(INFO, TAG, "BT adapter is not enabled");
+        return CA_ADAPTER_NOT_ENABLED;
+    }
 
-    char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
-    if (!address)
+    // get default bt adapter class
+    jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
+    if (!jni_cid_BTAdapter)
     {
-        OIC_LOG(ERROR, TAG, "address is not available");
+        OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_cid_BTAdapter is null");
+        CACheckJNIException(env);
         return CA_STATUS_FAILED;
     }
 
-    if (CALEClientIsDeviceInList(address))
+    jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
+                                                                    "getDefaultAdapter",
+                                                                    "()Landroid/bluetooth/"
+                                                                    "BluetoothAdapter;");
+    if (!jni_mid_getDefaultAdapter)
     {
-        CALEState_t* curState = CALEClientGetStateInfo(address);
-        if(!curState)
-        {
-            OIC_LOG(ERROR, TAG, "curState is null");
-            (*env)->ReleaseStringUTFChars(env, jni_address, address);
-            ca_mutex_unlock(g_deviceStateListMutex);
-            return CA_STATUS_FAILED;
-        }
-        OIC_LOG_V(INFO, TAG, "%d flag is set : %d", state_idx, flag);
-
-        switch(state_idx)
-        {
-            case CA_LE_AUTO_CONNECT_FLAG:
-                curState->autoConnectFlag = flag;
-                break;
-            case CA_LE_DESCRIPTOR_FOUND:
-                curState->isDescriptorFound = flag;
-                break;
-            default:
-                break;
-        }
+        OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+        return CA_STATUS_FAILED;
     }
 
-    (*env)->ReleaseStringUTFChars(env, jni_address, address);
-    ca_mutex_unlock(g_deviceStateListMutex);
-    OIC_LOG(DEBUG, TAG, "OUT - CALEClientSetFlagToState");
-    return CA_STATUS_OK;
-}
+    jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
+                                                               jni_mid_getDefaultAdapter);
+    if (!jni_obj_BTAdapter)
+    {
+        OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+        return CA_STATUS_FAILED;
+    }
 
-jboolean CALEClientGetFlagFromState(JNIEnv *env, jstring jni_address, jint state_idx)
-{
-    OIC_LOG(DEBUG, TAG, "IN - CALEClientGetFlagFromState");
-    VERIFY_NON_NULL_RET(env, TAG, "env", false);
-    VERIFY_NON_NULL_RET(jni_address, TAG, "jni_address", false);
+    // get bluetoothLeScanner class
+    jclass jni_cid_leScanner = (*env)->FindClass(env, CLASSPATH_LE_SCANNER);
+    if (!jni_cid_leScanner)
+    {
+        OIC_LOG(ERROR, TAG, "getState From leScanner: jni_cid_leScanner is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+        (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
+        return CA_STATUS_FAILED;
+    }
 
-    ca_mutex_lock(g_deviceStateListMutex);
+    // get remote bt adapter method
+    jmethodID jni_mid_getBluetoothLeScanner = (*env)->GetMethodID(env, jni_cid_BTAdapter,
+                                                                  "getBluetoothLeScanner",
+                                                                  "()Landroid/bluetooth/"
+                                                                  "le/BluetoothLeScanner;");
+    if (!jni_mid_getBluetoothLeScanner)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeScanner is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
+        (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
+        (*env)->DeleteLocalRef(env, jni_cid_leScanner);
+        return CA_STATUS_FAILED;
+    }
+    (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
 
-    char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
-    if (!address)
+    // get stopScan(ScanCallback callback) method
+    jmethodID jni_mid_stopScan = (*env)->GetMethodID(env, jni_cid_leScanner, "stopScan",
+                                                      "(Landroid/bluetooth/le/ScanCallback;)V");
+    if (!jni_mid_stopScan)
     {
-        OIC_LOG(ERROR, TAG, "address is not available");
-        ca_mutex_unlock(g_deviceStateListMutex);
-        return JNI_FALSE;
+        OIC_LOG(ERROR, TAG, "stopScan: jni_mid_stopScan is null");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
+        (*env)->DeleteLocalRef(env, jni_cid_leScanner);
+        return CA_STATUS_FAILED;
     }
+    (*env)->DeleteLocalRef(env, jni_cid_leScanner);
 
-    CALEState_t* curState = CALEClientGetStateInfo(address);
-    (*env)->ReleaseStringUTFChars(env, jni_address, address);
-    if(!curState)
+    // gat le scanner object
+    jobject jni_obj_leScanner = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
+                                                         jni_mid_getBluetoothLeScanner);
+    if (!jni_obj_leScanner)
     {
-        OIC_LOG(INFO, TAG, "there is no information. auto connect flag is false");
-        ca_mutex_unlock(g_deviceStateListMutex);
-        return JNI_FALSE;
+        OIC_LOG(ERROR, TAG, "getState From BTAdapter: jni_obj_leScanner is null");
+        CACheckJNIException(env);
+        return CA_STATUS_FAILED;
     }
 
-    jboolean ret = JNI_FALSE;
-    switch(state_idx)
+    // call stopScan method
+    OIC_LOG(INFO, TAG, "CALL API - stopScan for level 21");
+    (*env)->CallVoidMethod(env, jni_obj_leScanner, jni_mid_stopScan, callback);
+    if (CACheckJNIException(env))
     {
-        case CA_LE_AUTO_CONNECT_FLAG:
-            ret = curState->autoConnectFlag;
-            break;
-        case CA_LE_DESCRIPTOR_FOUND:
-            ret = curState->isDescriptorFound;
-            break;
-        default:
-            break;
+        OIC_LOG(INFO, TAG, "stopScan for level 21 has failed");
+        (*env)->DeleteLocalRef(env, jni_obj_leScanner);
+        return CA_STATUS_FAILED;
     }
-    ca_mutex_unlock(g_deviceStateListMutex);
 
-    OIC_LOG_V(INFO, TAG, "%d flag is %d", state_idx, ret);
-    OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetFlagFromState");
-    return ret;
+    (*env)->DeleteLocalRef(env, jni_obj_leScanner);
+    return CA_STATUS_OK;
 }
 
 CAResult_t CALEClientDirectConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect)
@@ -1709,13 +2401,13 @@ CAResult_t CALEClientDirectConnect(JNIEnv *env, jobject bluetoothDevice, jboolea
     VERIFY_NON_NULL(env, TAG, "env is null");
     VERIFY_NON_NULL(bluetoothDevice, TAG, "bluetoothDevice is null");
 
-    ca_mutex_lock(g_threadSendMutex);
+    oc_mutex_lock(g_threadSendMutex);
 
     jstring jni_address = CALEGetAddressFromBTDevice(env, bluetoothDevice);
     if (!jni_address)
     {
         OIC_LOG(ERROR, TAG, "jni_address is not available");
-        ca_mutex_unlock(g_threadSendMutex);
+        oc_mutex_unlock(g_threadSendMutex);
         return CA_STATUS_FAILED;
     }
 
@@ -1723,13 +2415,16 @@ CAResult_t CALEClientDirectConnect(JNIEnv *env, jobject bluetoothDevice, jboolea
     if (!address)
     {
         OIC_LOG(ERROR, TAG, "address is not available");
-        ca_mutex_unlock(g_threadSendMutex);
+        CACheckJNIException(env);
+        oc_mutex_unlock(g_threadSendMutex);
         return CA_STATUS_FAILED;
     }
 
     CAResult_t res = CA_STATUS_OK;
-    if(CALEClientIsValidState(address, CA_LE_CONNECTION_STATE,
-                              STATE_DISCONNECTED))
+    if(CALEIsValidState(address, CA_LE_CONNECTION_STATE,
+                        STATE_DISCONNECTED,
+                        g_deviceStateList,
+                        g_deviceStateListMutex))
     {
         jobject newGatt = CALEClientConnect(env, bluetoothDevice, autoconnect);
         if (NULL == newGatt)
@@ -1738,7 +2433,7 @@ CAResult_t CALEClientDirectConnect(JNIEnv *env, jobject bluetoothDevice, jboolea
             res = CA_STATUS_FAILED;
         }
     }
-    ca_mutex_unlock(g_threadSendMutex);
+    oc_mutex_unlock(g_threadSendMutex);
 
     return res;
 }
@@ -1752,6 +2447,11 @@ jobject CALEClientConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autocon
     // reset scan interval time after checking scanned devices
     CALERestartScanWithInterval(0, 0, BLE_SCAN_DISABLE);
 
+    // since there is no callback related stop success
+    // and scanning should be stopped before connectGatt is called.
+    // it should wait a few micro seconds.
+    usleep(100000);
+
     // get gatt object from Bluetooth Device object for closeProfileProxy(..)
     jstring jni_address = CALEClientGetLEAddressFromBTDevice(env, bluetoothDevice);
     if (jni_address)
@@ -1830,38 +2530,104 @@ jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean aut
         return NULL;
     }
 
-    // get BluetoothDevice method
-    OIC_LOG(DEBUG, TAG, "get BluetoothDevice method");
-    jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
-                                                     "connectGatt",
-                                                     "(Landroid/content/Context;ZLandroid/"
-                                                     "bluetooth/BluetoothGattCallback;)"
-                                                     "Landroid/bluetooth/BluetoothGatt;");
-    if (!jni_mid_connectGatt)
+    jobject jni_obj_connectGatt = NULL;
+    jint jni_int_sdk = CALEGetBuildVersion(env);
+    OIC_LOG_V(INFO, TAG, "API level is %d", jni_int_sdk);
+    if (jni_int_sdk >= 23) // upper than API level 23
     {
-        OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
-        return NULL;
-    }
+        jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
+                                                         "connectGatt",
+                                                         "(Landroid/content/Context;ZLandroid/"
+                                                         "bluetooth/BluetoothGattCallback;I)"
+                                                         "Landroid/bluetooth/BluetoothGatt;");
+        if (!jni_mid_connectGatt)
+        {
+            OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
+            return NULL;
+        }
 
-    OIC_LOG(INFO, TAG, "CALL API - connectGatt");
-    jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
-                                                           jni_mid_connectGatt,
-                                                           NULL,
-                                                           autoconnect, g_leGattCallback);
-    if (!jni_obj_connectGatt)
-    {
-        OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
-        CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
-        CALEClientUpdateSendCnt(env);
-        return NULL;
+        jint jni_transport_le = CALEGetConstantsValue(env, CLASSPATH_BT_DEVICE, "TRANSPORT_LE");
+        OIC_LOG_V(INFO, TAG, "CALL API - connectGatt with transport LE(%d)", jni_transport_le);
+        jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
+                                                       jni_mid_connectGatt, NULL,
+                                                       autoconnect, g_leGattCallback,
+                                                       jni_transport_le);
+        if (!jni_obj_connectGatt)
+        {
+            OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
+            CACheckJNIException(env);
+            CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
+            CALEClientUpdateSendCnt(env);
+            return NULL;
+        }
+        else
+        {
+            OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
+        }
     }
-    else
+    else // lower than API level 23
     {
-        OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
+#ifdef HIDDEN_API
+        const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
+        if (!address)
+        {
+            OIC_LOG(ERROR, TAG, "GetStringUTFChars has failed");
+            return NULL;
+        }
+        OIC_LOG(INFO, TAG, "CALL API - connectGatt for hidden");
+        jni_obj_connectGatt = CALEClientHiddenConnectGatt(bluetoothDevice, address, autoconnect);
+
+#else
+
+        jmethodID jni_mid_connectGatt = CAGetJNIMethodID(env, "android/bluetooth/BluetoothDevice",
+                                                         "connectGatt",
+                                                         "(Landroid/content/Context;ZLandroid/"
+                                                         "bluetooth/BluetoothGattCallback;)"
+                                                         "Landroid/bluetooth/BluetoothGatt;");
+        if (!jni_mid_connectGatt)
+        {
+            OIC_LOG(ERROR, TAG, "bleConnect: jni_mid_connectGatt is null");
+            return NULL;
+        }
+
+        OIC_LOG(INFO, TAG, "CALL API - connectGatt");
+        jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice,
+                                                               jni_mid_connectGatt,
+                                                               NULL,
+                                                               autoconnect, g_leGattCallback);
+#endif
+        if (!jni_obj_connectGatt)
+        {
+            OIC_LOG(ERROR, TAG, "connectGatt was failed..it will be removed");
+            CACheckJNIException(env);
+            CALEClientRemoveDeviceInScanDeviceList(env, jni_address);
+            CALEClientUpdateSendCnt(env);
+            return NULL;
+        }
+        else
+        {
+            OIC_LOG(DEBUG, TAG, "le connecting..please wait..");
+        }
+
     }
+
     return jni_obj_connectGatt;
 }
 
+bool CALEClientIsConnected(const char* address)
+{
+    if (CALEIsValidState(address, CA_LE_CONNECTION_STATE,
+                         STATE_SERVICE_CONNECTED,
+                         g_deviceStateList,
+                         g_deviceStateListMutex))
+    {
+        OIC_LOG(DEBUG, TAG, "current state is connected");
+        return true;
+    }
+    OIC_LOG(DEBUG, TAG, "current state is not connected");
+    return false;
+}
+
 CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
 {
     OIC_LOG(DEBUG, TAG, "IN - CALEClientCloseProfileProxy");
@@ -1873,7 +2639,7 @@ CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
     if (!jni_cid_BTAdapter)
     {
         OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     // get remote bt adapter method
@@ -1883,7 +2649,7 @@ CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
     if (!jni_mid_getDefaultAdapter)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     // gat bt adapter object
@@ -1892,7 +2658,7 @@ CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
     if (!jni_obj_BTAdapter)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     // get closeProfileProxy method
@@ -1903,14 +2669,14 @@ CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
     if (!jni_mid_closeProfileProxy)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_closeProfileProxy is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jclass jni_cid_BTProfile = (*env)->FindClass(env, CLASSPATH_BT_PROFILE);
     if (!jni_cid_BTProfile)
     {
         OIC_LOG(ERROR, TAG, "jni_cid_BTProfile is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     // GATT - Constant value : 7 (0x00000007)
@@ -1919,23 +2685,26 @@ CAResult_t CALEClientCloseProfileProxy(JNIEnv *env, jobject gatt)
     if (!id_gatt)
     {
         OIC_LOG(ERROR, TAG, "id_gatt is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jint jni_gatt = (*env)->GetStaticIntField(env, jni_cid_BTProfile, id_gatt);
+    CACheckJNIException(env);
 
     OIC_LOG(DEBUG, TAG, "CALL API - close the connection of the profile proxy to the Service");
     (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_closeProfileProxy, jni_gatt, gatt);
-    if ((*env)->ExceptionCheck(env))
+    if (CACheckJNIException(env))
     {
         OIC_LOG(ERROR, TAG, "closeProfileProxy has failed");
-        (*env)->ExceptionDescribe(env);
-        (*env)->ExceptionClear(env);
         return CA_STATUS_FAILED;
     }
 
     OIC_LOG(DEBUG, TAG, "OUT - CALEClientCloseProfileProxy");
     return CA_STATUS_OK;
+
+error_exit:
+    CACheckJNIException(env);
+    return CA_STATUS_FAILED;
 }
 
 
@@ -1958,11 +2727,9 @@ CAResult_t CALEClientDisconnect(JNIEnv *env, jobject bluetoothGatt)
     // call disconnect gatt method
     OIC_LOG(INFO, TAG, "CALL API - disconnect");
     (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
-    if ((*env)->ExceptionCheck(env))
+    if (CACheckJNIException(env))
     {
         OIC_LOG(ERROR, TAG, "disconnect has failed");
-        (*env)->ExceptionDescribe(env);
-        (*env)->ExceptionClear(env);
         return CA_STATUS_FAILED;
     }
 
@@ -2019,6 +2786,7 @@ CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
     if (!address)
     {
         OIC_LOG(ERROR, TAG, "address is null");
+        CACheckJNIException(env);
         return CA_STATUS_FAILED;
     }
 
@@ -2044,12 +2812,13 @@ CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
         if (!setAddress)
         {
             OIC_LOG(ERROR, TAG, "setAddress is null");
+            CACheckJNIException(env);
             (*env)->ReleaseStringUTFChars(env, remote_address, address);
             return CA_STATUS_FAILED;
         }
 
         OIC_LOG_V(DEBUG, TAG, "target address : %s, set address : %s", address, setAddress);
-        if (!strcmp(address, setAddress))
+        if (!strcasecmp(address, setAddress))
         {
             CAResult_t res = CALEClientDisconnect(env, jarrayObj);
             if (CA_STATUS_OK != res)
@@ -2071,6 +2840,40 @@ CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remote_address)
     return CA_STATUS_OK;
 }
 
+CAResult_t CALEClientRequestMTU(JNIEnv *env, jobject bluetoothGatt, jint size)
+{
+    VERIFY_NON_NULL(env, TAG, "env is null");
+    VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
+
+    if (!CALEIsEnableBTAdapter(env))
+    {
+        OIC_LOG(INFO, TAG, "BT adapter is not enabled");
+        return CA_ADAPTER_NOT_ENABLED;
+    }
+
+    // get BluetoothGatt.requestMtu method
+    OIC_LOG(DEBUG, TAG, "get BluetoothGatt.requestMtu method");
+    jmethodID jni_mid_requestMtu = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
+                                                    "requestMtu", "(I)Z");
+    if (!jni_mid_requestMtu)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_requestMtu is null");
+        return CA_STATUS_FAILED;
+    }
+
+    // call requestMtu
+    OIC_LOG(INFO, TAG, "CALL API - requestMtu");
+    jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_requestMtu, size);
+    if (!ret)
+    {
+        OIC_LOG(ERROR, TAG, "requestMtu has failed");
+        CACheckJNIException(env);
+        return CA_STATUS_FAILED;
+    }
+
+    return CA_STATUS_OK;
+}
+
 CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
 {
     VERIFY_NON_NULL(env, TAG, "env is null");
@@ -2098,6 +2901,7 @@ CAResult_t CALEClientDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
     if (!ret)
     {
         OIC_LOG(ERROR, TAG, "discoverServices has not been started");
+        CACheckJNIException(env);
         return CA_STATUS_FAILED;
     }
 
@@ -2113,7 +2917,6 @@ static void CALEWriteCharacteristicThread(void* object)
     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
     if (JNI_OK != res)
     {
-        OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
 
         if (JNI_OK != res)
@@ -2154,42 +2957,71 @@ CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
     const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
     if (!address)
     {
+        CACheckJNIException(env);
         CALEClientSendFinish(env, gatt);
         return CA_STATUS_FAILED;
     }
 
-    ca_mutex_lock(g_threadSendStateMutex);
+    oc_mutex_lock(g_threadSendStateMutex);
 
-    if (CALEClientIsValidState(address, CA_LE_SEND_STATE, STATE_SENDING))
+    if (CALEIsValidState(address, CA_LE_SEND_STATE, STATE_SENDING,
+                         g_deviceStateList,
+                         g_deviceStateListMutex))
     {
         OIC_LOG(INFO, TAG, "current state is SENDING");
         (*env)->ReleaseStringUTFChars(env, jni_address, address);
-        ca_mutex_unlock(g_threadSendStateMutex);
+        oc_mutex_unlock(g_threadSendStateMutex);
         return CA_STATUS_OK;
     }
 
-    if (CA_STATUS_OK != CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
-                                                    STATE_SENDING))
+    if (CA_STATUS_OK != CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
+                                              STATE_SENDING,
+                                              g_deviceStateList,
+                                              g_deviceStateListMutex))
     {
-        OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
+        OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
         (*env)->ReleaseStringUTFChars(env, jni_address, address);
         CALEClientSendFinish(env, gatt);
-        ca_mutex_unlock(g_threadSendStateMutex);
+        oc_mutex_unlock(g_threadSendStateMutex);
         return CA_STATUS_FAILED;
     }
 
     (*env)->ReleaseStringUTFChars(env, jni_address, address);
 
-    ca_mutex_unlock(g_threadSendStateMutex);
+    oc_mutex_unlock(g_threadSendStateMutex);
+
+    jbyteArray sendData = NULL;
+    oc_mutex_lock(g_setValueMutex);
+    if (g_sendBuffer)
+    {
+        OIC_LOG(INFO, TAG, "alloc local reference for data");
+        sendData = (jbyteArray)(*env)->NewLocalRef(env, g_sendBuffer);
+    }
+    else
+    {
+        OIC_LOG(ERROR, TAG, "send Buffer is empty");
+        oc_mutex_unlock(g_setValueMutex);
+        return CA_STATUS_FAILED;
+    }
+    oc_mutex_unlock(g_setValueMutex);
 
     // send data
-    jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, g_sendBuffer);
+    jobject jni_obj_character = CALEClientCreateGattCharacteristic(env, gatt, sendData);
     if (!jni_obj_character)
     {
+        if (sendData)
+        {
+            (*env)->DeleteLocalRef(env, sendData);
+        }
         CALEClientSendFinish(env, gatt);
         return CA_STATUS_FAILED;
     }
 
+    if (sendData)
+    {
+        (*env)->DeleteLocalRef(env, sendData);
+    }
+
     CAResult_t ret = CALEClientWriteCharacteristicImpl(env, gatt, jni_obj_character);
     if (CA_STATUS_OK != ret)
     {
@@ -2199,23 +3031,23 @@ CAResult_t CALESetValueAndWriteCharacteristic(JNIEnv* env, jobject gatt)
 
     // wait for callback for write Characteristic with success to sent data
     OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
-    ca_mutex_lock(g_threadWriteCharacteristicMutex);
+    oc_mutex_lock(g_threadWriteCharacteristicMutex);
     if (!g_isSignalSetFlag)
     {
         OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
-        if (CA_WAIT_SUCCESS != ca_cond_wait_for(g_threadWriteCharacteristicCond,
+        if (OC_WAIT_SUCCESS != oc_cond_wait_for(g_threadWriteCharacteristicCond,
                                   g_threadWriteCharacteristicMutex,
                                   WAIT_TIME_WRITE_CHARACTERISTIC))
         {
             OIC_LOG(ERROR, TAG, "there is no response. write has failed");
             g_isSignalSetFlag = false;
-            ca_mutex_unlock(g_threadWriteCharacteristicMutex);
+            oc_mutex_unlock(g_threadWriteCharacteristicMutex);
             return CA_STATUS_FAILED;
         }
     }
     // reset flag set by writeCharacteristic Callback
     g_isSignalSetFlag = false;
-    ca_mutex_unlock(g_threadWriteCharacteristicMutex);
+    oc_mutex_unlock(g_threadWriteCharacteristicMutex);
 
     CALEClientUpdateSendCnt(env);
 
@@ -2230,8 +3062,9 @@ CAResult_t CALEClientWriteCharacteristic(JNIEnv *env, jobject gatt)
     VERIFY_NON_NULL(gatt, TAG, "gatt is null");
 
     jobject gattParam = (*env)->NewGlobalRef(env, gatt);
-    if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle,
-                                                CALEWriteCharacteristicThread, (void*)gattParam))
+    CACheckJNIException(env);
+    if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CALEWriteCharacteristicThread,
+                                                (void*)gattParam, NULL))
     {
         OIC_LOG(ERROR, TAG, "Failed to create read thread!");
         return CA_STATUS_FAILED;
@@ -2278,6 +3111,7 @@ CAResult_t CALEClientWriteCharacteristicImpl(JNIEnv *env, jobject bluetoothGatt,
     }
     else
     {
+        CACheckJNIException(env);
         OIC_LOG(ERROR, TAG, "writeCharacteristic has failed");
         return CA_STATUS_FAILED;
     }
@@ -2300,6 +3134,7 @@ CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
     if (!jni_uuid)
     {
         OIC_LOG(ERROR, TAG, "jni_uuid is null");
+        CACheckJNIException(env);
         return CA_STATUS_FAILED;
     }
 
@@ -2332,6 +3167,7 @@ CAResult_t CALEClientReadCharacteristic(JNIEnv *env, jobject bluetoothGatt)
     else
     {
         OIC_LOG(ERROR, TAG, "readCharacteristic has failed");
+        CACheckJNIException(env);
         return CA_STATUS_FAILED;
     }
 
@@ -2373,6 +3209,7 @@ CAResult_t CALEClientSetCharacteristicNotification(JNIEnv *env, jobject bluetoot
     else
     {
         OIC_LOG(ERROR, TAG, "setCharacteristicNotification has failed");
+        CACheckJNIException(env);
         return CA_STATUS_FAILED;
     }
 
@@ -2417,6 +3254,7 @@ jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring cha
     if (!jni_obj_gattService)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_gattService is null");
+        CACheckJNIException(env);
         return NULL;
     }
 
@@ -2437,6 +3275,7 @@ jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring cha
     if (!uuid)
     {
         OIC_LOG(ERROR, TAG, "uuid is null");
+        CACheckJNIException(env);
         return NULL;
     }
 
@@ -2448,10 +3287,16 @@ jobject CALEClientGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring cha
         return NULL;
     }
 
-    OIC_LOG(DEBUG, TAG, "request to get Characteristic");
+    OIC_LOG(DEBUG, TAG, "CALL API getCharacteristic");
     jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService,
                                                                   jni_mid_getCharacteristic,
                                                                   jni_obj_tx_uuid);
+    if (!jni_obj_GattCharacteristic)
+    {
+        OIC_LOG(ERROR, TAG, "getCharacteristic has failed");
+        CACheckJNIException(env);
+        return NULL;
+    }
 
     (*env)->ReleaseStringUTFChars(env, characterUUID, uuid);
     return jni_obj_GattCharacteristic;
@@ -2474,7 +3319,7 @@ jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, j
     if (!jni_uuid)
     {
         OIC_LOG(ERROR, TAG, "jni_uuid is null");
-        return NULL;
+        goto error_exit;
     }
 
     jobject jni_obj_GattCharacteristic = CALEClientGetGattService(env, bluetoothGatt, jni_uuid);
@@ -2489,7 +3334,7 @@ jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, j
     if (!jni_cid_BTGattCharacteristic)
     {
         OIC_LOG(ERROR, TAG, "jni_cid_BTGattCharacteristic is null");
-        return NULL;
+        goto error_exit;
     }
 
     OIC_LOG(DEBUG, TAG, "set value in Characteristic");
@@ -2498,9 +3343,10 @@ jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, j
     if (!jni_mid_setValue)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
-        return NULL;
+        goto error_exit;
     }
 
+    OIC_LOG(DEBUG, TAG, "CALL API - setValue");
     jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue,
                                              data);
     if (JNI_TRUE == ret)
@@ -2510,32 +3356,49 @@ jobject CALEClientCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, j
     else
     {
         OIC_LOG(ERROR, TAG, "the locally stored value hasn't been set");
-        return NULL;
+        goto error_exit;
     }
 
-    // set Write Type
-    jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
-                                                         "setWriteType", "(I)V");
-    if (!jni_mid_setWriteType)
+    if (!g_setHighQoS)
     {
-        OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
-        return NULL;
-    }
+        OIC_LOG(DEBUG, TAG, "setWriteType with WRITE_TYPE_NO_RESPONSE");
+        // set Write Type
+        jmethodID jni_mid_setWriteType = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic,
+                                                             "setWriteType", "(I)V");
+        if (!jni_mid_setWriteType)
+        {
+            OIC_LOG(ERROR, TAG, "jni_mid_setWriteType is null");
+            goto error_exit;
+        }
 
-    jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
-                                                            "WRITE_TYPE_NO_RESPONSE", "I");
-    if (!jni_fid_no_response)
-    {
-        OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
-        return NULL;
-    }
+        jfieldID jni_fid_no_response = (*env)->GetStaticFieldID(env, jni_cid_BTGattCharacteristic,
+                                                                "WRITE_TYPE_NO_RESPONSE", "I");
+        if (!jni_fid_no_response)
+        {
+            OIC_LOG(ERROR, TAG, "jni_fid_no_response is not available");
+            goto error_exit;
+        }
 
-    jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
-                                                 jni_fid_no_response);
+        jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTGattCharacteristic,
+                                                     jni_fid_no_response);
+        CACheckJNIException(env);
 
-    (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
+        (*env)->CallVoidMethod(env, jni_obj_GattCharacteristic, jni_mid_setWriteType, jni_int_val);
+        if (CACheckJNIException(env))
+        {
+            OIC_LOG(ERROR, TAG, "setWriteType has failed");
+        }
+    }
+    else
+    {
+        OIC_LOG(DEBUG, TAG, "It will run with response property");
+    }
 
     return jni_obj_GattCharacteristic;
+
+error_exit:
+    CACheckJNIException(env);
+    return NULL;
 }
 
 jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
@@ -2560,6 +3423,7 @@ jbyteArray CALEClientGetValueFromCharacteristic(JNIEnv *env, jobject characteris
 
     jbyteArray jni_obj_data_array = (*env)->CallObjectMethod(env, characteristic,
                                                              jni_mid_getValue);
+    CACheckJNIException(env);
     return jni_obj_data_array;
 }
 
@@ -2576,7 +3440,6 @@ CAResult_t CALEClientCreateUUIDList()
     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
     if (JNI_OK != res)
     {
-        OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
 
         if (JNI_OK != res)
@@ -2592,6 +3455,7 @@ CAResult_t CALEClientCreateUUIDList()
     if (!jni_cid_uuid_list)
     {
         OIC_LOG(ERROR, TAG, "jni_cid_uuid_list is null");
+        CACheckJNIException(env);
         goto error_exit;
     }
 
@@ -2600,6 +3464,7 @@ CAResult_t CALEClientCreateUUIDList()
     if (!jni_obj_uuid_list)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_uuid_list is null");
+        CACheckJNIException(env);
         goto error_exit;
     }
 
@@ -2613,6 +3478,7 @@ CAResult_t CALEClientCreateUUIDList()
     (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
 
     g_uuidList = (jobjectArray)(*env)->NewGlobalRef(env, jni_obj_uuid_list);
+    CACheckJNIException(env);
 
     if (isAttached)
     {
@@ -2660,7 +3526,6 @@ CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
     if (!jni_obj_cc_uuid)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_cc_uuid is null");
-        return CA_STATUS_FAILED;
     }
 
     OIC_LOG(DEBUG, TAG, "request to get descriptor");
@@ -2669,7 +3534,7 @@ CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
     if (!jni_obj_descriptor)
     {
         OIC_LOG(INFO, TAG, "jni_obj_descriptor is null");
-        return CA_NOT_SUPPORTED;
+        goto error_exit;
     }
 
     OIC_LOG(DEBUG, TAG, "set value in descriptor");
@@ -2678,25 +3543,39 @@ CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
     if (!jni_cid_descriptor)
     {
         OIC_LOG(ERROR, TAG, "jni_cid_descriptor is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_descriptor, "setValue", "([B)Z");
     if (!jni_mid_setValue)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_setValue is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
-    jfieldID jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
-                                                          "ENABLE_NOTIFICATION_VALUE", "[B");
-    if (!jni_fid_NotiValue)
+    jfieldID jni_fid_NotiValue = NULL;
+    if (g_setHighQoS)
     {
-        OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
-        return CA_STATUS_FAILED;
+        OIC_LOG(DEBUG, TAG, "get ENABLE_INDICATION_VALUE");
+        jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
+                                                     "ENABLE_INDICATION_VALUE", "[B");
+        if (!jni_fid_NotiValue)
+        {
+            OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
+            goto error_exit;
+        }
+    }
+    else
+    {
+        OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
+        jni_fid_NotiValue = (*env)->GetStaticFieldID(env, jni_cid_descriptor,
+                                                     "ENABLE_NOTIFICATION_VALUE", "[B");
+        if (!jni_fid_NotiValue)
+        {
+            OIC_LOG(ERROR, TAG, "jni_fid_NotiValue is null");
+            goto error_exit;
+        }
     }
-
-    OIC_LOG(DEBUG, TAG, "get ENABLE_NOTIFICATION_VALUE");
 
     jboolean jni_setvalue = (*env)->CallBooleanMethod(
             env, jni_obj_descriptor, jni_mid_setValue,
@@ -2708,7 +3587,7 @@ CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
     else
     {
         OIC_LOG(ERROR, TAG, "setValue has failed");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jmethodID jni_mid_writeDescriptor  = CAGetJNIMethodID(env, "android/bluetooth/BluetoothGatt",
@@ -2731,10 +3610,14 @@ CAResult_t CALEClientSetUUIDToDescriptor(JNIEnv *env, jobject bluetoothGatt,
     else
     {
         OIC_LOG(ERROR, TAG, "writeDescriptor has failed");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     return CA_STATUS_OK;
+
+error_exit:
+    CACheckJNIException(env);
+    return CA_STATUS_FAILED;
 }
 
 void CALEClientCreateScanDeviceList(JNIEnv *env)
@@ -2742,7 +3625,7 @@ void CALEClientCreateScanDeviceList(JNIEnv *env)
     OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
 
-    ca_mutex_lock(g_deviceListMutex);
+    oc_mutex_lock(g_deviceListMutex);
     // create new object array
     if (g_deviceList == NULL)
     {
@@ -2750,7 +3633,7 @@ void CALEClientCreateScanDeviceList(JNIEnv *env)
 
         g_deviceList = u_arraylist_create();
     }
-    ca_mutex_unlock(g_deviceListMutex);
+    oc_mutex_unlock(g_deviceListMutex);
 }
 
 CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
@@ -2758,12 +3641,12 @@ CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
     VERIFY_NON_NULL(device, TAG, "device is null");
     VERIFY_NON_NULL(env, TAG, "env is null");
 
-    ca_mutex_lock(g_deviceListMutex);
+    oc_mutex_lock(g_deviceListMutex);
 
     if (!g_deviceList)
     {
         OIC_LOG(ERROR, TAG, "gdevice_list is null");
-        ca_mutex_unlock(g_deviceListMutex);
+        oc_mutex_unlock(g_deviceListMutex);
         return CA_STATUS_FAILED;
     }
 
@@ -2771,7 +3654,7 @@ CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
     if (!jni_remoteAddress)
     {
         OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
-        ca_mutex_unlock(g_deviceListMutex);
+        oc_mutex_unlock(g_deviceListMutex);
         return CA_STATUS_FAILED;
     }
 
@@ -2779,22 +3662,24 @@ CAResult_t CALEClientAddScanDeviceToList(JNIEnv *env, jobject device)
     if (!remoteAddress)
     {
         OIC_LOG(ERROR, TAG, "remoteAddress is null");
+        CACheckJNIException(env);
         (*env)->DeleteLocalRef(env, jni_remoteAddress);
-        ca_mutex_unlock(g_deviceListMutex);
+        oc_mutex_unlock(g_deviceListMutex);
         return CA_STATUS_FAILED;
     }
 
     if (!CALEClientIsDeviceInScanDeviceList(env, remoteAddress))
     {
         jobject gdevice = (*env)->NewGlobalRef(env, device);
+        CACheckJNIException(env);
         u_arraylist_add(g_deviceList, gdevice);
-        ca_cond_signal(g_deviceDescCond);
+        oc_cond_signal(g_deviceDescCond);
         OIC_LOG_V(DEBUG, TAG, "Added a new BT Device in deviceList [%s]", remoteAddress);
     }
     (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
     (*env)->DeleteLocalRef(env, jni_remoteAddress);
 
-    ca_mutex_unlock(g_deviceListMutex);
+    oc_mutex_unlock(g_deviceListMutex);
 
     return CA_STATUS_OK;
 }
@@ -2831,11 +3716,12 @@ bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
         if (!setAddress)
         {
             OIC_LOG(ERROR, TAG, "setAddress is null");
+            CACheckJNIException(env);
             (*env)->DeleteLocalRef(env, jni_setAddress);
             return true;
         }
 
-        if (!strcmp(remoteAddress, setAddress))
+        if (!strcasecmp(remoteAddress, setAddress))
         {
             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
             (*env)->DeleteLocalRef(env, jni_setAddress);
@@ -2845,9 +3731,6 @@ bool CALEClientIsDeviceInScanDeviceList(JNIEnv *env, const char* remoteAddress)
         (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
         (*env)->DeleteLocalRef(env, jni_setAddress);
     }
-
-    OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in scanned device list", remoteAddress);
-
     return false;
 }
 
@@ -2856,12 +3739,12 @@ CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
     OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
     VERIFY_NON_NULL(env, TAG, "env is null");
 
-    ca_mutex_lock(g_deviceListMutex);
+    oc_mutex_lock(g_deviceListMutex);
 
     if (!g_deviceList)
     {
         OIC_LOG(ERROR, TAG, "g_deviceList is null");
-        ca_mutex_unlock(g_deviceListMutex);
+        oc_mutex_unlock(g_deviceListMutex);
         return CA_STATUS_FAILED;
     }
 
@@ -2881,7 +3764,7 @@ CAResult_t CALEClientRemoveAllScanDevices(JNIEnv *env)
     OICFree(g_deviceList);
     g_deviceList = NULL;
 
-    ca_mutex_unlock(g_deviceListMutex);
+    oc_mutex_unlock(g_deviceListMutex);
     return CA_STATUS_OK;
 }
 
@@ -2891,12 +3774,12 @@ CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
     VERIFY_NON_NULL(address, TAG, "address is null");
     VERIFY_NON_NULL(env, TAG, "env is null");
 
-    ca_mutex_lock(g_deviceListMutex);
+    oc_mutex_lock(g_deviceListMutex);
 
     if (!g_deviceList)
     {
         OIC_LOG(ERROR, TAG, "g_deviceList is null");
-        ca_mutex_unlock(g_deviceListMutex);
+        oc_mutex_unlock(g_deviceListMutex);
         return CA_STATUS_FAILED;
     }
 
@@ -2907,7 +3790,7 @@ CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
         if (!jarrayObj)
         {
             OIC_LOG(ERROR, TAG, "jarrayObj is null");
-            ca_mutex_unlock(g_deviceListMutex);
+            oc_mutex_unlock(g_deviceListMutex);
             return CA_STATUS_FAILED;
         }
 
@@ -2915,7 +3798,7 @@ CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
         if (!jni_setAddress)
         {
             OIC_LOG(ERROR, TAG, "jni_setAddress is null");
-            ca_mutex_unlock(g_deviceListMutex);
+            oc_mutex_unlock(g_deviceListMutex);
             return CA_STATUS_FAILED;
         }
 
@@ -2923,7 +3806,8 @@ CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
         if (!setAddress)
         {
             OIC_LOG(ERROR, TAG, "setAddress is null");
-            ca_mutex_unlock(g_deviceListMutex);
+            CACheckJNIException(env);
+            oc_mutex_unlock(g_deviceListMutex);
             return CA_STATUS_FAILED;
         }
 
@@ -2931,12 +3815,13 @@ CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
         if (!remoteAddress)
         {
             OIC_LOG(ERROR, TAG, "remoteAddress is null");
+            CACheckJNIException(env);
             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
-            ca_mutex_unlock(g_deviceListMutex);
+            oc_mutex_unlock(g_deviceListMutex);
             return CA_STATUS_FAILED;
         }
 
-        if (!strcmp(setAddress, remoteAddress))
+        if (!strcasecmp(setAddress, remoteAddress))
         {
             OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
             (*env)->DeleteGlobalRef(env, jarrayObj);
@@ -2947,17 +3832,17 @@ CAResult_t CALEClientRemoveDeviceInScanDeviceList(JNIEnv *env, jstring address)
             if (NULL == u_arraylist_remove(g_deviceList, index))
             {
                 OIC_LOG(ERROR, TAG, "List removal failed.");
-                ca_mutex_unlock(g_deviceListMutex);
+                oc_mutex_unlock(g_deviceListMutex);
                 return CA_STATUS_FAILED;
             }
-            ca_mutex_unlock(g_deviceListMutex);
+            oc_mutex_unlock(g_deviceListMutex);
             return CA_STATUS_OK;
         }
         (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
         (*env)->ReleaseStringUTFChars(env, address, remoteAddress);
     }
 
-    ca_mutex_unlock(g_deviceListMutex);
+    oc_mutex_unlock(g_deviceListMutex);
     OIC_LOG(DEBUG, TAG, "There are no object in the device list");
 
     return CA_STATUS_OK;
@@ -2973,12 +3858,12 @@ CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
     VERIFY_NON_NULL(env, TAG, "env is null");
     VERIFY_NON_NULL(gatt, TAG, "gatt is null");
 
-    ca_mutex_lock(g_gattObjectMutex);
+    oc_mutex_lock(g_gattObjectMutex);
 
     if (!g_gattObjectList)
     {
         OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
-        ca_mutex_unlock(g_gattObjectMutex);
+        oc_mutex_unlock(g_gattObjectMutex);
         return CA_STATUS_FAILED;
     }
 
@@ -2986,7 +3871,7 @@ CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
     if (!jni_remoteAddress)
     {
         OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
-        ca_mutex_unlock(g_gattObjectMutex);
+        oc_mutex_unlock(g_gattObjectMutex);
         return CA_STATUS_FAILED;
     }
 
@@ -2994,7 +3879,9 @@ CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
     if (!remoteAddress)
     {
         OIC_LOG(ERROR, TAG, "remoteAddress is null");
-        ca_mutex_unlock(g_gattObjectMutex);
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_remoteAddress);
+        oc_mutex_unlock(g_gattObjectMutex);
         return CA_STATUS_FAILED;
     }
 
@@ -3007,20 +3894,19 @@ CAResult_t CALEClientAddGattobjToList(JNIEnv *env, jobject gatt)
     }
 
     (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
-    ca_mutex_unlock(g_gattObjectMutex);
+    (*env)->DeleteLocalRef(env, jni_remoteAddress);
+    oc_mutex_unlock(g_gattObjectMutex);
     return CA_STATUS_OK;
 }
 
 bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
 {
-    OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
     VERIFY_NON_NULL(env, TAG, "env is null");
     VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
 
     uint32_t length = u_arraylist_length(g_gattObjectList);
     for (uint32_t index = 0; index < length; index++)
     {
-
         jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
         if (!jarrayObj)
         {
@@ -3039,20 +3925,20 @@ bool CALEClientIsGattObjInList(JNIEnv *env, const char* remoteAddress)
         if (!setAddress)
         {
             OIC_LOG(ERROR, TAG, "setAddress is null");
+            CACheckJNIException(env);
+            (*env)->DeleteLocalRef(env, jni_setAddress);
             return true;
         }
 
-        if (!strcmp(remoteAddress, setAddress))
+        if (!strcasecmp(remoteAddress, setAddress))
         {
             OIC_LOG(DEBUG, TAG, "the device is already set");
             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+            (*env)->DeleteLocalRef(env, jni_setAddress);
             return true;
         }
-        else
-        {
-            (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
-            continue;
-        }
+        (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+        (*env)->DeleteLocalRef(env, jni_setAddress);
     }
 
     OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
@@ -3065,7 +3951,7 @@ jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
     VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
 
-    ca_mutex_lock(g_gattObjectMutex);
+    oc_mutex_lock(g_gattObjectMutex);
     uint32_t length = u_arraylist_length(g_gattObjectList);
     for (uint32_t index = 0; index < length; index++)
     {
@@ -3073,7 +3959,7 @@ jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
         if (!jarrayObj)
         {
             OIC_LOG(ERROR, TAG, "jarrayObj is null");
-            ca_mutex_unlock(g_gattObjectMutex);
+            oc_mutex_unlock(g_gattObjectMutex);
             return NULL;
         }
 
@@ -3081,7 +3967,7 @@ jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
         if (!jni_setAddress)
         {
             OIC_LOG(ERROR, TAG, "jni_setAddress is null");
-            ca_mutex_unlock(g_gattObjectMutex);
+            oc_mutex_unlock(g_gattObjectMutex);
             return NULL;
         }
 
@@ -3089,21 +3975,24 @@ jobject CALEClientGetGattObjInList(JNIEnv *env, const char* remoteAddress)
         if (!setAddress)
         {
             OIC_LOG(ERROR, TAG, "setAddress is null");
-            ca_mutex_unlock(g_gattObjectMutex);
+            CACheckJNIException(env);
+            (*env)->DeleteLocalRef(env, jni_setAddress);
+            oc_mutex_unlock(g_gattObjectMutex);
             return NULL;
         }
 
-        if (!strcmp(remoteAddress, setAddress))
+        if (!strcasecmp(remoteAddress, setAddress))
         {
             OIC_LOG(DEBUG, TAG, "the device is already set");
             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
-            ca_mutex_unlock(g_gattObjectMutex);
+            oc_mutex_unlock(g_gattObjectMutex);
             return jarrayObj;
         }
         (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+        (*env)->DeleteLocalRef(env, jni_setAddress);
     }
 
-    ca_mutex_unlock(g_gattObjectMutex);
+    oc_mutex_unlock(g_gattObjectMutex);
     OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
     return NULL;
 }
@@ -3113,11 +4002,11 @@ CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
     OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
     VERIFY_NON_NULL(env, TAG, "env is null");
 
-    ca_mutex_lock(g_gattObjectMutex);
+    oc_mutex_lock(g_gattObjectMutex);
     if (!g_gattObjectList)
     {
         OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
-        ca_mutex_unlock(g_gattObjectMutex);
+        oc_mutex_unlock(g_gattObjectMutex);
         return CA_STATUS_OK;
     }
 
@@ -3137,7 +4026,7 @@ CAResult_t CALEClientRemoveAllGattObjs(JNIEnv *env)
     OICFree(g_gattObjectList);
     g_gattObjectList = NULL;
     OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
-    ca_mutex_unlock(g_gattObjectMutex);
+    oc_mutex_unlock(g_gattObjectMutex);
     return CA_STATUS_OK;
 }
 
@@ -3147,11 +4036,11 @@ CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
     VERIFY_NON_NULL(gatt, TAG, "gatt is null");
     VERIFY_NON_NULL(env, TAG, "env is null");
 
-    ca_mutex_lock(g_gattObjectMutex);
+    oc_mutex_lock(g_gattObjectMutex);
     if (!g_gattObjectList)
     {
         OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
-        ca_mutex_unlock(g_gattObjectMutex);
+        oc_mutex_unlock(g_gattObjectMutex);
         return CA_STATUS_OK;
     }
 
@@ -3162,7 +4051,7 @@ CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
         if (!jarrayObj)
         {
             OIC_LOG(ERROR, TAG, "jarrayObj is null");
-            ca_mutex_unlock(g_gattObjectMutex);
+            oc_mutex_unlock(g_gattObjectMutex);
             return CA_STATUS_FAILED;
         }
 
@@ -3170,7 +4059,7 @@ CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
         if (!jni_setAddress)
         {
             OIC_LOG(ERROR, TAG, "jni_setAddress is null");
-            ca_mutex_unlock(g_gattObjectMutex);
+            oc_mutex_unlock(g_gattObjectMutex);
             return CA_STATUS_FAILED;
         }
 
@@ -3178,7 +4067,8 @@ CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
         if (!setAddress)
         {
             OIC_LOG(ERROR, TAG, "setAddress is null");
-            ca_mutex_unlock(g_gattObjectMutex);
+            CACheckJNIException(env);
+            oc_mutex_unlock(g_gattObjectMutex);
             return CA_STATUS_FAILED;
         }
 
@@ -3187,7 +4077,7 @@ CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
         {
             OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
-            ca_mutex_unlock(g_gattObjectMutex);
+            oc_mutex_unlock(g_gattObjectMutex);
             return CA_STATUS_FAILED;
         }
 
@@ -3195,12 +4085,13 @@ CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
         if (!remoteAddress)
         {
             OIC_LOG(ERROR, TAG, "remoteAddress is null");
+            CACheckJNIException(env);
             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
-            ca_mutex_unlock(g_gattObjectMutex);
+            oc_mutex_unlock(g_gattObjectMutex);
             return CA_STATUS_FAILED;
         }
 
-        if (!strcmp(setAddress, remoteAddress))
+        if (!strcasecmp(setAddress, remoteAddress))
         {
             OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
             (*env)->DeleteGlobalRef(env, jarrayObj);
@@ -3211,17 +4102,17 @@ CAResult_t CALEClientRemoveGattObj(JNIEnv *env, jobject gatt)
             if (NULL == u_arraylist_remove(g_gattObjectList, index))
             {
                 OIC_LOG(ERROR, TAG, "List removal failed.");
-                ca_mutex_unlock(g_gattObjectMutex);
+                oc_mutex_unlock(g_gattObjectMutex);
                 return CA_STATUS_FAILED;
             }
-            ca_mutex_unlock(g_gattObjectMutex);
+            oc_mutex_unlock(g_gattObjectMutex);
             return CA_STATUS_OK;
         }
         (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
         (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
     }
 
-    ca_mutex_unlock(g_gattObjectMutex);
+    oc_mutex_unlock(g_gattObjectMutex);
     OIC_LOG(DEBUG, TAG, "there are no target object");
     return CA_STATUS_OK;
 }
@@ -3232,11 +4123,11 @@ CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
     VERIFY_NON_NULL(addr, TAG, "addr is null");
     VERIFY_NON_NULL(env, TAG, "env is null");
 
-    ca_mutex_lock(g_gattObjectMutex);
+    oc_mutex_lock(g_gattObjectMutex);
     if (!g_gattObjectList)
     {
         OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
-        ca_mutex_unlock(g_gattObjectMutex);
+        oc_mutex_unlock(g_gattObjectMutex);
         return CA_STATUS_OK;
     }
 
@@ -3247,7 +4138,7 @@ CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
         if (!jarrayObj)
         {
             OIC_LOG(ERROR, TAG, "jarrayObj is null");
-            ca_mutex_unlock(g_gattObjectMutex);
+            oc_mutex_unlock(g_gattObjectMutex);
             return CA_STATUS_FAILED;
         }
 
@@ -3255,7 +4146,7 @@ CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
         if (!jni_setAddress)
         {
             OIC_LOG(ERROR, TAG, "jni_setAddress is null");
-            ca_mutex_unlock(g_gattObjectMutex);
+            oc_mutex_unlock(g_gattObjectMutex);
             return CA_STATUS_FAILED;
         }
 
@@ -3263,460 +4154,219 @@ CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr)
         if (!setAddress)
         {
             OIC_LOG(ERROR, TAG, "setAddress is null");
-            ca_mutex_unlock(g_gattObjectMutex);
+            CACheckJNIException(env);
+            oc_mutex_unlock(g_gattObjectMutex);
             return CA_STATUS_FAILED;
         }
 
         const char* remoteAddress = (*env)->GetStringUTFChars(env, addr, NULL);
         if (!remoteAddress)
         {
-            OIC_LOG(ERROR, TAG, "remoteAddress is null");
-            (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
-            ca_mutex_unlock(g_gattObjectMutex);
-            return CA_STATUS_FAILED;
-        }
-
-        if (!strcmp(setAddress, remoteAddress))
-        {
-            OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
-            (*env)->DeleteGlobalRef(env, jarrayObj);
-            jarrayObj = NULL;
-            (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
-            (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
-            if (NULL == u_arraylist_remove(g_gattObjectList, index))
-            {
-                OIC_LOG(ERROR, TAG, "List removal failed.");
-                ca_mutex_unlock(g_gattObjectMutex);
-                return CA_STATUS_FAILED;
-            }
-            ca_mutex_unlock(g_gattObjectMutex);
-            return CA_STATUS_OK;
-        }
-        (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
-        (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
-    }
-
-    ca_mutex_unlock(g_gattObjectMutex);
-    OIC_LOG(DEBUG, TAG, "there are no target object");
-    return CA_STATUS_FAILED;
-}
-
-jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
-{
-    OIC_LOG(DEBUG, TAG, "CALEClientGetLEAddressFromBTDevice");
-
-    VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
-    VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
-
-    // get Bluetooth Address
-    jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
-    if (!jni_btTargetAddress)
-    {
-        OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
-        return NULL;
-    }
-
-    const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
-    if (!targetAddress)
-    {
-        OIC_LOG(ERROR, TAG, "targetAddress is not available");
-        return NULL;
-    }
-
-    // get method ID of getDevice()
-    jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
-                                                   "getDevice", METHODID_BT_DEVICE);
-    if (!jni_mid_getDevice)
-    {
-        OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
-        (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
-        return NULL;
-    }
-
-    ca_mutex_lock(g_gattObjectMutex);
-
-    size_t length = u_arraylist_length(g_gattObjectList);
-    OIC_LOG_V(DEBUG, TAG, "length of gattObjectList : %d", length);
-    OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
-
-    for (size_t index = 0; index < length; index++)
-    {
-        jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
-        if (!jarrayObj)
-        {
-            ca_mutex_unlock(g_gattObjectMutex);
-            OIC_LOG(ERROR, TAG, "jarrayObj is null");
-            (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
-            return NULL;
-        }
-
-        jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
-        if (!jni_obj_device)
-        {
-            ca_mutex_unlock(g_gattObjectMutex);
-            OIC_LOG(ERROR, TAG, "jni_obj_device is null");
-            (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
-            return NULL;
-        }
-
-        jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
-        if (!jni_btAddress)
-        {
-            ca_mutex_unlock(g_gattObjectMutex);
-            OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
-            (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
-            return NULL;
-        }
-
-        const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
-        if (!btAddress)
-        {
-            ca_mutex_unlock(g_gattObjectMutex);
-            OIC_LOG(ERROR, TAG, "btAddress is not available");
-            (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
-            return NULL;
-        }
-
-        OIC_LOG_V(DEBUG, TAG, "btAddress : %s (idx: %d)", btAddress, index);
-        if (!strcmp(targetAddress, btAddress))
-        {
-            OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
-
-            // get LE address
-            jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
-            if (!jni_LEAddress)
-            {
-                OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
-            }
-            ca_mutex_unlock(g_gattObjectMutex);
-            (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
-            (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
-            (*env)->DeleteLocalRef(env, jni_btAddress);
-            (*env)->DeleteLocalRef(env, jni_obj_device);
-            return jni_LEAddress;
-        }
-        (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
-        (*env)->DeleteLocalRef(env, jni_btAddress);
-        (*env)->DeleteLocalRef(env, jni_obj_device);
-    }
-    ca_mutex_unlock(g_gattObjectMutex);
-
-    (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
-    OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in gattObjectList", targetAddress);
-    return NULL;
-}
-
-/**
- * BT State List
- */
-
-CAResult_t CALEClientUpdateDeviceState(const char* address, uint16_t state_type,
-                                       uint16_t target_state)
-{
-    VERIFY_NON_NULL(address, TAG, "address is null");
-    VERIFY_NON_NULL(address, TAG, "state_type is null");
-    VERIFY_NON_NULL(address, TAG, "target_state is null");
-
-    if (!g_deviceStateList)
-    {
-        OIC_LOG(ERROR, TAG, "gdevice_list is null");
-        return CA_STATUS_FAILED;
-    }
-
-    ca_mutex_lock(g_deviceStateListMutex);
-
-    if (CALEClientIsDeviceInList(address))
-    {
-        CALEState_t* curState = CALEClientGetStateInfo(address);
-        if(!curState)
-        {
-            OIC_LOG(ERROR, TAG, "curState is null");
-            ca_mutex_unlock(g_deviceStateListMutex);
-            return CA_STATUS_FAILED;
-        }
-
-        switch(state_type)
-        {
-            case CA_LE_CONNECTION_STATE:
-                curState->connectedState = target_state;
-                break;
-            case CA_LE_SEND_STATE:
-                curState->sendState = target_state;
-                break;
-            default:
-                break;
-        }
-        OIC_LOG_V(INFO, TAG, "update state - addr : %s, conn : %d, send : %d, ACFlag : %d",
-                  curState->address, curState->connectedState, curState->sendState,
-                  curState->autoConnectFlag);
-    }
-    else /** state is added newly **/
-    {
-        if (strlen(address) > CA_MACADDR_SIZE)
-        {
-            OIC_LOG(ERROR, TAG, "address is not proper");
-            ca_mutex_unlock(g_deviceStateListMutex);
-            return CA_STATUS_INVALID_PARAM;
-        }
-
-        CALEState_t *newstate = (CALEState_t*) OICCalloc(1, sizeof(*newstate));
-        if (!newstate)
-        {
-            OIC_LOG(ERROR, TAG, "out of memory");
-            ca_mutex_unlock(g_deviceStateListMutex);
-            return CA_MEMORY_ALLOC_FAILED;
-        }
-
-        OICStrcpy(newstate->address, sizeof(newstate->address), address);
-
-        switch(state_type)
-        {
-            case CA_LE_CONNECTION_STATE:
-                newstate->connectedState = target_state;
-                newstate->sendState = STATE_SEND_NONE;
-                break;
-            case CA_LE_SEND_STATE:
-                newstate->connectedState = STATE_DISCONNECTED;
-                newstate->sendState = target_state;
-                break;
-            default:
-                break;
-        }
-        OIC_LOG_V(INFO, TAG, "add a new state to List - addr : %s, "
-                  "conn : %d, send : %d, ACFlag : %d",
-                  newstate->address, newstate->connectedState, newstate->sendState,
-                  newstate->autoConnectFlag);
-        u_arraylist_add(g_deviceStateList, newstate); // update new state
-    }
-    ca_mutex_unlock(g_deviceStateListMutex);
-
-    return CA_STATUS_OK;
-}
-
-bool CALEClientIsDeviceInList(const char* remoteAddress)
-{
-    VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
-
-    if (!g_deviceStateList)
-    {
-        OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
-        return false;
-    }
-
-    uint32_t length = u_arraylist_length(g_deviceStateList);
-    for (uint32_t index = 0; index < length; index++)
-    {
-        CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
-        if (!state)
-        {
-            OIC_LOG(ERROR, TAG, "CALEState_t object is null");
-            return false;
-        }
-
-        if (!strcmp(remoteAddress, state->address))
-        {
-            OIC_LOG(DEBUG, TAG, "the device is already set");
-            return true;
-        }
-        else
-        {
-            continue;
-        }
-    }
-
-    OIC_LOG(DEBUG, TAG, "there are no the device in list.");
-    return false;
-}
-
-CAResult_t CALEClientRemoveAllDeviceState()
-{
-    OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllDeviceState");
-
-    ca_mutex_lock(g_deviceStateListMutex);
-    if (!g_deviceStateList)
-    {
-        OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
-        ca_mutex_unlock(g_deviceStateListMutex);
-        return CA_STATUS_FAILED;
-    }
-
-    uint32_t length = u_arraylist_length(g_deviceStateList);
-    for (uint32_t index = 0; index < length; index++)
-    {
-        CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
-        if (!state)
-        {
-            OIC_LOG(ERROR, TAG, "jarrayObj is null");
-            continue;
-        }
-        OICFree(state);
-    }
-
-    OICFree(g_deviceStateList);
-    g_deviceStateList = NULL;
-    ca_mutex_unlock(g_deviceStateListMutex);
-
-    return CA_STATUS_OK;
-}
-
-CAResult_t CALEClientResetDeviceStateForAll()
-{
-    OIC_LOG(DEBUG, TAG, "CALEClientResetDeviceStateForAll");
-
-    ca_mutex_lock(g_deviceStateListMutex);
-    if (!g_deviceStateList)
-    {
-        OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
-        ca_mutex_unlock(g_deviceStateListMutex);
-        return CA_STATUS_FAILED;
-    }
-
-    size_t length = u_arraylist_length(g_deviceStateList);
-    for (size_t index = 0; index < length; index++)
-    {
-        CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
-        if (!state)
-        {
-            OIC_LOG(ERROR, TAG, "jarrayObj is null");
-            continue;
-        }
-
-        // autoConnectFlag value will be not changed,
-        // since it has reset only termination case.
-        state->connectedState = STATE_DISCONNECTED;
-        state->sendState = STATE_SEND_NONE;
-    }
-    ca_mutex_unlock(g_deviceStateListMutex);
-
-    return CA_STATUS_OK;
-}
-
-CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
-{
-    OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
-    VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
-
-    if (!g_deviceStateList)
-    {
-        OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
-        return CA_STATUS_FAILED;
-    }
-
-    uint32_t length = u_arraylist_length(g_deviceStateList);
-    for (uint32_t index = 0; index < length; index++)
-    {
-        CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
-        if (!state)
-        {
-            OIC_LOG(ERROR, TAG, "CALEState_t object is null");
-            continue;
+            OIC_LOG(ERROR, TAG, "remoteAddress is null");
+            (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+            oc_mutex_unlock(g_gattObjectMutex);
+            return CA_STATUS_FAILED;
         }
 
-        if (!strcmp(state->address, remoteAddress))
+        if (!strcasecmp(setAddress, remoteAddress))
         {
-            OIC_LOG_V(DEBUG, TAG, "remove state : %s", state->address);
-
-            CALEState_t* targetState  = (CALEState_t*)u_arraylist_remove(g_deviceStateList,
-                                                                         index);
-            if (NULL == targetState)
+            OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddress);
+            (*env)->DeleteGlobalRef(env, jarrayObj);
+            jarrayObj = NULL;
+            (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+            (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
+            if (NULL == u_arraylist_remove(g_gattObjectList, index))
             {
                 OIC_LOG(ERROR, TAG, "List removal failed.");
+                oc_mutex_unlock(g_gattObjectMutex);
                 return CA_STATUS_FAILED;
             }
-
-            OICFree(targetState);
+            oc_mutex_unlock(g_gattObjectMutex);
             return CA_STATUS_OK;
         }
+        (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
+        (*env)->ReleaseStringUTFChars(env, addr, remoteAddress);
     }
 
-    return CA_STATUS_OK;
+    oc_mutex_unlock(g_gattObjectMutex);
+    OIC_LOG(DEBUG, TAG, "there are no target object");
+    return CA_STATUS_FAILED;
 }
 
-CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
+jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
 {
-    VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
+    VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
+    VERIFY_NON_NULL_RET(bluetoothDevice, TAG, "bluetoothDevice", NULL);
 
-    if (!g_deviceStateList)
+    // get Bluetooth Address
+    jstring jni_btTargetAddress = CALEGetAddressFromBTDevice(env, bluetoothDevice);
+    if (!jni_btTargetAddress)
+    {
+        OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
+        return NULL;
+    }
+
+    const char* targetAddress = (*env)->GetStringUTFChars(env, jni_btTargetAddress, NULL);
+    if (!targetAddress)
     {
-        OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
+        OIC_LOG(ERROR, TAG, "targetAddress is not available");
+        CACheckJNIException(env);
+        return NULL;
+    }
+
+    // get method ID of getDevice()
+    jmethodID jni_mid_getDevice = CAGetJNIMethodID(env, CLASSPATH_BT_GATT,
+                                                   "getDevice", METHODID_BT_DEVICE);
+    if (!jni_mid_getDevice)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_getDevice is null");
+        (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
         return NULL;
     }
 
-    uint32_t length = u_arraylist_length(g_deviceStateList);
-    OIC_LOG_V(DEBUG, TAG, "length of deviceStateList : %d", length);
-    OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress);
+    oc_mutex_lock(g_gattObjectMutex);
 
-    for (uint32_t index = 0; index < length; index++)
+    size_t length = u_arraylist_length(g_gattObjectList);
+    OIC_LOG_V(DEBUG, TAG, "length of gattObjectList : %d", length);
+    OIC_LOG_V(DEBUG, TAG, "targetAddress : %s", targetAddress);
+
+    for (size_t index = 0; index < length; index++)
     {
-        CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
-        if (!state)
+        jobject jarrayObj = (jobject) u_arraylist_get(g_gattObjectList, index);
+        if (!jarrayObj)
         {
-            OIC_LOG(ERROR, TAG, "CALEState_t object is null");
-            continue;
+            oc_mutex_unlock(g_gattObjectMutex);
+            OIC_LOG(ERROR, TAG, "jarrayObj is null");
+            (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
+            return NULL;
+        }
+
+        jobject jni_obj_device = (*env)->CallObjectMethod(env, jarrayObj, jni_mid_getDevice);
+        if (!jni_obj_device)
+        {
+            CACheckJNIException(env);
+            oc_mutex_unlock(g_gattObjectMutex);
+            OIC_LOG(ERROR, TAG, "jni_obj_device is null");
+            (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
+            return NULL;
+        }
+
+        jstring jni_btAddress = CALEGetAddressFromBTDevice(env, jni_obj_device);
+        if (!jni_btAddress)
+        {
+            oc_mutex_unlock(g_gattObjectMutex);
+            OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
+            (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
+            (*env)->DeleteLocalRef(env, jni_obj_device);
+            return NULL;
         }
 
-        OIC_LOG_V(DEBUG, TAG, "state address : %s (idx: %d)", state->address, index);
+        const char* btAddress = (*env)->GetStringUTFChars(env, jni_btAddress, NULL);
+        if (!btAddress)
+        {
+            CACheckJNIException(env);
+            oc_mutex_unlock(g_gattObjectMutex);
+            OIC_LOG(ERROR, TAG, "btAddress is not available");
+            (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
+            (*env)->DeleteLocalRef(env, jni_btAddress);
+            (*env)->DeleteLocalRef(env, jni_obj_device);
+            return NULL;
+        }
 
-        if (!strcmp(state->address, remoteAddress))
+        OIC_LOG_V(DEBUG, TAG, "btAddress : %s (idx: %d)", btAddress, index);
+        if (!strcasecmp(targetAddress, btAddress))
         {
-            OIC_LOG(DEBUG, TAG, "found state");
-            return state;
+            OIC_LOG(DEBUG, TAG, "Found Gatt object from BT device");
+
+            // get LE address
+            jstring jni_LEAddress = CALEClientGetAddressFromGattObj(env, jarrayObj);
+            if (!jni_LEAddress)
+            {
+                OIC_LOG(ERROR, TAG, "jni_LEAddress is null");
+            }
+            oc_mutex_unlock(g_gattObjectMutex);
+            (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
+            (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
+            (*env)->DeleteLocalRef(env, jni_btAddress);
+            (*env)->DeleteLocalRef(env, jni_obj_device);
+            return jni_LEAddress;
         }
+        (*env)->ReleaseStringUTFChars(env, jni_btAddress, btAddress);
+        (*env)->DeleteLocalRef(env, jni_btAddress);
+        (*env)->DeleteLocalRef(env, jni_obj_device);
     }
+    oc_mutex_unlock(g_gattObjectMutex);
 
-    OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in deviceStateList", remoteAddress);
+    (*env)->ReleaseStringUTFChars(env, jni_btTargetAddress, targetAddress);
+    OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in gattObjectList", targetAddress);
     return NULL;
 }
 
-bool CALEClientIsValidState(const char* remoteAddress, uint16_t state_type,
-                             uint16_t target_state)
+/**
+ * BT State List
+ */
+CAResult_t CALEClientUpdateDeviceStateWithBtDevice(JNIEnv *env,
+                                                   jobject device,
+                                                   uint16_t state_type,
+                                                   uint16_t target_state)
 {
-    OIC_LOG_V(DEBUG, TAG, "CALEClientIsValidState : type[%d], target state[%d]",
-              state_type, target_state);
-    VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
+    VERIFY_NON_NULL(device, TAG, "device is null");
 
-    ca_mutex_lock(g_deviceStateListMutex);
-    if (!g_deviceStateList)
+    // get Bluetooth Address
+    jstring jni_Address = CALEGetAddressFromBTDevice(env, device);
+    if (!jni_Address)
     {
-        OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
-        ca_mutex_unlock(g_deviceStateListMutex);
-        return false;
+        OIC_LOG(ERROR, TAG, "CALEGetAddressFromBTDevice has failed");
+        return CA_STATUS_FAILED;
     }
 
-    CALEState_t* state = CALEClientGetStateInfo(remoteAddress);
-    if (NULL == state)
+    const char* address = (*env)->GetStringUTFChars(env, jni_Address, NULL);
+    if (!address)
     {
-        OIC_LOG(ERROR, TAG, "state is null");
-        ca_mutex_unlock(g_deviceStateListMutex);
-        return false;
+        OIC_LOG(ERROR, TAG, "targetAddress is not available");
+        CACheckJNIException(env);
+        (*env)->DeleteLocalRef(env, jni_Address);
+        return CA_STATUS_FAILED;
     }
 
-    uint16_t curValue = 0;
-    switch(state_type)
+    if (CALEIsValidState(address, state_type, target_state,
+                         g_deviceStateList,
+                         g_deviceStateListMutex))
     {
-        case CA_LE_CONNECTION_STATE:
-            curValue = state->connectedState;
-            break;
-        case CA_LE_SEND_STATE:
-            curValue = state->sendState;
-            break;
-        default:
-            break;
+        (*env)->DeleteLocalRef(env, jni_Address);
+        return CA_STATUS_OK;
     }
 
-    if (target_state == curValue)
-    {
-        ca_mutex_unlock(g_deviceStateListMutex);
-        return true;
-    }
-    else
+    CAResult_t res = CALEUpdateDeviceState(address, state_type,
+                                           target_state,
+                                           g_deviceStateList,
+                                           g_deviceStateListMutex);
+    if (CA_STATUS_OK != res)
     {
-        ca_mutex_unlock(g_deviceStateListMutex);
-        return false;
+        OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
     }
+    (*env)->ReleaseStringUTFChars(env, jni_Address, address);
+    (*env)->DeleteLocalRef(env, jni_Address);
 
-    ca_mutex_unlock(g_deviceStateListMutex);
-    return false;
+    return res;
+}
+
+CAResult_t CALEClientSetFlagToState(JNIEnv *env, jstring jni_address,
+                                    jint state_idx, jboolean flag)
+{
+    return CALESetFlagToState(env, jni_address, state_idx, flag,
+                              g_deviceStateList, g_deviceStateListMutex);
+}
+
+jboolean CALEClientGetFlagFromState(JNIEnv *env, jstring jni_address, jint state_idx)
+{
+    return CALEGetFlagFromState(env, jni_address, state_idx, g_deviceStateList,
+                                g_deviceStateListMutex);
+}
+
+uint16_t CALEClientGetMtuSize(const char* address)
+{
+    return CALEGetMtuSize(address, g_deviceStateList, g_deviceStateListMutex);
 }
 
 void CALEClientCreateDeviceList()
@@ -3746,6 +4396,11 @@ void CALEClientCreateDeviceList()
     }
 }
 
+CAResult_t CALEClientResetDeviceStateForAll()
+{
+    return CALEResetDeviceStateForAll(g_deviceStateList, g_deviceStateListMutex);
+}
+
 /**
  * Check Sent Count for remove g_sendBuffer
  */
@@ -3755,7 +4410,7 @@ void CALEClientUpdateSendCnt(JNIEnv *env)
 
     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
     // mutex lock
-    ca_mutex_lock(g_threadMutex);
+    oc_mutex_lock(g_threadMutex);
 
     g_currentSentCnt++;
 
@@ -3764,143 +4419,153 @@ void CALEClientUpdateSendCnt(JNIEnv *env)
         g_targetCnt = 0;
         g_currentSentCnt = 0;
 
-        if (g_sendBuffer)
-        {
-            (*env)->DeleteGlobalRef(env, g_sendBuffer);
-            g_sendBuffer = NULL;
-        }
+        CALEDeleteSendBuffer(env);
+
         // notity the thread
-        ca_cond_signal(g_threadCond);
+        oc_cond_signal(g_threadCond);
+        oc_cond_signal(g_threadWriteCharacteristicCond);
 
         CALEClientSetSendFinishFlag(true);
         OIC_LOG(DEBUG, TAG, "set signal for send data");
     }
 
+#ifdef SCAN_INTERVAL
     // reset interval scan logic
     CALERestartScanWithInterval(g_scanIntervalTimePrev, 0, BLE_SCAN_ENABLE);
+#endif
 
     // mutex unlock
-    ca_mutex_unlock(g_threadMutex);
+    oc_mutex_unlock(g_threadMutex);
 }
 
 CAResult_t CALEClientInitGattMutexVaraibles()
 {
     if (NULL == g_bleReqRespClientCbMutex)
     {
-        g_bleReqRespClientCbMutex = ca_mutex_new();
+        g_bleReqRespClientCbMutex = oc_mutex_new();
         if (NULL == g_bleReqRespClientCbMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_bleServerBDAddressMutex)
     {
-        g_bleServerBDAddressMutex = ca_mutex_new();
+        g_bleServerBDAddressMutex = oc_mutex_new();
         if (NULL == g_bleServerBDAddressMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_threadMutex)
     {
-        g_threadMutex = ca_mutex_new();
+        g_threadMutex = oc_mutex_new();
         if (NULL == g_threadMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_threadSendMutex)
     {
-        g_threadSendMutex = ca_mutex_new();
+        g_threadSendMutex = oc_mutex_new();
         if (NULL == g_threadSendMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_deviceListMutex)
     {
-        g_deviceListMutex = ca_mutex_new();
+        g_deviceListMutex = oc_mutex_new();
         if (NULL == g_deviceListMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_gattObjectMutex)
     {
-        g_gattObjectMutex = ca_mutex_new();
+        g_gattObjectMutex = oc_mutex_new();
         if (NULL == g_gattObjectMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_deviceStateListMutex)
     {
-        g_deviceStateListMutex = ca_mutex_new();
+        g_deviceStateListMutex = oc_mutex_new();
         if (NULL == g_deviceStateListMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_SendFinishMutex)
     {
-        g_SendFinishMutex = ca_mutex_new();
+        g_SendFinishMutex = oc_mutex_new();
         if (NULL == g_SendFinishMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_threadWriteCharacteristicMutex)
     {
-        g_threadWriteCharacteristicMutex = ca_mutex_new();
+        g_threadWriteCharacteristicMutex = oc_mutex_new();
         if (NULL == g_threadWriteCharacteristicMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_deviceScanRetryDelayMutex)
     {
-        g_deviceScanRetryDelayMutex = ca_mutex_new();
+        g_deviceScanRetryDelayMutex = oc_mutex_new();
         if (NULL == g_deviceScanRetryDelayMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_threadSendStateMutex)
     {
-        g_threadSendStateMutex = ca_mutex_new();
+        g_threadSendStateMutex = oc_mutex_new();
         if (NULL == g_threadSendStateMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_threadScanIntervalMutex)
     {
-        g_threadScanIntervalMutex = ca_mutex_new();
+        g_threadScanIntervalMutex = oc_mutex_new();
         if (NULL == g_threadScanIntervalMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_setValueMutex)
+    {
+        g_setValueMutex = oc_mutex_new();
+        if (NULL == g_setValueMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
             return CA_STATUS_FAILED;
         }
     }
@@ -3910,44 +4575,53 @@ CAResult_t CALEClientInitGattMutexVaraibles()
 
 void CALEClientTerminateGattMutexVariables()
 {
-    ca_mutex_free(g_bleReqRespClientCbMutex);
+    oc_mutex_free(g_bleReqRespClientCbMutex);
     g_bleReqRespClientCbMutex = NULL;
 
-    ca_mutex_free(g_bleServerBDAddressMutex);
+    oc_mutex_free(g_bleServerBDAddressMutex);
     g_bleServerBDAddressMutex = NULL;
 
-    ca_mutex_free(g_threadMutex);
+    oc_mutex_free(g_threadMutex);
     g_threadMutex = NULL;
 
-    ca_mutex_free(g_threadSendMutex);
+    oc_mutex_free(g_threadSendMutex);
     g_threadSendMutex = NULL;
 
-    ca_mutex_free(g_deviceListMutex);
+    oc_mutex_free(g_deviceListMutex);
     g_deviceListMutex = NULL;
 
-    ca_mutex_free(g_SendFinishMutex);
+    oc_mutex_free(g_SendFinishMutex);
     g_SendFinishMutex = NULL;
 
-    ca_mutex_free(g_threadWriteCharacteristicMutex);
+    oc_mutex_free(g_threadWriteCharacteristicMutex);
     g_threadWriteCharacteristicMutex = NULL;
 
-    ca_mutex_free(g_deviceScanRetryDelayMutex);
+    oc_mutex_free(g_deviceScanRetryDelayMutex);
     g_deviceScanRetryDelayMutex = NULL;
 
-    ca_mutex_free(g_threadSendStateMutex);
+    oc_mutex_free(g_threadSendStateMutex);
     g_threadSendStateMutex = NULL;
 
-    ca_mutex_free(g_threadScanIntervalMutex);
+    oc_mutex_free(g_threadScanIntervalMutex);
     g_threadScanIntervalMutex = NULL;
+
+    oc_mutex_free(g_gattObjectMutex);
+    g_gattObjectMutex = NULL;
+
+    oc_mutex_free(g_deviceStateListMutex);
+    g_deviceStateListMutex = NULL;
+
+    oc_mutex_free(g_setValueMutex);
+    g_setValueMutex = NULL;
 }
 
 void CALEClientSetSendFinishFlag(bool flag)
 {
     OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
 
-    ca_mutex_lock(g_SendFinishMutex);
+    oc_mutex_lock(g_SendFinishMutex);
     g_isFinishedSendData = flag;
-    ca_mutex_unlock(g_SendFinishMutex);
+    oc_mutex_unlock(g_SendFinishMutex);
 }
 
 /**
@@ -3959,22 +4633,22 @@ CAResult_t CAStartLEGattClient()
     // init mutex for send logic
     if (!g_deviceDescCond)
     {
-        g_deviceDescCond = ca_cond_new();
+        g_deviceDescCond = oc_cond_new();
     }
 
     if (!g_threadCond)
     {
-        g_threadCond = ca_cond_new();
+        g_threadCond = oc_cond_new();
     }
 
     if (!g_threadWriteCharacteristicCond)
     {
-        g_threadWriteCharacteristicCond = ca_cond_new();
+        g_threadWriteCharacteristicCond = oc_cond_new();
     }
 
     if (!g_threadScanIntervalCond)
     {
-        g_threadScanIntervalCond = ca_cond_new();
+        g_threadScanIntervalCond = oc_cond_new();
     }
 
     CAResult_t ret = CALEClientStartScanWithInterval();
@@ -4003,7 +4677,6 @@ void CAStopLEGattClient()
     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
     if (JNI_OK != res)
     {
-        OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
 
         if (JNI_OK != res)
@@ -4022,32 +4695,37 @@ void CAStopLEGattClient()
 
     CALEClientStopScanWithInterval();
 
-    ca_mutex_lock(g_threadMutex);
-    OIC_LOG(DEBUG, TAG, "signal - connection cond");
-    ca_cond_signal(g_threadCond);
-    CALEClientSetSendFinishFlag(true);
-    ca_mutex_unlock(g_threadMutex);
-
-    ca_mutex_lock(g_threadWriteCharacteristicMutex);
+    oc_mutex_lock(g_threadWriteCharacteristicMutex);
     OIC_LOG(DEBUG, TAG, "signal - WriteCharacteristic cond");
-    ca_cond_signal(g_threadWriteCharacteristicCond);
-    ca_mutex_unlock(g_threadWriteCharacteristicMutex);
+    oc_cond_signal(g_threadWriteCharacteristicCond);
+    oc_mutex_unlock(g_threadWriteCharacteristicMutex);
+
+    CALEClientSetSendFinishFlag(true);
+    oc_mutex_lock(g_threadMutex);
+    OIC_LOG(DEBUG, TAG, "signal - g_threadCond cond");
+    oc_cond_signal(g_threadCond);
+    oc_mutex_unlock(g_threadMutex);
 
-    ca_mutex_lock(g_deviceScanRetryDelayMutex);
+    oc_mutex_lock(g_deviceScanRetryDelayMutex);
     OIC_LOG(DEBUG, TAG, "signal - delay cond");
-    ca_cond_signal(g_deviceScanRetryDelayCond);
-    ca_mutex_unlock(g_deviceScanRetryDelayMutex);
+    oc_cond_signal(g_deviceScanRetryDelayCond);
+    oc_mutex_unlock(g_deviceScanRetryDelayMutex);
 
-    ca_mutex_lock(g_threadScanIntervalMutex);
+    oc_mutex_lock(g_threadScanIntervalMutex);
     OIC_LOG(DEBUG, TAG, "signal - delay cond");
-    ca_cond_signal(g_threadScanIntervalCond);
-    ca_mutex_unlock(g_threadScanIntervalMutex);
+    oc_cond_signal(g_threadScanIntervalCond);
+    oc_mutex_unlock(g_threadScanIntervalMutex);
+
+    oc_mutex_lock(g_threadSendMutex);
+    OIC_LOG(DEBUG, TAG, "signal - g_deviceDesc cond");
+    oc_cond_signal(g_deviceDescCond);
+    oc_mutex_unlock(g_threadSendMutex);
 
-    ca_cond_free(g_deviceDescCond);
-    ca_cond_free(g_threadCond);
-    ca_cond_free(g_threadWriteCharacteristicCond);
-    ca_cond_free(g_deviceScanRetryDelayCond);
-    ca_cond_free(g_threadScanIntervalCond);
+    oc_cond_free(g_deviceDescCond);
+    oc_cond_free(g_threadCond);
+    oc_cond_free(g_threadWriteCharacteristicCond);
+    oc_cond_free(g_deviceScanRetryDelayCond);
+    oc_cond_free(g_threadScanIntervalCond);
 
     g_deviceDescCond = NULL;
     g_threadCond = NULL;
@@ -4071,17 +4749,17 @@ CAResult_t CAInitializeLEGattClient()
 
 void CATerminateLEGattClient()
 {
-    OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
+    OIC_LOG(INFO, TAG, "IN - Terminate GATT Client");
     CAStopLEGattClient();
     CALEClientTerminate();
+    OIC_LOG(INFO, TAG, "OUT - Terminate GATT Client");
 }
 
 CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const uint8_t  *data,
                                                uint32_t dataLen, CALETransferType_t type,
                                                int32_t position)
 {
-    OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
-    VERIFY_NON_NULL(data, TAG, "data is null");
+    OIC_LOG(INFO, TAG, "call CALEClientSendUnicastMessage");
     VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
 
     if (LE_UNICAST != type || position < 0)
@@ -4103,9 +4781,9 @@ CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t
 
 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
 {
-    ca_mutex_lock(g_bleReqRespClientCbMutex);
+    oc_mutex_lock(g_bleReqRespClientCbMutex);
     g_CABLEClientDataReceivedCallback = callback;
-    ca_mutex_unlock(g_bleReqRespClientCbMutex);
+    oc_mutex_unlock(g_bleReqRespClientCbMutex);
 }
 
 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
@@ -4116,7 +4794,6 @@ void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
 CAResult_t CAGetLEAddress(char **local_address)
 {
     VERIFY_NON_NULL(local_address, TAG, "local_address");
-    OIC_LOG(INFO, TAG, "CAGetLEAddress is not support");
     return CA_NOT_SUPPORTED;
 }
 
@@ -4130,6 +4807,21 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback(JNIEnv *env,
     VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
 
     g_leScanCallback = (*env)->NewGlobalRef(env, callback);
+    CACheckJNIException(env);
+}
+
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallbackForV21(JNIEnv *env,
+                                                                          jobject obj,
+                                                                          jobject callback)
+{
+    OIC_LOG(DEBUG, TAG, "caLeRegisterLeScanCallbackForV21");
+    VERIFY_NON_NULL_VOID(env, TAG, "env is null");
+    VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
+    VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
+
+    g_leScanCallback = (*env)->NewGlobalRef(env, callback);
+    CACheckJNIException(env);
 }
 
 JNIEXPORT void JNICALL
@@ -4142,6 +4834,7 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback(JNIEnv *env, j
     VERIFY_NON_NULL_VOID(callback, TAG, "callback is null");
 
     g_leGattCallback = (*env)->NewGlobalRef(env, callback);
+    CACheckJNIException(env);
 }
 
 JNIEXPORT void JNICALL
@@ -4159,6 +4852,38 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback(JNIEnv *env, jobject o
     }
 }
 
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaLeClientInterface_caLeScanFailedCallback(JNIEnv *env, jobject obj,
+                                                                jint errorCode)
+{
+    VERIFY_NON_NULL_VOID(env, TAG, "env is null");
+    VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
+
+    switch (errorCode)
+    {
+        case 1:
+            OIC_LOG(ERROR, TAG, "BLE scan has failed, error is SCAN_FAILED_ALREADY_STARTED");
+            break;
+
+        case 2:
+            OIC_LOG(ERROR, TAG,
+                    "BLE scan has failed, error is SCAN_FAILED_APPLICATION_REGISTRATION_FAILED");
+            break;
+
+        case 3:
+            OIC_LOG(ERROR, TAG, "BLE scan has failed, error is SCAN_FAILED_INTERNAL_ERROR");
+            break;
+
+        case 4:
+            OIC_LOG(ERROR, TAG, "BLE scan has failed, error is SCAN_FAILED_FEATURE_UNSUPPORTED");
+            break;
+
+        default:
+            OIC_LOG(ERROR, TAG, "BLE scan has failed with unknown error");
+            break;
+    }
+}
+
 /*
  * Class:     org_iotivity_ca_jar_caleinterface
  * Method:    CALeGattConnectionStateChangeCallback
@@ -4190,22 +4915,25 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(J
     if (!address)
     {
         OIC_LOG(ERROR, TAG, "address is null");
+        CACheckJNIException(env);
         goto error_exit;
     }
-    OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - address [%s]", address);
+    OIC_LOG_V(INFO, TAG, "CALeGattConnectionStateChangeCallback - address [%s]", address);
 
     if (state_connected == newstate)
     {
         OIC_LOG(DEBUG, TAG, "LE is connected");
         if (GATT_SUCCESS == status)
         {
-            CAResult_t res = CALEClientUpdateDeviceState(address,
-                                                         CA_LE_CONNECTION_STATE,
-                                                         STATE_CONNECTED);
+            CAResult_t res = CALEUpdateDeviceState(address,
+                                                   CA_LE_CONNECTION_STATE,
+                                                   STATE_CONNECTED,
+                                                   g_deviceStateList,
+                                                   g_deviceStateListMutex);
             (*env)->ReleaseStringUTFChars(env, jni_address, address);
             if (CA_STATUS_OK != res)
             {
-                OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
+                OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
                 goto error_exit;
             }
 
@@ -4233,15 +4961,30 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(J
     {
         OIC_LOG(DEBUG, TAG, "LE is disconnected");
 
-        CAResult_t res = CALEClientUpdateDeviceState(address,
-                                                     CA_LE_CONNECTION_STATE,
-                                                     STATE_DISCONNECTED);
-        (*env)->ReleaseStringUTFChars(env, jni_address, address);
+        if (CALEIsValidState(address, CA_LE_SEND_STATE, STATE_SEND_PREPARING,
+                             g_deviceStateList, g_deviceStateListMutex))
+        {
+            OIC_LOG(INFO, TAG, "current state is STATE_SEND_PREPARING");
+            CAResult_t res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
+                                                   STATE_SEND_FAIL,
+                                                   g_deviceStateList,
+                                                   g_deviceStateListMutex);
+            if (CA_STATUS_OK != res)
+            {
+                OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
+            }
+        }
+
+        CAResult_t res = CALEUpdateDeviceState(address,
+                                               CA_LE_CONNECTION_STATE,
+                                               STATE_DISCONNECTED,
+                                               g_deviceStateList,
+                                               g_deviceStateListMutex);
         if (CA_STATUS_OK != res)
         {
-            OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
-            goto error_exit;
+            OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
         }
+        (*env)->ReleaseStringUTFChars(env, jni_address, address);
 
         res = CALEClientGattClose(env, gatt);
         if (CA_STATUS_OK != res)
@@ -4254,22 +4997,14 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback(J
             // this state is unexpected reason to disconnect
             // if the reason is suitable, connection logic of the device will be destroyed.
             OIC_LOG(INFO, TAG, "connection logic destroy");
-            goto error_exit;
         }
         else
         {
             // other reason except for gatt_success is expected to running
             // background connection in BT platform.
             OIC_LOG(INFO, TAG, "unknown status or manual disconnected state");
-            CALEClientUpdateSendCnt(env);
-            return;
-        }
-
-        if (g_sendBuffer)
-        {
-            (*env)->DeleteGlobalRef(env, g_sendBuffer);
-            g_sendBuffer = NULL;
         }
+        CALEClientUpdateSendCnt(env);
     }
     return;
 
@@ -4311,6 +5046,7 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIE
     const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
     if (!address)
     {
+        CACheckJNIException(env);
         CALEClientSendFinish(env, gatt);
         return;
     }
@@ -4342,43 +5078,46 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback(JNIE
     {
         OIC_LOG_V(INFO, TAG, "Descriptor is not found : %d", res);
 
-        res = CALEClientSetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_FALSE);
+        res = CALESetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_FALSE,
+                                 g_deviceStateList, g_deviceStateListMutex);
         if (CA_STATUS_OK != res)
         {
-            OIC_LOG(ERROR, TAG, "CALEClientSetFlagToState has failed");
+            OIC_LOG(ERROR, TAG, "CALESetFlagToState has failed");
             goto error_exit;
         }
 
-        res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
-                                          STATE_SERVICE_CONNECTED);
+        res = CALEUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
+                                    STATE_SERVICE_CONNECTED,
+                                    g_deviceStateList,
+                                    g_deviceStateListMutex);
         if (CA_STATUS_OK != res)
         {
-            OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
+            OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
             goto error_exit;
         }
 
-        if (g_sendBuffer)
+        res = CALEClientRequestMTU(env, gatt, CA_SUPPORTED_BLE_MTU_SIZE);
+        if (CA_STATUS_OK != res)
         {
-            CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
-            if (CA_STATUS_OK != res)
-            {
-                OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
-                goto error_exit;
-            }
+            OIC_LOG(ERROR, TAG, "CALEClientRequestMTU has failed");
+            goto error_exit;
         }
     }
     else
     {
-        res = CALEClientSetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_TRUE);
+        res = CALESetFlagToState(env, jni_address, CA_LE_DESCRIPTOR_FOUND, JNI_TRUE,
+                                 g_deviceStateList, g_deviceStateListMutex);
         if (CA_STATUS_OK != res)
         {
-            OIC_LOG(ERROR, TAG, "CALEClientSetFlagToState has failed");
+            OIC_LOG(ERROR, TAG, "CALESetFlagToState has failed");
             goto error_exit;
         }
     }
 
+#ifdef SCAN_INTERVAL
     // reset interval scan logic
     CALERestartScanWithInterval(g_scanIntervalTimePrev, 0, BLE_SCAN_ENABLE);
+#endif
 
     OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
     (*env)->ReleaseStringUTFChars(env, jni_address, address);
@@ -4416,6 +5155,7 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
     const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
     if (!address)
     {
+        CACheckJNIException(env);
         goto error_exit;
     }
 
@@ -4428,22 +5168,27 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
         if (CA_STATUS_OK != res)
         {
             OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
-            ca_mutex_lock(g_threadWriteCharacteristicMutex);
+            oc_mutex_lock(g_threadWriteCharacteristicMutex);
             g_isSignalSetFlag = true;
-            ca_cond_signal(g_threadWriteCharacteristicCond);
-            ca_mutex_unlock(g_threadWriteCharacteristicMutex);
+            oc_cond_signal(g_threadWriteCharacteristicCond);
+            oc_mutex_unlock(g_threadWriteCharacteristicMutex);
 
-            CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
-                                                         STATE_SEND_FAIL);
+            CAResult_t res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
+                                                   STATE_SEND_FAIL,
+                                                   g_deviceStateList,
+                                                   g_deviceStateListMutex);
             if (CA_STATUS_OK != res)
             {
-                OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
+                OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
             }
 
             if (g_clientErrorCallback)
             {
                 jint length = (*env)->GetArrayLength(env, data);
+                CACheckJNIException(env);
                 g_clientErrorCallback(address, data, length, CA_SEND_FAILED);
+                CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, address, 0, length,
+                                   false, "writeChar failure");
             }
 
             (*env)->ReleaseStringUTFChars(env, jni_address, address);
@@ -4453,18 +5198,24 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback(
     else
     {
         OIC_LOG(DEBUG, TAG, "send success");
-        CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_SEND_STATE,
-                                                     STATE_SEND_SUCCESS);
+        CAResult_t res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
+                                               STATE_SEND_SUCCESS,
+                                               g_deviceStateList,
+                                               g_deviceStateListMutex);
         if (CA_STATUS_OK != res)
         {
-            OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
+            OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
         }
 
-        ca_mutex_lock(g_threadWriteCharacteristicMutex);
+        oc_mutex_lock(g_threadWriteCharacteristicMutex);
         OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
         g_isSignalSetFlag = true;
-        ca_cond_signal(g_threadWriteCharacteristicCond);
-        ca_mutex_unlock(g_threadWriteCharacteristicMutex);
+        oc_cond_signal(g_threadWriteCharacteristicCond);
+        oc_mutex_unlock(g_threadWriteCharacteristicMutex);
+
+        CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, address, 0,
+                           (*env)->GetArrayLength(env, data),
+                           true, "writeChar success");
     }
 
     (*env)->ReleaseStringUTFChars(env, jni_address, address);
@@ -4486,7 +5237,7 @@ JNIEXPORT void JNICALL
 Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
         JNIEnv *env, jobject obj, jobject gatt, jbyteArray data)
 {
-    OIC_LOG(INFO, TAG, "CALeGattCharacteristicChangedCallback");
+    OIC_LOG(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
     VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
     VERIFY_NON_NULL_VOID(gatt, TAG, "gatt is null");
@@ -4497,9 +5248,7 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
 
     jboolean isCopy;
     jbyte *jni_byte_responseData = (jbyte*) (*env)->GetByteArrayElements(env, data, &isCopy);
-
-    OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - raw data received : %p",
-            jni_byte_responseData);
+    CACheckJNIException(env);
 
     uint8_t* receivedData = OICMalloc(length);
     if (!receivedData)
@@ -4523,6 +5272,7 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
     if (!address)
     {
         OIC_LOG(ERROR, TAG, "address is null");
+        CACheckJNIException(env);
         OICFree(receivedData);
         return;
     }
@@ -4531,9 +5281,9 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback(
               receivedData, length);
 
     uint32_t sentLength = 0;
-    ca_mutex_lock(g_bleServerBDAddressMutex);
+    oc_mutex_lock(g_bleServerBDAddressMutex);
     g_CABLEClientDataReceivedCallback(address, receivedData, length, &sentLength);
-    ca_mutex_unlock(g_bleServerBDAddressMutex);
+    oc_mutex_unlock(g_bleServerBDAddressMutex);
 
     (*env)->ReleaseStringUTFChars(env, jni_address, address);
 }
@@ -4567,26 +5317,26 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback(JNIEnv
     const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
     if (!address)
     {
+        CACheckJNIException(env);
         goto error_exit;
     }
 
-    CAResult_t res = CALEClientUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
-                                                 STATE_SERVICE_CONNECTED);
+    CAResult_t res = CALEUpdateDeviceState(address, CA_LE_CONNECTION_STATE,
+                                           STATE_SERVICE_CONNECTED,
+                                           g_deviceStateList,
+                                           g_deviceStateListMutex);
     (*env)->ReleaseStringUTFChars(env, jni_address, address);
     if (CA_STATUS_OK != res)
     {
-        OIC_LOG(ERROR, TAG, "CALEClientUpdateDeviceState has failed");
+        OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
         goto error_exit;
     }
 
-    if (g_sendBuffer)
+    res = CALEClientRequestMTU(env, gatt, CA_SUPPORTED_BLE_MTU_SIZE);
+    if (CA_STATUS_OK != res)
     {
-        CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
-        if (CA_STATUS_OK != res)
-        {
-            OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
-            goto error_exit;
-        }
+        OIC_LOG(ERROR, TAG, "CALEClientRequestMTU has failed");
+        goto error_exit;
     }
     return;
 
@@ -4596,3 +5346,67 @@ error_exit:
     CALEClientSendFinish(env, gatt);
     return;
 }
+
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaLeClientInterface_caLeGattMtuChangedCallback(JNIEnv *env,
+                                                                    jobject obj,
+                                                                    jobject gatt,
+                                                                    jint mtu,
+                                                                    jint status)
+{
+    OIC_LOG_V(INFO, TAG, "caLeGattMtuChangedCallback - status %d, "
+              "mtu[%d-including Header size 3 byte]", status, mtu);
+
+    (void)obj;
+
+    if (0 == status || 133 == status)
+    {
+        if (g_sendBuffer)
+        {
+            CAResult_t res = CALEClientWriteCharacteristic(env, gatt);
+            if (CA_STATUS_OK != res)
+            {
+                OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
+            }
+        }
+        else
+        {
+            OIC_LOG(INFO, TAG, "mtu nego is done");
+            jstring jni_address = CALEClientGetAddressFromGattObj(env, gatt);
+            if (!jni_address)
+            {
+                CALEClientSendFinish(env, gatt);
+                return;
+            }
+
+            const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
+            if (!address)
+            {
+                CACheckJNIException(env);
+                (*env)->DeleteLocalRef(env, jni_address);
+                CALEClientSendFinish(env, gatt);
+                return;
+            }
+
+            // update mtu size
+            CAResult_t res = CALESetMtuSize(address, mtu - CA_BLE_MTU_HEADER_SIZE,
+                                            g_deviceStateList, g_deviceStateListMutex);
+            if (CA_STATUS_OK != res)
+            {
+                OIC_LOG(ERROR, TAG, "CALESetMtuSize has failed");
+            }
+
+            res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
+                                        STATE_SEND_MTU_NEGO_SUCCESS,
+                                        g_deviceStateList,
+                                        g_deviceStateListMutex);
+            if (CA_STATUS_OK != res)
+            {
+                OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
+            }
+            CALEClientUpdateSendCnt(env);
+            (*env)->ReleaseStringUTFChars(env, jni_address, address);
+            (*env)->DeleteLocalRef(env, jni_address);
+        }
+    }
+}
index d42b6f2..e05a0d4 100644 (file)
@@ -25,6 +25,7 @@
 #ifndef CA_LECLIENT_H_
 #define CA_LECLIENT_H_
 
+#include "calestate.h"
 #include "cacommon.h"
 #include "cathreadpool.h"
 #include "uarraylist.h"
@@ -35,29 +36,14 @@ extern "C"
 {
 #endif
 
-static const uint16_t GATT_ERROR = 133;
-
-static const uint16_t STATE_SEND_NONE = 1;
-static const uint16_t STATE_SEND_SUCCESS = 2;
-static const uint16_t STATE_SEND_FAIL = 3;
-static const uint16_t STATE_SENDING = 4;
-
-typedef struct le_state_info
-{
-    char address[CA_MACADDR_SIZE];
-    uint16_t connectedState;
-    uint16_t sendState;
-    jboolean autoConnectFlag;
-    jboolean isDescriptorFound;
-} CALEState_t;
-
 /**
  * BLE Scanning State.
  */
 typedef enum
 {
     BLE_SCAN_ENABLE = 0, /**< BLE scan is working */
-    BLE_SCAN_DISABLE     /**< BLE scan is not working */
+    BLE_SCAN_DISABLE,    /**< BLE scan is not working */
+    BLE_SCAN_NONE        /**< Initialize State */
 } CALEScanState_t;
 
 /**
@@ -109,6 +95,13 @@ CAResult_t CALEClientDestroyJniInterface();
 void CALEClientSendFinish(JNIEnv *env, jobject gatt);
 
 /**
+ * send negotiation message after gatt connection is done.
+ * @param[in]   address               remote address.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientSendNegotiationMessage(const char* address);
+
+/**
  * send data for unicast (interface).
  * @param[in]   address               remote address.
  * @param[in]   data                  data for transmission.
@@ -233,6 +226,14 @@ CAResult_t CALEClientStartScan();
 CAResult_t CALEClientStartScanImpl(JNIEnv *env, jobject callback);
 
 /**
+ * start to scan whole bluetooth devices for android API level 21 (implement).
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   callback              callback to receive device object by scanning.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientStartScanImplForV21(JNIEnv *env, jobject callback);
+
+/**
  * start to scan target bluetooth devices for service uuid (implement).
  * @param[in]   env                   JNI interface pointer.
  * @param[in]   uuids                 target UUID.
@@ -243,6 +244,16 @@ CAResult_t CALEClientStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids,
                                            jobject callback);
 
 /**
+ * start to scan target bluetooth devices for service uuid for android API level 21 (implement).
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   uuids                 target UUID.
+ * @param[in]   callback              callback to receive device object by scanning.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientStartScanWithUUIDImplForV21(JNIEnv *env, jobjectArray uuids,
+                                                 jobject callback);
+
+/**
  * get uuid object.
  * @param[in]   env                   JNI interface pointer.
  * @param[in]   uuid                  uuid.
@@ -265,23 +276,12 @@ CAResult_t CALEClientStopScan();
 CAResult_t CALEClientStopScanImpl(JNIEnv *env, jobject callback);
 
 /**
- * set flag into State List.
- * @param[in]   env                   JNI interface pointer.
- * @param[in]   jni_address           remote address.
- * @param[in]   state_idx             state index.
- * @param[in]   flag                  auto connect flag.
- */
-CAResult_t CALEClientSetFlagToState(JNIEnv *env, jstring jni_address,
-                                    jint state_idx, jboolean flag);
-
-/**
- * get flag from State List.
+ * stop scan for android API level 21(implement).
  * @param[in]   env                   JNI interface pointer.
- * @param[in]   jni_address           remote address.
- * @param[in]   state_idx             state index.
- * @return  current flag;
+ * @param[in]   callback              callback to receive device object by scanning.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
  */
-jboolean CALEClientGetFlagFromState(JNIEnv *env, jstring jni_address, jint state_idx);
+CAResult_t CALEClientStopScanImplForV21(JNIEnv *env, jobject callback);
 
 /**
  * connect to gatt server hosted.
@@ -318,6 +318,14 @@ CAResult_t CALEClientDisconnectAll(JNIEnv *env);
 CAResult_t CALEClientDisconnectforAddress(JNIEnv *env, jstring remoteAddress);
 
 /**
+ * request MTU size negotiation to server.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   bluetoothGatt         gatt object.
+ * @param[in]   size                  MTU size.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientRequestMTU(JNIEnv *env, jobject bluetoothGatt, jint size);
+/**
  * start discovery server.
  * @param[in]   env                   JNI interface pointer.
  * @param[in]   bluetoothGatt         Gatt profile object.
@@ -499,58 +507,50 @@ CAResult_t CALEClientRemoveGattObjForAddr(JNIEnv *env, jstring addr);
 jstring CALEClientGetLEAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice);
 
 /**
- * update new state information.
- * @param[in]   address               remote address.
+ * update new state information by Bluetooth device object.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   device                Bluetooth device.
  * @param[in]   state_type            state type.
  * @param[in]   target_state          state index to update.
  * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
  */
-CAResult_t CALEClientUpdateDeviceState(const char* address, uint16_t state_type,
-                                       uint16_t target_state);
+CAResult_t CALEClientUpdateDeviceStateWithBtDevice(JNIEnv *env,
+                                                   jobject device,
+                                                   uint16_t state_type,
+                                                   uint16_t target_state);
 
 /**
- * check whether the remote address is existed or not.
- * @param[in]   address               remote address.
- * @return  true or false.
+ * set flag into State List.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   jni_address           remote address.
+ * @param[in]   state_idx             state index.
+ * @param[in]   flag                  auto connect flag.
  */
-bool CALEClientIsDeviceInList(const char *remoteAddress);
+CAResult_t CALEClientSetFlagToState(JNIEnv *env, jstring jni_address,
+                                    jint state_idx, jboolean flag);
 
 /**
- * remove all device states.
- * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ * get flag from State List.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   jni_address           remote address.
+ * @param[in]   state_idx             state index.
+ * @return  current flag;
  */
-CAResult_t CALEClientRemoveAllDeviceState();
+jboolean CALEClientGetFlagFromState(JNIEnv *env, jstring jni_address, jint state_idx);
 
 /**
- * Reset values of device state for all of devices.
- * this method has to be invoked when BT adapter is disabled.
- * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ * get MTU size.
+ * @param[in] address      the address of the remote device.
+ * @return  mtu size negotiated from remote device.
  */
-CAResult_t CALEClientResetDeviceStateForAll();
+uint16_t CALEClientGetMtuSize(const char* address);
 
 /**
- * remove the device state for a remote device.
- * @param[in]   remoteAddress         remote address.
+ * Reset values of device state for all of devices.
+ * this method has to be invoked when BT adapter is disabled.
  * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
  */
-CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress);
-
-/**
- * get state information for a remote device.
- * @param[in]   remoteAddress         remote address.
- * @return  CALEState_t.
- */
-CALEState_t* CALEClientGetStateInfo(const char* remoteAddress);
-
-/**
- * check whether the remote address has same state with target state.
- * @param[in]   remoteAddress         remote address.
- * @param[in]   state_type            state_type.
- * @param[in]   target_state          state index to check.
- * @return  true or false.
- */
-bool CALEClientIsValidState(const char* remoteAddress, uint16_t state_type,
-                            uint16_t target_state);
+CAResult_t CALEClientResetDeviceStateForAll();
 
 /**
  * create scan device list.
@@ -607,6 +607,13 @@ jobject CALEClientGattConnect(JNIEnv *env, jobject bluetoothDevice, jboolean aut
 CAResult_t CALEClientDirectConnect(JNIEnv *env, jobject bluetoothDevice, jboolean autoconnect);
 
 /**
+ * check connection status.
+ * @param[in] address      the address of the remote device.
+ * @return  true or false.
+ */
+bool CALEClientIsConnected(const char* address);
+
+/**
  * set new interval time and working count.
  * @param[in]  intervalTime             interval time(Seconds).
  * @param[in]  workingCount             working count for selected interval time.
index 4a65ed2..440fe3e 100644 (file)
@@ -29,7 +29,7 @@
 #include "caleinterface.h"
 #include "caadapterutils.h"
 
-#include "camutex.h"
+#include "octhread.h"
 
 #include "org_iotivity_ca_CaLeClientInterface.h"
 #include "org_iotivity_ca_CaLeServerInterface.h"
@@ -57,14 +57,14 @@ static CALEConnectionStateChangedCallback g_bleConnectionStateChangedCallback =
  * @brief Mutex to synchronize access to the deviceStateChanged Callback when the state
  *           of the LE adapter gets change.
  */
-static ca_mutex g_bleDeviceStateChangedCbMutex = NULL;
+static oc_mutex g_bleDeviceStateChangedCbMutex = NULL;
 
 /**
  * @var g_bleConnectionStateChangedCbMutex
  * @brief Mutex to synchronize access to the LE ConnectionStateChanged Callback when the state
  *           of the LE adapter gets change.
  */
-static ca_mutex g_bleConnectionStateChangedCbMutex = NULL;
+static oc_mutex g_bleConnectionStateChangedCbMutex = NULL;
 
 //getting context
 void CALENetworkMonitorJNISetContext()
@@ -108,49 +108,41 @@ CAResult_t CAStopLEAdapter()
 
 CAResult_t CAInitLENwkMonitorMutexVaraibles()
 {
-    OIC_LOG(DEBUG, TAG, "IN");
     if (NULL == g_bleDeviceStateChangedCbMutex)
     {
-        g_bleDeviceStateChangedCbMutex = ca_mutex_new();
+        g_bleDeviceStateChangedCbMutex = oc_mutex_new();
         if (NULL == g_bleDeviceStateChangedCbMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_bleConnectionStateChangedCbMutex)
     {
-       g_bleConnectionStateChangedCbMutex = ca_mutex_new();
+       g_bleConnectionStateChangedCbMutex = oc_mutex_new();
         if (NULL == g_bleConnectionStateChangedCbMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
-            ca_mutex_free(g_bleDeviceStateChangedCbMutex);
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            oc_mutex_free(g_bleDeviceStateChangedCbMutex);
             return CA_STATUS_FAILED;
         }
     }
 
-    OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
 
 void CATerminateLENwkMonitorMutexVaraibles()
 {
-    OIC_LOG(DEBUG, TAG, "IN");
-
-    ca_mutex_free(g_bleDeviceStateChangedCbMutex);
+    oc_mutex_free(g_bleDeviceStateChangedCbMutex);
     g_bleDeviceStateChangedCbMutex = NULL;
 
-    ca_mutex_free(g_bleConnectionStateChangedCbMutex);
+    oc_mutex_free(g_bleConnectionStateChangedCbMutex);
     g_bleConnectionStateChangedCbMutex = NULL;
-
-    OIC_LOG(DEBUG, TAG, "OUT");
 }
 
 CAResult_t CAGetLEAdapterState()
 {
-    OIC_LOG(DEBUG, TAG, "IN");
-
     if (!g_jvm)
     {
         OIC_LOG(ERROR, TAG, "g_jvm is null");
@@ -188,14 +180,11 @@ CAResult_t CAGetLEAdapterState()
         (*g_jvm)->DetachCurrentThread(g_jvm);
     }
 
-    OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
 
 CAResult_t CAInitializeLENetworkMonitor()
 {
-    OIC_LOG(DEBUG, TAG, "IN");
-
     CAResult_t res = CAInitLENwkMonitorMutexVaraibles();
     if (CA_STATUS_OK != res)
     {
@@ -206,32 +195,24 @@ CAResult_t CAInitializeLENetworkMonitor()
     CALENetworkMonitorJNISetContext();
     CALENetworkMonitorJniInit();
 
-    OIC_LOG(DEBUG, TAG, "OUT");
-
     return CA_STATUS_OK;
-
 }
 
 void CATerminateLENetworkMonitor()
 {
-    OIC_LOG(DEBUG, TAG, "IN");
+    OIC_LOG(DEBUG, TAG, "CATerminateLENetworkMonitor");
 
     CATerminateLENwkMonitorMutexVaraibles();
-
-    OIC_LOG(DEBUG, TAG, "OUT");
 }
 
 CAResult_t CASetLEAdapterStateChangedCb(CALEDeviceStateChangedCallback callback)
 {
-    OIC_LOG(DEBUG, TAG, "IN");
-
     OIC_LOG(DEBUG, TAG, "Setting CALEDeviceStateChangedCallback");
 
-    ca_mutex_lock(g_bleDeviceStateChangedCbMutex);
+    oc_mutex_lock(g_bleDeviceStateChangedCbMutex);
     CALESetAdapterStateCallback(callback);
-    ca_mutex_unlock(g_bleDeviceStateChangedCbMutex);
+    oc_mutex_unlock(g_bleDeviceStateChangedCbMutex);
 
-    OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
 
@@ -243,21 +224,19 @@ CAResult_t CAUnSetLEAdapterStateChangedCb()
 
 CAResult_t CASetLENWConnectionStateChangedCb(CALEConnectionStateChangedCallback callback)
 {
-    OIC_LOG(DEBUG, TAG, "IN");
-    ca_mutex_lock(g_bleConnectionStateChangedCbMutex);
+    OIC_LOG(DEBUG, TAG, "CASetLENWConnectionStateChangedCb");
+    oc_mutex_lock(g_bleConnectionStateChangedCbMutex);
     g_bleConnectionStateChangedCallback = callback;
-    ca_mutex_unlock(g_bleConnectionStateChangedCbMutex);
-    OIC_LOG(DEBUG, TAG, "OUT");
+    oc_mutex_unlock(g_bleConnectionStateChangedCbMutex);
     return CA_STATUS_OK;
 }
 
-CAResult_t CAUnsetLENWConnectionStateChangedCb()
+CAResult_t CAUnSetLENWConnectionStateChangedCb()
 {
-    OIC_LOG(DEBUG, TAG, "IN");
-    ca_mutex_lock(g_bleConnectionStateChangedCbMutex);
+    OIC_LOG(DEBUG, TAG, "CAUnSetLENWConnectionStateChangedCb");
+    oc_mutex_lock(g_bleConnectionStateChangedCbMutex);
     g_bleConnectionStateChangedCallback = NULL;
-    ca_mutex_unlock(g_bleConnectionStateChangedCbMutex);
-    OIC_LOG(DEBUG, TAG, "OUT");
+    oc_mutex_unlock(g_bleConnectionStateChangedCbMutex);
     return CA_STATUS_OK;
 }
 
@@ -275,6 +254,7 @@ static CAResult_t CALEStateConnectedCallback(JNIEnv *env, jstring jni_address,
             if (!address)
             {
                 OIC_LOG(ERROR, TAG, "address is null");
+                CACheckJNIException(env);
                 return CA_STATUS_FAILED;
             }
 
@@ -295,7 +275,7 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeStateChangedCallback(JNIEnv *env, j
     VERIFY_NON_NULL_VOID(env, TAG, "env is null");
     VERIFY_NON_NULL_VOID(obj, TAG, "obj is null");
 
-    OIC_LOG_V(DEBUG, TAG, "CaLeClientInterface - Network State Changed : status(%d)", status);
+    OIC_LOG_V(INFO, TAG, "CaLeClientInterface - Network State Changed : status(%d)", status);
 
     if (!g_bleDeviceStateChangedCallback)
     {
@@ -311,7 +291,11 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeStateChangedCallback(JNIEnv *env, j
     {
         CANetworkStatus_t newStatus = CA_INTERFACE_UP;
         CALEClientCreateDeviceList();
-        CALEServerCreateCachedDeviceList();
+
+        if (!(caglobals.bleFlags & CA_LE_SERVER_DISABLE))
+        {
+            CALEServerCreateCachedDeviceList();
+        }
 
         g_bleDeviceStateChangedCallback(newStatus);
     }
@@ -394,7 +378,7 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeGattNWConnectionStateChangeCallback
                                                                                  jint status,
                                                                                  jint newState)
 {
-    OIC_LOG_V(DEBUG, TAG, "CALeGattNWConnectionStateChangeCallback - status %d, newstate %d",
+    OIC_LOG_V(INFO, TAG, "CALeGattNWConnectionStateChangeCallback - status %d, newstate %d",
               status, newState);
     VERIFY_NON_NULL_VOID(env, TAG, "env");
     VERIFY_NON_NULL_VOID(obj, TAG, "obj");
@@ -415,6 +399,7 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeGattNWConnectionStateChangeCallback
         if (!address)
         {
             OIC_LOG(ERROR, TAG, "address is null");
+            CACheckJNIException(env);
             return;
         }
 
@@ -422,7 +407,7 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeGattNWConnectionStateChangeCallback
         {
             if (g_bleConnectionStateChangedCallback)
             {
-                OIC_LOG_V(DEBUG, TAG, "LE Disconnected state is %d, %s", newState, address);
+                OIC_LOG_V(DEBUG, TAG, "LE Disconnected state is %s", address);
                 g_bleConnectionStateChangedCallback(CA_ADAPTER_GATT_BTLE, address, false);
             }
         }
@@ -456,6 +441,7 @@ Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerNWConnectionStateChangeCa
             if (!address)
             {
                 OIC_LOG(ERROR, TAG, "address is null");
+                CACheckJNIException(env);
                 return;
             }
 
@@ -493,7 +479,7 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeGattNWServicesDiscoveredCallback(JN
                                                                               jobject gatt,
                                                                               jint status)
 {
-    OIC_LOG_V(DEBUG, TAG, "caLeGattNWServicesDiscoveredCallback - status %d", status);
+    OIC_LOG_V(INFO, TAG, "caLeGattNWServicesDiscoveredCallback - status %d", status);
     VERIFY_NON_NULL_VOID(env, TAG, "env");
     VERIFY_NON_NULL_VOID(obj, TAG, "obj");
     VERIFY_NON_NULL_VOID(gatt, TAG, "gatt");
@@ -522,7 +508,7 @@ Java_org_iotivity_ca_CaLeClientInterface_caLeGattNWDescriptorWriteCallback(JNIEn
                                                                            jobject gatt,
                                                                            jint status)
 {
-    OIC_LOG_V(DEBUG, TAG, "caLeGattNWDescriptorWriteCallback - status %d", status);
+    OIC_LOG_V(INFO, TAG, "caLeGattNWDescriptorWriteCallback - status %d", status);
     VERIFY_NON_NULL_VOID(env, TAG, "env");
     VERIFY_NON_NULL_VOID(obj, TAG, "obj");
     VERIFY_NON_NULL_VOID(gatt, TAG, "gatt");
index b722c01..3cbb821 100644 (file)
 #include "caleutils.h"
 #include "caleinterface.h"
 #include "caadapterutils.h"
+#include "calestate.h"
 
 #include "logger.h"
 #include "oic_malloc.h"
 #include "cathreadpool.h"
-#include "camutex.h"
+#include "octhread.h"
 #include "uarraylist.h"
 #include "org_iotivity_ca_CaLeServerInterface.h"
 
@@ -51,6 +52,7 @@ static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
 static CABLEErrorHandleCallback g_serverErrorCallback;
 
 static u_arraylist_t *g_connectedDeviceList = NULL;
+static u_arraylist_t *g_deviceStateList = NULL;
 
 static bool g_isStartServer = false;
 static bool g_isInitializedServer = false;
@@ -59,21 +61,25 @@ static jbyteArray g_sendBuffer = NULL;
 static jobject g_obj_bluetoothDevice = NULL;
 
 static CABLEDataReceivedCallback g_CABLEServerDataReceivedCallback = NULL;
-static ca_mutex g_bleReqRespCbMutex = NULL;
-static ca_mutex g_bleClientBDAddressMutex = NULL;
-static ca_mutex g_connectedDeviceListMutex = NULL;
+static oc_mutex g_bleReqRespCbMutex = NULL;
+static oc_mutex g_bleClientBDAddressMutex = NULL;
+static oc_mutex g_connectedDeviceListMutex = NULL;
 
-static ca_mutex g_threadSendMutex = NULL;
-static ca_mutex g_threadSendNotifyMutex = NULL;
-static ca_cond g_threadSendNotifyCond = NULL;
+static oc_mutex g_threadSendMutex = NULL;
+static oc_mutex g_threadSendNotifyMutex = NULL;
+static oc_cond g_threadSendNotifyCond = NULL;
 static bool g_isSignalSetFlag = false;
 
+static oc_mutex g_deviceStateListMutex = NULL;
+
 static jint g_state_connected = INVALID_STATE;
 static jint g_state_disconnected = INVALID_STATE;
 
 static const char CLASSPATH_BT_ADVERTISE_CB[] = "android/bluetooth/le/AdvertiseCallback";
 static const char CLASSPATH_BT_GATTSERVER[] = "android/bluetooth/BluetoothGattServer";
 
+static bool g_setHighQoS = true;
+
 void CALEServerJNISetContext()
 {
     OIC_LOG(DEBUG, TAG, "CALEServerJNISetContext");
@@ -186,6 +192,12 @@ static jint CALEServerGetConnectionState(JNIEnv *env, jobject device)
     jint jni_state = (jint)(*env)->CallIntMethod(env, g_bluetoothManager,
                                                  jni_mid_getConnectionState,
                                                  device, GATT_PROFILE);
+    if (CACheckJNIException(env))
+    {
+        OIC_LOG(ERROR, TAG, "getConnectionState has failed");
+        return -1;
+    }
+
     OIC_LOG_V(INFO, TAG, "connection state is %d", jni_state);
     return jni_state;
 }
@@ -232,6 +244,7 @@ jobject CALEServerSetResponseData(JNIEnv *env, jbyteArray responseData)
     if (!jni_obj_bluetoothGattService)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattService is null");
+        CACheckJNIException(env);
         return NULL;
     }
 
@@ -260,6 +273,7 @@ jobject CALEServerSetResponseData(JNIEnv *env, jbyteArray responseData)
     if (!jni_obj_bluetoothGattCharacteristic)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattCharacteristic is null");
+        CACheckJNIException(env);
         return NULL;
     }
 
@@ -278,6 +292,7 @@ jobject CALEServerSetResponseData(JNIEnv *env, jbyteArray responseData)
     if (JNI_FALSE == jni_boolean_setValue)
     {
         OIC_LOG(ERROR, TAG, "Fail to set response data");
+        CACheckJNIException(env);
     }
 
     OIC_LOG(DEBUG, TAG, "OUT - CALEServerSetResponseData");
@@ -329,25 +344,26 @@ CAResult_t CALEServerSendResponseData(JNIEnv *env, jobject device, jobject respo
     if (JNI_FALSE == jni_boolean_notifyCharacteristicChanged)
     {
         OIC_LOG(ERROR, TAG, "Fail to notify characteristic");
+        CACheckJNIException(env);
         return CA_SEND_FAILED;
     }
 
     OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
-    ca_mutex_lock(g_threadSendNotifyMutex);
+    oc_mutex_lock(g_threadSendNotifyMutex);
     if (!g_isSignalSetFlag)
     {
         OIC_LOG(DEBUG, TAG, "wait for callback to notify notifyCharacteristic is success");
-        if (0 != ca_cond_wait_for(g_threadSendNotifyCond, g_threadSendNotifyMutex,
+        if (0 != oc_cond_wait_for(g_threadSendNotifyCond, g_threadSendNotifyMutex,
                                   WAIT_TIME_WRITE_CHARACTERISTIC))
         {
             OIC_LOG(ERROR, TAG, "there is no response. notifyCharacteristic has failed");
-            ca_mutex_unlock(g_threadSendNotifyMutex);
+            oc_mutex_unlock(g_threadSendNotifyMutex);
             return CA_STATUS_FAILED;
         }
     }
     // reset flag set by writeCharacteristic Callback
     g_isSignalSetFlag = false;
-    ca_mutex_unlock(g_threadSendNotifyMutex);
+    oc_mutex_unlock(g_threadSendNotifyMutex);
     OIC_LOG(INFO, TAG, "notifyCharacteristic success");
     return CA_STATUS_OK;
 }
@@ -391,6 +407,7 @@ CAResult_t CALEServerSendResponse(JNIEnv *env, jobject device, jint requestId, j
     if (JNI_FALSE == jni_boolean_sendResponse)
     {
         OIC_LOG(ERROR, TAG, "Fail to send response for gatt characteristic write request");
+        CACheckJNIException(env);
         return CA_SEND_FAILED;
     }
 
@@ -398,8 +415,15 @@ CAResult_t CALEServerSendResponse(JNIEnv *env, jobject device, jint requestId, j
     return CA_STATUS_OK;
 }
 
-CAResult_t CALEStartAdvertise()
+CAResult_t CALEServerStartAdvertise()
 {
+    if ((caglobals.bleFlags & CA_LE_ADV_DISABLE) || CA_DEFAULT_BT_FLAGS == caglobals.bleFlags)
+    {
+        OIC_LOG_V(INFO, TAG, "the advertisement of the bleFlags is disable[%d]",
+                  caglobals.bleFlags);
+        return CA_STATUS_OK;
+    }
+
     if (!g_jvm)
     {
         OIC_LOG(ERROR, TAG, "g_jvm is null");
@@ -423,10 +447,10 @@ CAResult_t CALEStartAdvertise()
     }
 
     // start advertise
-    CAResult_t ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
+    CAResult_t ret = CALEServerStartAdvertiseImpl(env, g_leAdvertiseCallback);
     if (CA_STATUS_OK != ret)
     {
-        OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
+        OIC_LOG(ERROR, TAG, "CALEServerStartAdvertiseImpl has failed");
     }
 
     if (isAttached)
@@ -436,9 +460,9 @@ CAResult_t CALEStartAdvertise()
     return ret;
 }
 
-CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
+CAResult_t CALEServerStartAdvertiseImpl(JNIEnv *env, jobject advertiseCallback)
 {
-    OIC_LOG(DEBUG, TAG, "IN - CALEServerStartAdvertise");
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerStartAdvertiseImpl");
     VERIFY_NON_NULL(env, TAG, "env is null");
     VERIFY_NON_NULL(advertiseCallback, TAG, "advertiseCallback is null");
 
@@ -454,7 +478,7 @@ CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_cid_AdvertiseSettings)
     {
         OIC_LOG(ERROR, TAG, "jni_cid_AdvertiseSettings is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jmethodID jni_mid_AdvertiseSettings = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
@@ -462,7 +486,7 @@ CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_mid_AdvertiseSettings)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_AdvertiseSettings is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jobject jni_AdvertiseSettings = (*env)->NewObject(env, jni_cid_AdvertiseSettings,
@@ -470,7 +494,7 @@ CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_AdvertiseSettings)
     {
         OIC_LOG(ERROR, TAG, "jni_AdvertiseSettings is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jmethodID jni_mid_setAdvertiseMode = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
@@ -480,7 +504,7 @@ CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_mid_setAdvertiseMode)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_setAdvertiseMode is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     // 0: Low power, 1: Balanced
@@ -489,7 +513,7 @@ CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_obj_setAdvertiseMode)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_setAdvertiseMode is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jmethodID jni_mid_setConnectable = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
@@ -499,7 +523,7 @@ CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_mid_setConnectable)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_setConnectable is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jobject jni_obj_setConnectable = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
@@ -507,7 +531,7 @@ CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_obj_setConnectable)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_setConnectable is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jmethodID jni_mid_setTimeout = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings, "setTimeout",
@@ -516,7 +540,7 @@ CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_mid_setTimeout)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_setTimeout is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     //A value of 0 will disable the time limit
@@ -525,7 +549,7 @@ CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_obj_setTimeout)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_setTimeout is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jclass jni_cid_AdvertiseDataBuilder = (*env)->FindClass(env,
@@ -534,7 +558,7 @@ CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_cid_AdvertiseDataBuilder)
     {
         OIC_LOG(ERROR, TAG, "jni_cid_AdvertiseDataBuilder is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jmethodID jni_mid_AdvertiseDataBuilder = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
@@ -542,7 +566,7 @@ CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_mid_AdvertiseDataBuilder)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_AdvertiseDataBuilder is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jobject jni_AdvertiseDataBuilder = (*env)->NewObject(env, jni_cid_AdvertiseDataBuilder,
@@ -550,7 +574,7 @@ CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_AdvertiseDataBuilder)
     {
         OIC_LOG(ERROR, TAG, "jni_AdvertiseDataBuilder is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jobject jni_AdvertiseDataBuilderForScanRsp = (*env)->NewObject(env,
@@ -559,7 +583,7 @@ CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_AdvertiseDataBuilderForScanRsp)
     {
         OIC_LOG(ERROR, TAG, "jni_AdvertiseDataBuilderForScanRsp is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
@@ -583,7 +607,7 @@ CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_mid_addServiceUuid)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_addServiceUuid is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jobject jni_obj_addServiceUuid = (*env)->CallObjectMethod(env, jni_AdvertiseDataBuilder,
@@ -592,7 +616,7 @@ CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_obj_addServiceUuid)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_addServiceUuid is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     // Device name has to be included in advertise packet after Android API 23
@@ -605,7 +629,7 @@ CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_mid_setIncludeDeviceName)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_setIncludeDeviceName is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jobject jni_obj_setIncludeDeviceName  = (*env)->CallObjectMethod(env,
@@ -615,7 +639,7 @@ CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_obj_setIncludeDeviceName)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_setIncludeDeviceName is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jclass jni_cid_BTAdapter = (*env)->FindClass(env, "android/bluetooth/BluetoothAdapter");
@@ -632,7 +656,7 @@ CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_mid_getDefaultAdapter)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
@@ -640,7 +664,7 @@ CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_obj_BTAdapter)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jmethodID jni_mid_getBluetoothLeAdvertiser = (*env)->GetMethodID(env, jni_cid_BTAdapter,
@@ -650,7 +674,7 @@ CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_mid_getBluetoothLeAdvertiser)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_getBluetoothLeAdvertiser is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jobject jni_obj_getBluetoothLeAdvertiser = (*env)->CallObjectMethod(
@@ -658,7 +682,7 @@ CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_obj_getBluetoothLeAdvertiser)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_getBluetoothLeAdvertiser is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jmethodID jni_mid_build_LeAdvertiseSettings = (*env)->GetMethodID(env,
@@ -669,7 +693,7 @@ CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_mid_build_LeAdvertiseSettings)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_build_LeAdvertiseSettings is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jobject jni_obj_build_LeAdvertiseSettings = (*env)->CallObjectMethod(
@@ -677,7 +701,7 @@ CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_obj_build_LeAdvertiseSettings)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_build_LeAdvertiseSettings is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jmethodID jni_mid_build_LeAdvertiseData = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
@@ -687,7 +711,7 @@ CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_mid_build_LeAdvertiseData)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_build_LeAdvertiseData is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jobject jni_obj_build_LeAdvertiseData = (*env)->CallObjectMethod(env, jni_AdvertiseDataBuilder,
@@ -695,7 +719,7 @@ CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_obj_build_LeAdvertiseData)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_build_LeAdvertiseData is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jobject jni_obj_build_LeAdvertiseDataForScanRsp = (*env)->CallObjectMethod(env,
@@ -704,7 +728,7 @@ CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_obj_build_LeAdvertiseDataForScanRsp)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_build_LeAdvertiseDataForScanRsp is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jmethodID jni_mid_startAdvertising = CAGetJNIMethodID(env, "android/bluetooth/le/"
@@ -724,24 +748,62 @@ CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback)
     (*env)->CallVoidMethod(env, jni_obj_getBluetoothLeAdvertiser, jni_mid_startAdvertising,
                            jni_obj_build_LeAdvertiseSettings, jni_obj_build_LeAdvertiseData,
                            jni_obj_build_LeAdvertiseDataForScanRsp, advertiseCallback);
-
-    if ((*env)->ExceptionCheck(env))
+    if (CACheckJNIException(env))
     {
         OIC_LOG(ERROR, TAG, "StartAdvertising has failed");
-        (*env)->ExceptionDescribe(env);
-        (*env)->ExceptionClear(env);
         return CA_STATUS_FAILED;
     }
 
     OIC_LOG(DEBUG, TAG, "Advertising started!!");
-
     OIC_LOG(DEBUG, TAG, "OUT - CALEServerStartAdvertise");
     return CA_STATUS_OK;
+
+error_exit:
+    CACheckJNIException(env);
+    return CA_STATUS_FAILED;
 }
 
-CAResult_t CALEServerStopAdvertise(JNIEnv *env, jobject advertiseCallback)
+CAResult_t CALEServerStopAdvertise()
 {
-    OIC_LOG(DEBUG, TAG, "LEServerStopAdvertise");
+    if (!g_jvm)
+    {
+        OIC_LOG(ERROR, TAG, "g_jvm is null");
+        return CA_STATUS_FAILED;
+    }
+
+    bool isAttached = false;
+    JNIEnv* env = NULL;
+    jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
+    if (JNI_OK != res)
+    {
+        OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
+        res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
+
+        if (JNI_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
+            return CA_STATUS_FAILED;
+        }
+        isAttached = true;
+    }
+
+    CAResult_t ret = CALEServerStopAdvertiseImpl(env, g_leAdvertiseCallback);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEServerStopAdvertise has failed");
+    }
+
+    if (isAttached)
+    {
+        (*g_jvm)->DetachCurrentThread(g_jvm);
+    }
+
+    return ret;
+}
+
+CAResult_t CALEServerStopAdvertiseImpl(JNIEnv *env, jobject advertiseCallback)
+{
+    OIC_LOG(DEBUG, TAG, "CALEServerStopAdvertiseImpl");
     VERIFY_NON_NULL(env, TAG, "env is null");
     VERIFY_NON_NULL(advertiseCallback, TAG, "advertiseCallback is null");
 
@@ -755,7 +817,7 @@ CAResult_t CALEServerStopAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_cid_BTAdapter)
     {
         OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
@@ -765,7 +827,7 @@ CAResult_t CALEServerStopAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_mid_getDefaultAdapter)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jmethodID jni_mid_getBTLeAdvertiser = (*env)->GetMethodID(env, jni_cid_BTAdapter,
@@ -775,7 +837,7 @@ CAResult_t CALEServerStopAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_mid_getBTLeAdvertiser)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_getBTLeAdvertiser is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jmethodID jni_mid_stopAdvertising = CAGetJNIMethodID(env, "android/bluetooth/le/"
@@ -786,7 +848,7 @@ CAResult_t CALEServerStopAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_mid_stopAdvertising)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_stopAdvertising is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
@@ -794,7 +856,7 @@ CAResult_t CALEServerStopAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_obj_BTAdapter)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jobject jni_obj_getBluetoothLeAdvertiser = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
@@ -802,21 +864,23 @@ CAResult_t CALEServerStopAdvertise(JNIEnv *env, jobject advertiseCallback)
     if (!jni_obj_getBluetoothLeAdvertiser)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_getBluetoothLeAdvertiser is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     (*env)->CallVoidMethod(env, jni_obj_getBluetoothLeAdvertiser, jni_mid_stopAdvertising,
                            advertiseCallback);
-    if ((*env)->ExceptionCheck(env))
+    if (CACheckJNIException(env))
     {
         OIC_LOG(ERROR, TAG, "getBluetoothLeAdvertiser has failed");
-        (*env)->ExceptionDescribe(env);
-        (*env)->ExceptionClear(env);
         return CA_STATUS_FAILED;
     }
 
     OIC_LOG(DEBUG, TAG, "Advertising stopped!!");
     return CA_STATUS_OK;
+
+error_exit:
+    CACheckJNIException(env);
+    return CA_STATUS_FAILED;
 }
 
 CAResult_t CALEServerStartGattServer(JNIEnv *env, jobject gattServerCallback)
@@ -879,14 +943,14 @@ jobject CALEServerOpenGattServer(JNIEnv *env)
     if (!CALEIsEnableBTAdapter(env))
     {
         OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
-        return NULL;
+        goto error_exit;
     }
 
     jclass jni_cid_context = (*env)->FindClass(env, "android/content/Context");
     if (!jni_cid_context)
     {
         OIC_LOG(ERROR, TAG, "jni_cid_context is null");
-        return NULL;
+        goto error_exit;
     }
 
     jfieldID jni_fid_bluetoothService = (*env)->GetStaticFieldID(env, jni_cid_context,
@@ -895,7 +959,7 @@ jobject CALEServerOpenGattServer(JNIEnv *env)
     if (!jni_fid_bluetoothService)
     {
         OIC_LOG(ERROR, TAG, "jni_fid_bluetoothService is null");
-        return NULL;
+        goto error_exit;
     }
 
     jmethodID jni_mid_getSystemService = (*env)->GetMethodID(env, jni_cid_context,
@@ -905,7 +969,7 @@ jobject CALEServerOpenGattServer(JNIEnv *env)
     if (!jni_mid_getSystemService)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_getSystemService is null");
-        return NULL;
+        goto error_exit;
     }
 
     jmethodID jni_mid_openGattServer = CAGetJNIMethodID(env, "android/bluetooth/"
@@ -927,7 +991,7 @@ jobject CALEServerOpenGattServer(JNIEnv *env)
     if (!jni_obj_bluetoothService)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_bluetoothService is null");
-        return NULL;
+        goto error_exit;
     }
 
     jobject jni_obj_bluetoothManager = (*env)->CallObjectMethod(env, g_context,
@@ -936,7 +1000,7 @@ jobject CALEServerOpenGattServer(JNIEnv *env)
     if (!jni_obj_bluetoothManager)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_bluetoothManager is null");
-        return NULL;
+        goto error_exit;
     }
 
     if (g_bluetoothManager)
@@ -952,11 +1016,15 @@ jobject CALEServerOpenGattServer(JNIEnv *env)
     if (!jni_obj_bluetoothGattServer)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_bluetoothGattServer is null");
-        return NULL;
+        goto error_exit;
     }
 
     OIC_LOG(DEBUG, TAG, "OUT - CALEServerOpenGattServer");
     return jni_obj_bluetoothGattServer;
+
+error_exit:
+    CACheckJNIException(env);
+    return NULL;
 }
 
 jobject CALEServerCreateGattService(JNIEnv *env)
@@ -975,7 +1043,7 @@ jobject CALEServerCreateGattService(JNIEnv *env)
     if (!jni_cid_bluetoothGattService)
     {
         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattService is null");
-        return NULL;
+        goto error_exit;
     }
 
     jclass jni_cid_bluetoothGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
@@ -983,7 +1051,7 @@ jobject CALEServerCreateGattService(JNIEnv *env)
     if (!jni_cid_bluetoothGattCharacteristic)
     {
         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattCharacteristic is null");
-        return NULL;
+        goto error_exit;
     }
 
     jfieldID jni_fid_serviceType = (*env)->GetStaticFieldID(env, jni_cid_bluetoothGattService,
@@ -991,25 +1059,50 @@ jobject CALEServerCreateGattService(JNIEnv *env)
     if (!jni_fid_serviceType)
     {
         OIC_LOG(ERROR, TAG, "jni_fid_serviceType is null");
-        return NULL;
+        goto error_exit;
     }
 
-    jfieldID jni_fid_readProperties = (*env)->GetStaticFieldID(env,
-                                                               jni_cid_bluetoothGattCharacteristic,
-                                                               "PROPERTY_NOTIFY", "I");
-    if (!jni_fid_readProperties)
+    jfieldID jni_fid_readProperties = NULL;
+    jfieldID jni_fid_writeProperties = NULL;
+    if (g_setHighQoS)
     {
-        OIC_LOG(ERROR, TAG, "jni_fid_readProperties is null");
-        return NULL;
-    }
+        jni_fid_readProperties = (*env)->GetStaticFieldID(env,
+                                                          jni_cid_bluetoothGattCharacteristic,
+                                                          "PROPERTY_INDICATE", "I");
+        if (!jni_fid_readProperties)
+        {
+            OIC_LOG(ERROR, TAG, "jni_fid_readProperties is null");
+            goto error_exit;
+        }
 
-    jfieldID jni_fid_writeProperties = (*env)->GetStaticFieldID(env,
-                                                                jni_cid_bluetoothGattCharacteristic,
-                                                                "PROPERTY_WRITE_NO_RESPONSE", "I");
-    if (!jni_fid_writeProperties)
+        jni_fid_writeProperties = (*env)->GetStaticFieldID(env,
+                                                           jni_cid_bluetoothGattCharacteristic,
+                                                           "PROPERTY_WRITE", "I");
+        if (!jni_fid_writeProperties)
+        {
+            OIC_LOG(ERROR, TAG, "jni_fid_writeProperties is null");
+            goto error_exit;
+        }
+    }
+    else
     {
-        OIC_LOG(ERROR, TAG, "jni_fid_writeProperties is null");
-        return NULL;
+        jni_fid_readProperties = (*env)->GetStaticFieldID(env,
+                                                          jni_cid_bluetoothGattCharacteristic,
+                                                          "PROPERTY_NOTIFY", "I");
+        if (!jni_fid_readProperties)
+        {
+            OIC_LOG(ERROR, TAG, "jni_fid_readProperties is null");
+            goto error_exit;
+        }
+
+        jni_fid_writeProperties = (*env)->GetStaticFieldID(env,
+                                                           jni_cid_bluetoothGattCharacteristic,
+                                                           "PROPERTY_WRITE_NO_RESPONSE", "I");
+        if (!jni_fid_writeProperties)
+        {
+            OIC_LOG(ERROR, TAG, "jni_fid_writeProperties is null");
+            goto error_exit;
+        }
     }
 
     jfieldID jni_fid_readPermissions = (*env)->GetStaticFieldID(env,
@@ -1018,7 +1111,7 @@ jobject CALEServerCreateGattService(JNIEnv *env)
     if (!jni_fid_readPermissions)
     {
         OIC_LOG(ERROR, TAG, "jni_fid_readPermissions is null");
-        return NULL;
+        goto error_exit;
     }
 
     jfieldID jni_fid_writePermissions = (*env)->GetStaticFieldID(
@@ -1026,7 +1119,7 @@ jobject CALEServerCreateGattService(JNIEnv *env)
     if (!jni_fid_writePermissions)
     {
         OIC_LOG(ERROR, TAG, "jni_fid_writePermissions is null");
-        return NULL;
+        goto error_exit;
     }
 
     jmethodID jni_mid_bluetoothGattService = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
@@ -1034,7 +1127,7 @@ jobject CALEServerCreateGattService(JNIEnv *env)
     if (!jni_mid_bluetoothGattService)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattService is null");
-        return NULL;
+        goto error_exit;
     }
 
     jmethodID jni_mid_addCharacteristic = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
@@ -1044,7 +1137,7 @@ jobject CALEServerCreateGattService(JNIEnv *env)
     if (!jni_mid_addCharacteristic)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_addCharacteristic is null");
-        return NULL;
+        goto error_exit;
     }
 
     jmethodID jni_mid_bluetoothGattCharacteristic = (*env)->GetMethodID(
@@ -1052,7 +1145,7 @@ jobject CALEServerCreateGattService(JNIEnv *env)
     if (!jni_mid_bluetoothGattCharacteristic)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattCharacteristic is null");
-        return NULL;
+        goto error_exit;
     }
 
     jobject jni_obj_serviceUUID = CALEGetUuidFromString(env, OIC_GATT_SERVICE_UUID);
@@ -1070,7 +1163,7 @@ jobject CALEServerCreateGattService(JNIEnv *env)
     if (!jni_bluetoothGattService)
     {
         OIC_LOG(ERROR, TAG, "jni_bluetoothGattService is null");
-        return NULL;
+        goto error_exit;
     }
 
     jobject jni_obj_readUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
@@ -1083,14 +1176,17 @@ jobject CALEServerCreateGattService(JNIEnv *env)
     jint jni_int_readProperties = (*env)->GetStaticIntField(env,
                                                             jni_cid_bluetoothGattCharacteristic,
                                                             jni_fid_readProperties);
+    CACheckJNIException(env);
 
     jint jni_int_readPermissions = (*env)->GetStaticIntField(env,
                                                              jni_cid_bluetoothGattCharacteristic,
                                                              jni_fid_readPermissions);
+    CACheckJNIException(env);
 
     jint jni_int_writePermissions = (*env)->GetStaticIntField(env,
                                                               jni_cid_bluetoothGattCharacteristic,
                                                               jni_fid_writePermissions);
+    CACheckJNIException(env);
 
     jobject jni_readCharacteristic = (*env)->NewObject(env, jni_cid_bluetoothGattCharacteristic,
                                                        jni_mid_bluetoothGattCharacteristic,
@@ -1100,7 +1196,7 @@ jobject CALEServerCreateGattService(JNIEnv *env)
     if (!jni_readCharacteristic)
     {
         OIC_LOG(ERROR, TAG, "jni_readCharacteristic is null");
-        return NULL;
+        goto error_exit;
     }
 
     jboolean jni_boolean_addReadCharacteristic = (*env)->CallBooleanMethod(
@@ -1108,7 +1204,7 @@ jobject CALEServerCreateGattService(JNIEnv *env)
     if (!jni_boolean_addReadCharacteristic)
     {
         OIC_LOG(ERROR, TAG, "jni_boolean_addReadCharacteristic is null");
-        return NULL;
+        goto error_exit;
     }
 
     jobject jni_obj_writeUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
@@ -1121,6 +1217,7 @@ jobject CALEServerCreateGattService(JNIEnv *env)
     jint jni_int_writeProperties = (*env)->GetStaticIntField(env,
                                                              jni_cid_bluetoothGattCharacteristic,
                                                              jni_fid_writeProperties);
+    CACheckJNIException(env);
 
     jobject jni_writeCharacteristic = (*env)->NewObject(env, jni_cid_bluetoothGattCharacteristic,
                                                         jni_mid_bluetoothGattCharacteristic,
@@ -1129,7 +1226,7 @@ jobject CALEServerCreateGattService(JNIEnv *env)
     if (!jni_writeCharacteristic)
     {
         OIC_LOG(ERROR, TAG, "jni_writeCharacteristic is null");
-        return NULL;
+        goto error_exit;
     }
 
     jboolean jni_boolean_addWriteCharacteristic = (*env)->CallBooleanMethod(
@@ -1137,11 +1234,15 @@ jobject CALEServerCreateGattService(JNIEnv *env)
     if (JNI_FALSE == jni_boolean_addWriteCharacteristic)
     {
         OIC_LOG(ERROR, TAG, "Fail to add jni_boolean_addReadCharacteristic");
-        return NULL;
+        goto error_exit;
     }
 
     OIC_LOG(DEBUG, TAG, "OUT - CALEServerCreateGattService");
     return jni_bluetoothGattService;
+
+error_exit:
+    CACheckJNIException(env);
+    return NULL;
 }
 
 CAResult_t CALEServerAddDescriptor(JNIEnv *env, jobject characteristic)
@@ -1155,7 +1256,7 @@ CAResult_t CALEServerAddDescriptor(JNIEnv *env, jobject characteristic)
     if (!jni_cid_bluetoothGattDescriptor)
     {
         OIC_LOG(ERROR, TAG, "jni_cid_bluetoothGattDescriptor is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jmethodID jni_mid_bluetoothGattDescriptor = (*env)->GetMethodID(env,
@@ -1165,7 +1266,7 @@ CAResult_t CALEServerAddDescriptor(JNIEnv *env, jobject characteristic)
     if (!jni_mid_bluetoothGattDescriptor)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_bluetoothGattDescriptor is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jfieldID jni_fid_readPermissions = (*env)->GetStaticFieldID(env,
@@ -1174,7 +1275,7 @@ CAResult_t CALEServerAddDescriptor(JNIEnv *env, jobject characteristic)
     if (!jni_fid_readPermissions)
     {
         OIC_LOG(ERROR, TAG, "jni_fid_readPermissions is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jobject jni_obj_readUuid = CALEGetUuidFromString(env, OIC_GATT_CHARACTERISTIC_CONFIG_UUID);
@@ -1186,6 +1287,7 @@ CAResult_t CALEServerAddDescriptor(JNIEnv *env, jobject characteristic)
 
     jint jni_int_readPermissions = (*env)->GetStaticIntField(env, jni_cid_bluetoothGattDescriptor,
                                                              jni_fid_readPermissions);
+    CACheckJNIException(env);
 
     OIC_LOG(DEBUG, TAG, "initialize new Descriptor");
 
@@ -1195,7 +1297,7 @@ CAResult_t CALEServerAddDescriptor(JNIEnv *env, jobject characteristic)
     if (!jni_readDescriptor)
     {
         OIC_LOG(ERROR, TAG, "jni_readDescriptor is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jclass jni_cid_GattCharacteristic = (*env)->FindClass(env, "android/bluetooth/"
@@ -1203,7 +1305,7 @@ CAResult_t CALEServerAddDescriptor(JNIEnv *env, jobject characteristic)
     if (!jni_cid_GattCharacteristic)
     {
         OIC_LOG(ERROR, TAG, "jni_cid_GattCharacteristic is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jmethodID jni_mid_addDescriptor = (*env)->GetMethodID(env, jni_cid_GattCharacteristic,
@@ -1213,7 +1315,7 @@ CAResult_t CALEServerAddDescriptor(JNIEnv *env, jobject characteristic)
     if (!jni_mid_addDescriptor)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_addDescriptor is null");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
 
     jboolean jni_boolean_addDescriptor = (*env)->CallBooleanMethod(env, characteristic,
@@ -1223,13 +1325,17 @@ CAResult_t CALEServerAddDescriptor(JNIEnv *env, jobject characteristic)
     if (JNI_FALSE == jni_boolean_addDescriptor)
     {
         OIC_LOG(ERROR, TAG, "addDescriptor has failed");
-        return CA_STATUS_FAILED;
+        goto error_exit;
     }
     else
     {
         OIC_LOG(DEBUG, TAG, "addDescriptor success");
     }
     return CA_STATUS_OK;
+
+error_exit:
+    CACheckJNIException(env);
+    return CA_STATUS_FAILED;
 }
 
 CAResult_t CALEServerAddGattService(JNIEnv *env, jobject bluetoothGattServer,
@@ -1263,6 +1369,7 @@ CAResult_t CALEServerAddGattService(JNIEnv *env, jobject bluetoothGattServer,
     if (JNI_FALSE == jni_boolean_addService)
     {
         OIC_LOG(ERROR, TAG, "Fail to add GATT service");
+        CACheckJNIException(env);
         return CA_STATUS_FAILED;
     }
 
@@ -1297,6 +1404,7 @@ CAResult_t CALEServerConnect(JNIEnv *env, jobject bluetoothDevice)
     if (JNI_FALSE == jni_boolean_connect)
     {
         OIC_LOG(ERROR, TAG, "Fail to connect");
+        CACheckJNIException(env);
         return CA_STATUS_FAILED;
     }
 
@@ -1309,11 +1417,11 @@ CAResult_t CALEServerDisconnectAllDevices(JNIEnv *env)
     OIC_LOG(DEBUG, TAG, "IN - CALEServerDisconnectAllDevices");
     VERIFY_NON_NULL(env, TAG, "env is null");
 
-    ca_mutex_lock(g_connectedDeviceListMutex);
+    oc_mutex_lock(g_connectedDeviceListMutex);
     if (!g_connectedDeviceList)
     {
         OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
-        ca_mutex_unlock(g_connectedDeviceListMutex);
+        oc_mutex_unlock(g_connectedDeviceListMutex);
         return CA_STATUS_FAILED;
     }
 
@@ -1336,7 +1444,7 @@ CAResult_t CALEServerDisconnectAllDevices(JNIEnv *env)
         }
     }
 
-    ca_mutex_unlock(g_connectedDeviceListMutex);
+    oc_mutex_unlock(g_connectedDeviceListMutex);
     OIC_LOG(DEBUG, TAG, "OUT - CALEServerDisconnectAllDevices");
     return CA_STATUS_OK;
 }
@@ -1365,11 +1473,9 @@ CAResult_t CALEServerDisconnect(JNIEnv *env, jobject bluetoothDevice)
 
     (*env)->CallVoidMethod(env, g_bluetoothGattServer, jni_mid_cancelConnection, bluetoothDevice);
 
-    if ((*env)->ExceptionCheck(env))
+    if (CACheckJNIException(env))
     {
         OIC_LOG(ERROR, TAG, "cancelConnection has failed");
-        (*env)->ExceptionDescribe(env);
-        (*env)->ExceptionClear(env);
         return CA_STATUS_FAILED;
     }
 
@@ -1398,11 +1504,9 @@ CAResult_t CALEServerGattClose(JNIEnv *env, jobject bluetoothGattServer)
     OIC_LOG(DEBUG, TAG, "request to close GATT");
     (*env)->CallVoidMethod(env, bluetoothGattServer, jni_mid_closeGatt);
 
-    if ((*env)->ExceptionCheck(env))
+    if (CACheckJNIException(env))
     {
         OIC_LOG(ERROR, TAG, "closeGATT has failed");
-        (*env)->ExceptionDescribe(env);
-        (*env)->ExceptionClear(env);
         return CA_STATUS_FAILED;
     }
 
@@ -1480,7 +1584,7 @@ CAResult_t CALEServerInitialize()
         return ret;
     }
 
-    g_threadSendNotifyCond = ca_cond_new();
+    g_threadSendNotifyCond = oc_cond_new();
 
     ret = CALEServerInitMutexVaraibles();
     if (CA_STATUS_OK != ret)
@@ -1557,7 +1661,7 @@ void CALEServerTerminate()
         g_bluetoothManager = NULL;
     }
 
-    ca_cond_free(g_threadSendNotifyCond);
+    oc_cond_free(g_threadSendNotifyCond);
     g_threadSendNotifyCond = NULL;
 
     CALEServerTerminateMutexVaraibles();
@@ -1705,7 +1809,7 @@ CAResult_t CALEServerStartMulticastServer()
     }
 
     // start advertise
-    ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
+    ret = CALEServerStartAdvertise();
     if (CA_STATUS_OK != ret)
     {
         OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
@@ -1734,29 +1838,7 @@ CAResult_t CALEServerStopMulticastServer()
         return CA_STATUS_FAILED;
     }
 
-    if (!g_jvm)
-    {
-        OIC_LOG(ERROR, TAG, "g_jvm is null");
-        return CA_STATUS_FAILED;
-    }
-
-    bool isAttached = false;
-    JNIEnv* env = NULL;
-    jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
-    if (JNI_OK != res)
-    {
-        OIC_LOG(INFO, TAG, "Could not get JNIEnv pointer");
-        res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
-
-        if (JNI_OK != res)
-        {
-            OIC_LOG(ERROR, TAG, "AttachCurrentThread has failed");
-            return CA_STATUS_FAILED;
-        }
-        isAttached = true;
-    }
-
-    CAResult_t ret = CALEServerStopAdvertise(env, g_leAdvertiseCallback);
+    CAResult_t ret = CALEServerStopAdvertise();
     if (CA_STATUS_OK != ret)
     {
         OIC_LOG(ERROR, TAG, "CALEServerStopAdvertise has failed");
@@ -1764,11 +1846,6 @@ CAResult_t CALEServerStopMulticastServer()
 
     g_isStartServer = false;
 
-    if (isAttached)
-    {
-        (*g_jvm)->DetachCurrentThread(g_jvm);
-    }
-
     OIC_LOG(DEBUG, TAG, "OUT - CALEServerStopMulticastServer");
     return ret;
 }
@@ -1794,7 +1871,7 @@ CAResult_t CALEServerSendUnicastMessageImpl(JNIEnv *env, const char* address, co
         return CA_STATUS_FAILED;
     }
 
-    ca_mutex_lock(g_threadSendMutex);
+    oc_mutex_lock(g_threadSendMutex);
 
     uint32_t length = u_arraylist_length(g_connectedDeviceList);
     for (uint32_t index = 0; index < length; index++)
@@ -1823,7 +1900,7 @@ CAResult_t CALEServerSendUnicastMessageImpl(JNIEnv *env, const char* address, co
         OIC_LOG_V(DEBUG, TAG, "setAddress : %s", setAddress);
         OIC_LOG_V(DEBUG, TAG, "address : %s", address);
 
-        if (!strcmp(setAddress, address))
+        if (!strcasecmp(setAddress, address))
         {
             OIC_LOG(DEBUG, TAG, "found the device");
 
@@ -1836,6 +1913,7 @@ CAResult_t CALEServerSendUnicastMessageImpl(JNIEnv *env, const char* address, co
             if (jarrayObj)
             {
                 g_obj_bluetoothDevice = (*env)->NewGlobalRef(env, jarrayObj);
+                CACheckJNIException(env);
             }
             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
             break;
@@ -1846,8 +1924,11 @@ CAResult_t CALEServerSendUnicastMessageImpl(JNIEnv *env, const char* address, co
     if (g_obj_bluetoothDevice)
     {
         jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
+        CACheckJNIException(env);
         (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
+        CACheckJNIException(env);
         g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
+        CACheckJNIException(env);
 
         CAResult_t res = CALEServerSend(env, g_obj_bluetoothDevice, g_sendBuffer);
         if (CA_STATUS_OK != res)
@@ -1868,7 +1949,7 @@ CAResult_t CALEServerSendUnicastMessageImpl(JNIEnv *env, const char* address, co
         g_sendBuffer = NULL;
     }
 
-    ca_mutex_unlock(g_threadSendMutex);
+    oc_mutex_unlock(g_threadSendMutex);
     OIC_LOG(INFO, TAG, "unicast - send request is successful");
     return CA_STATUS_OK;
 
@@ -1885,7 +1966,7 @@ error_exit:
         g_obj_bluetoothDevice = NULL;
     }
 
-    ca_mutex_unlock(g_threadSendMutex);
+    oc_mutex_unlock(g_threadSendMutex);
     return CA_SEND_FAILED;
 }
 
@@ -1901,7 +1982,7 @@ CAResult_t CALEServerSendMulticastMessageImpl(JNIEnv *env, const uint8_t *data,
         return CA_STATUS_FAILED;
     }
 
-    ca_mutex_lock(g_threadSendMutex);
+    oc_mutex_lock(g_threadSendMutex);
 
     OIC_LOG(DEBUG, TAG, "set data into g_sendBuffer for notify");
     if (g_sendBuffer)
@@ -1910,8 +1991,11 @@ CAResult_t CALEServerSendMulticastMessageImpl(JNIEnv *env, const uint8_t *data,
         g_sendBuffer = NULL;
     }
     jbyteArray jni_arr = (*env)->NewByteArray(env, dataLen);
+    CACheckJNIException(env);
     (*env)->SetByteArrayRegion(env, jni_arr, 0, dataLen, (jbyte*) data);
+    CACheckJNIException(env);
     g_sendBuffer = (jbyteArray)(*env)->NewGlobalRef(env, jni_arr);
+    CACheckJNIException(env);
 
     uint32_t length = u_arraylist_length(g_connectedDeviceList);
     for (uint32_t index = 0; index < length; index++)
@@ -1925,7 +2009,9 @@ CAResult_t CALEServerSendMulticastMessageImpl(JNIEnv *env, const uint8_t *data,
 
         // send data for all device
         jbyteArray jni_bytearr_data = (*env)->NewByteArray(env, dataLen);
+        CACheckJNIException(env);
         (*env)->SetByteArrayRegion(env, jni_bytearr_data, 0, dataLen, (jbyte*) data);
+        CACheckJNIException(env);
 
         jstring jni_address = CALEGetAddressFromBTDevice(env, jarrayObj);
         if (!jni_address)
@@ -1950,6 +2036,7 @@ CAResult_t CALEServerSendMulticastMessageImpl(JNIEnv *env, const uint8_t *data,
         if (jarrayObj)
         {
             g_obj_bluetoothDevice = (*env)->NewGlobalRef(env, jarrayObj);
+            CACheckJNIException(env);
         }
 
         CAResult_t res = CALEServerSend(env, g_obj_bluetoothDevice, jni_bytearr_data);
@@ -1975,20 +2062,29 @@ CAResult_t CALEServerSendMulticastMessageImpl(JNIEnv *env, const uint8_t *data,
         g_sendBuffer = NULL;
     }
 
-    ca_mutex_unlock(g_threadSendMutex);
+    oc_mutex_unlock(g_threadSendMutex);
     return CA_STATUS_OK;
 }
 
 void CALEServerCreateCachedDeviceList()
 {
-    ca_mutex_lock(g_connectedDeviceListMutex);
+    oc_mutex_lock(g_connectedDeviceListMutex);
     // create new object array
     if (!g_connectedDeviceList)
     {
         OIC_LOG(DEBUG, TAG, "Create device list");
         g_connectedDeviceList = u_arraylist_create();
     }
-    ca_mutex_unlock(g_connectedDeviceListMutex);
+    oc_mutex_unlock(g_connectedDeviceListMutex);
+
+    oc_mutex_lock(g_deviceStateListMutex);
+    // create new object array
+    if (!g_deviceStateList)
+    {
+        OIC_LOG(DEBUG, TAG, "Create device list");
+        g_deviceStateList = u_arraylist_create();
+    }
+    oc_mutex_unlock(g_deviceStateListMutex);
 }
 
 bool CALEServerIsDeviceInList(JNIEnv *env, const char* remoteAddress)
@@ -2027,7 +2123,7 @@ bool CALEServerIsDeviceInList(JNIEnv *env, const char* remoteAddress)
             return false;
         }
 
-        if (!strcmp(remoteAddress, setAddress))
+        if (!strcasecmp(remoteAddress, setAddress))
         {
             OIC_LOG(ERROR, TAG, "the device is already set");
             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
@@ -2050,12 +2146,12 @@ CAResult_t CALEServerAddDeviceToList(JNIEnv *env, jobject device)
     VERIFY_NON_NULL(device, TAG, "device is null");
     VERIFY_NON_NULL(env, TAG, "env is null");
 
-    ca_mutex_lock(g_connectedDeviceListMutex);
+    oc_mutex_lock(g_connectedDeviceListMutex);
 
     if (!g_connectedDeviceList)
     {
         OIC_LOG(ERROR, TAG, "list is null");
-        ca_mutex_unlock(g_connectedDeviceListMutex);
+        oc_mutex_unlock(g_connectedDeviceListMutex);
         return CA_STATUS_FAILED;
     }
 
@@ -2063,7 +2159,7 @@ CAResult_t CALEServerAddDeviceToList(JNIEnv *env, jobject device)
     if (!jni_remoteAddress)
     {
         OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
-        ca_mutex_unlock(g_connectedDeviceListMutex);
+        oc_mutex_unlock(g_connectedDeviceListMutex);
         return CA_STATUS_FAILED;
     }
 
@@ -2071,7 +2167,7 @@ CAResult_t CALEServerAddDeviceToList(JNIEnv *env, jobject device)
     if (!remoteAddress)
     {
         OIC_LOG(ERROR, TAG, "remoteAddress is null");
-        ca_mutex_unlock(g_connectedDeviceListMutex);
+        oc_mutex_unlock(g_connectedDeviceListMutex);
         return CA_STATUS_FAILED;
     }
 
@@ -2083,7 +2179,7 @@ CAResult_t CALEServerAddDeviceToList(JNIEnv *env, jobject device)
     }
 
     (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
-    ca_mutex_unlock(g_connectedDeviceListMutex);
+    oc_mutex_unlock(g_connectedDeviceListMutex);
     OIC_LOG(DEBUG, TAG, "OUT - CALEServerAddDeviceToList");
     return CA_STATUS_OK;
 }
@@ -2093,11 +2189,11 @@ CAResult_t CALEServerRemoveAllDevices(JNIEnv *env)
     OIC_LOG(DEBUG, TAG, "IN - CALEServerRemoveAllDevices");
     VERIFY_NON_NULL(env, TAG, "env is null");
 
-    ca_mutex_lock(g_connectedDeviceListMutex);
+    oc_mutex_lock(g_connectedDeviceListMutex);
     if (!g_connectedDeviceList)
     {
         OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
-        ca_mutex_unlock(g_connectedDeviceListMutex);
+        oc_mutex_unlock(g_connectedDeviceListMutex);
         return CA_STATUS_FAILED;
     }
 
@@ -2113,7 +2209,7 @@ CAResult_t CALEServerRemoveAllDevices(JNIEnv *env)
 
     OICFree(g_connectedDeviceList);
     g_connectedDeviceList = NULL;
-    ca_mutex_unlock(g_connectedDeviceListMutex);
+    oc_mutex_unlock(g_connectedDeviceListMutex);
 
     OIC_LOG(DEBUG, TAG, "OUT - CALEServerRemoveAllDevices");
     return CA_STATUS_OK;
@@ -2125,11 +2221,11 @@ CAResult_t CALEServerRemoveDevice(JNIEnv *env, jstring address)
     VERIFY_NON_NULL(env, TAG, "env is null");
     VERIFY_NON_NULL(address, TAG, "address is null");
 
-    ca_mutex_lock(g_connectedDeviceListMutex);
+    oc_mutex_lock(g_connectedDeviceListMutex);
     if (!g_connectedDeviceList)
     {
         OIC_LOG(ERROR, TAG, "no deviceList");
-        ca_mutex_unlock(g_connectedDeviceListMutex);
+        oc_mutex_unlock(g_connectedDeviceListMutex);
         return CA_STATUS_FAILED;
     }
 
@@ -2161,7 +2257,7 @@ CAResult_t CALEServerRemoveDevice(JNIEnv *env, jstring address)
                 continue;
             }
 
-            if (!strcmp(setAddress, remoteAddress))
+            if (!strcasecmp(setAddress, remoteAddress))
             {
                 OIC_LOG_V(DEBUG, TAG, "device address : %s", remoteAddress);
 
@@ -2173,10 +2269,10 @@ CAResult_t CALEServerRemoveDevice(JNIEnv *env, jstring address)
                 if (NULL == u_arraylist_remove(g_connectedDeviceList, index))
                 {
                     OIC_LOG(ERROR, TAG, "List removal failed.");
-                    ca_mutex_unlock(g_connectedDeviceListMutex);
+                    oc_mutex_unlock(g_connectedDeviceListMutex);
                     return CA_STATUS_FAILED;
                 }
-                ca_mutex_unlock(g_connectedDeviceListMutex);
+                oc_mutex_unlock(g_connectedDeviceListMutex);
                 return CA_STATUS_OK;
             }
             (*env)->ReleaseStringUTFChars(env, jni_setAddress, setAddress);
@@ -2184,7 +2280,7 @@ CAResult_t CALEServerRemoveDevice(JNIEnv *env, jstring address)
         }
     }
 
-    ca_mutex_unlock(g_connectedDeviceListMutex);
+    oc_mutex_unlock(g_connectedDeviceListMutex);
 
     OIC_LOG(DEBUG, TAG, "there are no device in the device list");
 
@@ -2202,6 +2298,7 @@ Java_org_iotivity_ca_CaLeServerInterface_caLeRegisterGattServerCallback(JNIEnv *
     VERIFY_NON_NULL_VOID(callback, TAG, "callback");
 
     g_bluetoothGattServerCallback = (*env)->NewGlobalRef(env, callback);
+    CACheckJNIException(env);
 }
 
 JNIEXPORT void JNICALL
@@ -2215,6 +2312,7 @@ Java_org_iotivity_ca_CaLeServerInterface_caLeRegisterBluetoothLeAdvertiseCallbac
     VERIFY_NON_NULL_VOID(callback, TAG, "callback");
 
     g_leAdvertiseCallback = (*env)->NewGlobalRef(env, callback);
+    CACheckJNIException(env);
 }
 
 JNIEXPORT void JNICALL
@@ -2228,46 +2326,71 @@ Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerConnectionStateChangeCall
     VERIFY_NON_NULL_VOID(obj, TAG, "obj");
     VERIFY_NON_NULL_VOID(device, TAG, "device");
 
-    if (newState == g_state_connected)
+    jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
+    if (!jni_remoteAddress)
     {
+        OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
+        return;
+    }
 
+    const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
+    if (!remoteAddress)
+    {
+        OIC_LOG(ERROR, TAG, "remoteAddress is null");
+        CACheckJNIException(env);
+        return;
+    }
+
+    if (newState == g_state_connected)
+    {
         OIC_LOG(DEBUG, TAG, "LE CONNECTED");
 
-        jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
-        if (!jni_remoteAddress)
+        if (false == CALEServerIsDeviceInList(env, remoteAddress))
         {
-            OIC_LOG(ERROR, TAG, "jni_remoteAddress is null");
-            return;
+            OIC_LOG(DEBUG, TAG, "add connected device to cache");
+            CALEServerAddDeviceToList(env, device);
         }
 
-        const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
-        if (!remoteAddress)
+        CAResult_t res = CALEUpdateDeviceState(remoteAddress,
+                                               CA_LE_CONNECTION_STATE,
+                                               STATE_CONNECTED,
+                                               g_deviceStateList,
+                                               g_deviceStateListMutex);
+        if (CA_STATUS_OK != res)
         {
-            OIC_LOG(ERROR, TAG, "remoteAddress is null");
-            return;
+            OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
         }
 
-        if (false == CALEServerIsDeviceInList(env, remoteAddress))
+        res = CALEServerStopAdvertise();
+        if (CA_STATUS_OK != res)
         {
-            OIC_LOG(DEBUG, TAG, "add connected device to cache");
-            CALEServerAddDeviceToList(env, device);
+            OIC_LOG(DEBUG, TAG, "CALEServerStopAdvertise has failed");
         }
-        (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
     }
     else if (newState == g_state_disconnected)
     {
         OIC_LOG(DEBUG, TAG, "LE DISCONNECTED");
 
         jstring jni_remoteAddress = CALEGetAddressFromBTDevice(env, device);
-        CAResult_t ret = CALEServerRemoveDevice(env, jni_remoteAddress);
-        if (CA_STATUS_OK != ret)
+        CAResult_t res = CALEServerRemoveDevice(env, jni_remoteAddress);
+        if (CA_STATUS_OK != res)
         {
             OIC_LOG(ERROR, TAG, "CALEServerRemoveDevice has failed");
         }
 
+        res = CALEUpdateDeviceState(remoteAddress,
+                                    CA_LE_CONNECTION_STATE,
+                                    STATE_DISCONNECTED,
+                                    g_deviceStateList,
+                                    g_deviceStateListMutex);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
+        }
+
         // start advertise
-        ret = CALEServerStartAdvertise(env, g_leAdvertiseCallback);
-        if (CA_STATUS_OK != ret)
+        res = CALEServerStartAdvertise();
+        if (CA_STATUS_OK != res)
         {
             OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
         }
@@ -2280,6 +2403,8 @@ Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerConnectionStateChangeCall
         OIC_LOG_V(DEBUG, TAG, "LE Connection state is [newState : %d, status %d]", newState,
                 status);
     }
+    (*env)->ReleaseStringUTFChars(env, jni_remoteAddress, remoteAddress);
+    (*env)->DeleteLocalRef(env, jni_remoteAddress);
 }
 
 JNIEXPORT void JNICALL
@@ -2310,7 +2435,8 @@ Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerCharacteristicReadRequest
 
 JNIEXPORT void JNICALL
 Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerCharacteristicWriteRequestCallback(
-        JNIEnv *env, jobject obj, jobject device, jbyteArray data)
+        JNIEnv *env, jobject obj, jobject device, jbyteArray data,
+        jint requestId, jint offset, jbyteArray value)
 {
     OIC_LOG_V(DEBUG, TAG, "Gatt Server Characteristic Write Request Callback");
     VERIFY_NON_NULL_VOID(env, TAG, "env");
@@ -2318,11 +2444,24 @@ Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerCharacteristicWriteReques
     VERIFY_NON_NULL_VOID(device, TAG, "device");
     VERIFY_NON_NULL_VOID(data, TAG, "data");
 
+    if (g_setHighQoS)
+    {
+        CALEServerSendResponse(env, device, requestId, 0, offset, value);
+    }
+    else
+    {
+        (void)requestId;
+        (void)offset;
+        (void)value;
+    }
+
     // get Byte Array and covert to uint8_t*
     jint length = (*env)->GetArrayLength(env, data);
+    CACheckJNIException(env);
 
     jboolean isCopy;
     jbyte *jni_byte_requestData = (jbyte *) (*env)->GetByteArrayElements(env, data, &isCopy);
+    CACheckJNIException(env);
 
     uint8_t* requestData = NULL;
     requestData = OICMalloc(length);
@@ -2347,17 +2486,18 @@ Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerCharacteristicWriteReques
     if (!address)
     {
         OIC_LOG(ERROR, TAG, "address is null");
+        CACheckJNIException(env);
         OICFree(requestData);
         return;
     }
 
     OIC_LOG_V(DEBUG, TAG, "remote device address : %s, %p, %d", address, requestData, length);
 
-    ca_mutex_lock(g_bleClientBDAddressMutex);
+    oc_mutex_lock(g_bleClientBDAddressMutex);
     uint32_t sentLength = 0;
     g_CABLEServerDataReceivedCallback(address, requestData, length,
                                       &sentLength);
-    ca_mutex_unlock(g_bleClientBDAddressMutex);
+    oc_mutex_unlock(g_bleClientBDAddressMutex);
 
     (*env)->ReleaseStringUTFChars(env, jni_address, address);
 }
@@ -2375,6 +2515,21 @@ Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerNotificationSentCallback(
     OIC_LOG_V(DEBUG, TAG, "Gatt Server Notification Sent Callback (status : %d)",
               status);
 
+    jstring jni_address = CALEGetAddressFromBTDevice(env, device);
+    if (!jni_address)
+    {
+        OIC_LOG(ERROR, TAG, "jni_address is null");
+        return;
+    }
+
+    const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
+    if (!address)
+    {
+        OIC_LOG(ERROR, TAG, "address is not available");
+        (*env)->DeleteLocalRef(env, jni_address);
+        return;
+    }
+
     jint gatt_success = CALEGetConstantsValue(env, CLASSPATH_BT_GATT, "GATT_SUCCESS");
     if (gatt_success != status) // error case
     {
@@ -2391,12 +2546,18 @@ Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerNotificationSentCallback(
                 g_obj_bluetoothDevice = NULL;
             }
 
-            ca_mutex_lock(g_threadSendNotifyMutex);
+            oc_mutex_lock(g_threadSendNotifyMutex);
             g_isSignalSetFlag = true;
-            ca_cond_signal(g_threadSendNotifyCond);
-            ca_mutex_unlock(g_threadSendNotifyMutex);
+            oc_cond_signal(g_threadSendNotifyCond);
+            oc_mutex_unlock(g_threadSendNotifyMutex);
+
+            (*env)->ReleaseStringUTFChars(env, jni_address, address);
+            (*env)->DeleteLocalRef(env, jni_address);
             return;
         }
+
+        CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, address, 0, -1,
+                           false, "notifyChar failure");
     }
     else
     {
@@ -2409,12 +2570,17 @@ Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerNotificationSentCallback(
         }
 
         // next data can be sent
-        ca_mutex_lock(g_threadSendNotifyMutex);
+        oc_mutex_lock(g_threadSendNotifyMutex);
         OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
         g_isSignalSetFlag = true;
-        ca_cond_signal(g_threadSendNotifyCond);
-        ca_mutex_unlock(g_threadSendNotifyMutex);
+        oc_cond_signal(g_threadSendNotifyCond);
+        oc_mutex_unlock(g_threadSendNotifyMutex);
+
+        CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, address, 0, -1,
+                           true, "notifyChar success");
     }
+    (*env)->ReleaseStringUTFChars(env, jni_address, address);
+    (*env)->DeleteLocalRef(env, jni_address);
 
 }
 
@@ -2455,6 +2621,54 @@ Java_org_iotivity_ca_CaLeServerInterface_caLeAdvertiseStartFailureCallback(JNIEn
     }
 }
 
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerMtuChangedCallback(JNIEnv * env,
+                                                                          jobject obj,
+                                                                          jobject device,
+                                                                          jint mtu)
+{
+    VERIFY_NON_NULL_VOID(env, TAG, "env");
+    VERIFY_NON_NULL_VOID(obj, TAG, "obj");
+    VERIFY_NON_NULL_VOID(device, TAG, "device");
+
+    OIC_LOG_V(INFO, TAG, "gatt MTU size is changed (%d byte)", mtu);
+
+    jstring jni_address = CALEGetAddressFromBTDevice(env, device);
+    if (!jni_address)
+    {
+        OIC_LOG(ERROR, TAG, "jni_address is null");
+        return;
+    }
+
+    const char* address = (*env)->GetStringUTFChars(env, jni_address, NULL);
+    if (!address)
+    {
+        OIC_LOG(ERROR, TAG, "address is not available");
+        (*env)->DeleteLocalRef(env, jni_address);
+        return;
+    }
+
+    // update mtu size
+    CAResult_t res = CALESetMtuSize(address, mtu - CA_BLE_MTU_HEADER_SIZE,
+                                    g_deviceStateList, g_deviceStateListMutex);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "CALESetMtuSize has failed");
+    }
+
+    res = CALEUpdateDeviceState(address, CA_LE_SEND_STATE,
+                                STATE_SEND_MTU_NEGO_SUCCESS,
+                                g_deviceStateList,
+                                g_deviceStateListMutex);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "CALEUpdateDeviceState has failed");
+    }
+
+    (*env)->ReleaseStringUTFChars(env, jni_address, address);
+    (*env)->DeleteLocalRef(env, jni_address);
+}
+
 /**
  * adapter common
  */
@@ -2542,9 +2756,9 @@ CAResult_t CAStopLEGattServer()
         g_obj_bluetoothDevice = NULL;
     }
 
-    ca_mutex_lock(g_threadSendNotifyMutex);
-    ca_cond_signal(g_threadSendNotifyCond);
-    ca_mutex_unlock(g_threadSendNotifyMutex);
+    oc_mutex_lock(g_threadSendNotifyMutex);
+    oc_cond_signal(g_threadSendNotifyCond);
+    oc_mutex_unlock(g_threadSendNotifyMutex);
 
     g_isStartServer = false;
 
@@ -2570,9 +2784,9 @@ void CATerminateLEGattServer()
 
 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
 {
-    ca_mutex_lock(g_bleReqRespCbMutex);
+    oc_mutex_lock(g_bleReqRespCbMutex);
     g_CABLEServerDataReceivedCallback = callback;
-    ca_mutex_unlock(g_bleReqRespCbMutex);
+    oc_mutex_unlock(g_bleReqRespCbMutex);
 }
 
 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
@@ -2616,50 +2830,60 @@ CAResult_t CALEServerInitMutexVaraibles()
 {
     if (NULL == g_bleReqRespCbMutex)
     {
-        g_bleReqRespCbMutex = ca_mutex_new();
+        g_bleReqRespCbMutex = oc_mutex_new();
         if (NULL == g_bleReqRespCbMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_bleClientBDAddressMutex)
     {
-        g_bleClientBDAddressMutex = ca_mutex_new();
+        g_bleClientBDAddressMutex = oc_mutex_new();
         if (NULL == g_bleClientBDAddressMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_connectedDeviceListMutex)
     {
-        g_connectedDeviceListMutex = ca_mutex_new();
+        g_connectedDeviceListMutex = oc_mutex_new();
         if (NULL == g_connectedDeviceListMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_threadSendMutex)
     {
-        g_threadSendMutex = ca_mutex_new();
+        g_threadSendMutex = oc_mutex_new();
         if (NULL == g_threadSendMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_threadSendNotifyMutex)
     {
-        g_threadSendNotifyMutex = ca_mutex_new();
+        g_threadSendNotifyMutex = oc_mutex_new();
         if (NULL == g_threadSendNotifyMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_deviceStateListMutex)
+    {
+        g_deviceStateListMutex = oc_mutex_new();
+        if (NULL == g_deviceStateListMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
             return CA_STATUS_FAILED;
         }
     }
@@ -2669,23 +2893,46 @@ CAResult_t CALEServerInitMutexVaraibles()
 
 void CALEServerTerminateMutexVaraibles()
 {
-    ca_mutex_free(g_bleReqRespCbMutex);
+    oc_mutex_free(g_bleReqRespCbMutex);
     g_bleReqRespCbMutex = NULL;
 
-    ca_mutex_free(g_bleClientBDAddressMutex);
+    oc_mutex_free(g_bleClientBDAddressMutex);
     g_bleClientBDAddressMutex = NULL;
 
-    ca_mutex_free(g_connectedDeviceListMutex);
+    oc_mutex_free(g_connectedDeviceListMutex);
     g_connectedDeviceListMutex = NULL;
 
-    ca_mutex_free(g_threadSendMutex);
+    oc_mutex_free(g_threadSendMutex);
     g_threadSendMutex = NULL;
 
-    ca_mutex_free(g_threadSendNotifyMutex);
+    oc_mutex_free(g_threadSendNotifyMutex);
     g_threadSendNotifyMutex = NULL;
+
+    oc_mutex_free(g_deviceStateListMutex);
+    g_deviceStateListMutex = NULL;
 }
 
 void CALEServerTerminateConditionVaraibles()
 {
     OIC_LOG(DEBUG, TAG, "this method is not supported");
 }
+
+bool CALEServerIsConnected(const char* address)
+{
+    if (CALEIsValidState(address, CA_LE_CONNECTION_STATE,
+                         STATE_SERVICE_CONNECTED,
+                         g_deviceStateList,
+                         g_deviceStateListMutex))
+    {
+        OIC_LOG(DEBUG, TAG, "current state is connected");
+        return true;
+    }
+    OIC_LOG(DEBUG, TAG, "current state is not connected");
+    return false;
+}
+
+uint16_t CALEServerGetMtuSize(const char* address)
+{
+    return CALEGetMtuSize(address, g_deviceStateList, g_deviceStateListMutex);
+}
+
index 83943b6..516075e 100644 (file)
@@ -128,8 +128,9 @@ CAResult_t CALEServerCreateJniInterfaceObject();
 
 /**
  * start advertise in gatt server.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
  */
-CAResult_t CALEStartAdvertise();
+CAResult_t CALEServerStartAdvertise();
 
 /**
  * start advertise in gatt server.
@@ -138,7 +139,13 @@ CAResult_t CALEStartAdvertise();
  *                                 advertisement result.
  * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
  */
-CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback);
+CAResult_t CALEServerStartAdvertiseImpl(JNIEnv *env, jobject advertiseCallback);
+
+/**
+ * stop advertise in gatt server.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEServerStopAdvertise();
 
 /**
  * stop advertise in gatt server.
@@ -147,7 +154,7 @@ CAResult_t CALEServerStartAdvertise(JNIEnv *env, jobject advertiseCallback);
  *                                 advertisement result.
  * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
  */
-CAResult_t CALEServerStopAdvertise(JNIEnv *env, jobject advertiseCallback);
+CAResult_t CALEServerStopAdvertiseImpl(JNIEnv *env, jobject advertiseCallback);
 
 /**
  * open a gatt server.
@@ -317,6 +324,19 @@ CAResult_t CALEServerInitConditionVaraibles();
  */
 void CALEServerTerminateConditionVaraibles();
 
+/**
+ * check connection status.
+ * @param[in] address      the address of the remote device.
+ * @return  true or false.
+ */
+bool CALEServerIsConnected(const char* address);
+
+/**
+ * get MTU size.
+ * @param[in] address      the address of the remote device.
+ * @return  mtu size negotiated from remote device.
+ */
+uint16_t CALEServerGetMtuSize(const char* address);
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/android/calestate.c b/resource/csdk/connectivity/src/bt_le_adapter/android/calestate.c
new file mode 100644 (file)
index 0000000..c1b7101
--- /dev/null
@@ -0,0 +1,463 @@
+/******************************************************************
+ *
+ * Copyright 2017 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 <stdio.h>
+#include <string.h>
+#include <jni.h>
+#include <unistd.h>
+
+#include "calestate.h"
+#include "caleinterface.h"
+#include "caadapterutils.h"
+#include "caleutils.h"
+
+#include "logger.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "cathreadpool.h" /* for thread pool */
+#include "octhread.h"
+#include "uarraylist.h"
+
+#define TAG PCF("OIC_CA_LE_STATE")
+
+CAResult_t CALEUpdateDeviceState(const char* address,
+                                 uint16_t state_type,
+                                 uint16_t target_state,
+                                 u_arraylist_t *deviceList,
+                                 oc_mutex deviceListMutex)
+{
+    VERIFY_NON_NULL(address, TAG, "address is null");
+    VERIFY_NON_NULL(deviceList, TAG, "deviceList is null");
+
+    oc_mutex_lock(deviceListMutex);
+
+    if (CALEIsDeviceInList(address, deviceList))
+    {
+        CALEState_t* curState = CALEGetStateInfo(address, deviceList);
+        if(!curState)
+        {
+            OIC_LOG(ERROR, TAG, "curState is null");
+            oc_mutex_unlock(deviceListMutex);
+            return CA_STATUS_FAILED;
+        }
+
+        switch(state_type)
+        {
+            case CA_LE_CONNECTION_STATE:
+                curState->connectedState = target_state;
+                break;
+            case CA_LE_SEND_STATE:
+                curState->sendState = target_state;
+                break;
+            default:
+                break;
+        }
+        OIC_LOG_V(INFO, TAG, "update state - addr: %s, conn: %d, send: %d, ACFlag: %d, mtu: %d",
+                  curState->address, curState->connectedState, curState->sendState,
+                  curState->autoConnectFlag, curState->mtuSize);
+    }
+    else /** state is added newly **/
+    {
+        if (strlen(address) > CA_MACADDR_SIZE)
+        {
+            OIC_LOG(ERROR, TAG, "address is not proper");
+            oc_mutex_unlock(deviceListMutex);
+            return CA_STATUS_INVALID_PARAM;
+        }
+
+        CALEState_t *newstate = (CALEState_t*) OICCalloc(1, sizeof(*newstate));
+        if (!newstate)
+        {
+            OIC_LOG(ERROR, TAG, "out of memory");
+            oc_mutex_unlock(deviceListMutex);
+            return CA_MEMORY_ALLOC_FAILED;
+        }
+
+        OICStrcpy(newstate->address, sizeof(newstate->address), address);
+        newstate->mtuSize = CA_DEFAULT_BLE_MTU_SIZE;
+        switch(state_type)
+        {
+            case CA_LE_CONNECTION_STATE:
+                newstate->connectedState = target_state;
+                newstate->sendState = STATE_SEND_NONE;
+                break;
+            case CA_LE_SEND_STATE:
+                newstate->connectedState = STATE_DISCONNECTED;
+                newstate->sendState = target_state;
+                break;
+            default:
+                break;
+        }
+        OIC_LOG_V(INFO, TAG, "add a new state to List - addr : %s, "
+                  "conn : %d, send : %d, ACFlag : %d",
+                  newstate->address, newstate->connectedState, newstate->sendState,
+                  newstate->autoConnectFlag);
+        u_arraylist_add(deviceList, newstate); // update new state
+    }
+    oc_mutex_unlock(deviceListMutex);
+
+    return CA_STATUS_OK;
+}
+
+bool CALEIsDeviceInList(const char* remoteAddress,
+                        u_arraylist_t *deviceList)
+{
+    VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
+    VERIFY_NON_NULL_RET(deviceList, TAG, "deviceList is null", false);
+
+    uint32_t length = u_arraylist_length(deviceList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        CALEState_t* state = (CALEState_t*) u_arraylist_get(deviceList, index);
+        if (!state)
+        {
+            OIC_LOG(ERROR, TAG, "CALEState_t object is null");
+            return false;
+        }
+
+        if (!strcasecmp(remoteAddress, state->address))
+        {
+            return true;
+        }
+        else
+        {
+            continue;
+        }
+    }
+
+    OIC_LOG(INFO, TAG, "there are no the device in list.");
+    return false;
+}
+
+CAResult_t CALERemoveAllDeviceState(u_arraylist_t *deviceList,
+                                    oc_mutex deviceListMutex)
+{
+    OIC_LOG(DEBUG, TAG, "CALERemoveAllDeviceState");
+    VERIFY_NON_NULL(deviceList, TAG, "deviceList is null");
+
+    oc_mutex_lock(deviceListMutex);
+    uint32_t length = u_arraylist_length(deviceList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        CALEState_t* state = (CALEState_t*) u_arraylist_get(deviceList, index);
+        if (!state)
+        {
+            OIC_LOG(ERROR, TAG, "jarrayObj is null");
+            continue;
+        }
+        OICFree(state);
+    }
+
+    oc_mutex_unlock(deviceListMutex);
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CALEResetDeviceStateForAll(u_arraylist_t *deviceList,
+                                      oc_mutex deviceListMutex)
+{
+    OIC_LOG(DEBUG, TAG, "CALEResetDeviceStateForAll");
+    VERIFY_NON_NULL(deviceList, TAG, "deviceList is null");
+
+    oc_mutex_lock(deviceListMutex);
+    size_t length = u_arraylist_length(deviceList);
+    for (size_t index = 0; index < length; index++)
+    {
+        CALEState_t* state = (CALEState_t*) u_arraylist_get(deviceList, index);
+        if (!state)
+        {
+            OIC_LOG(ERROR, TAG, "jarrayObj is null");
+            continue;
+        }
+
+        // autoConnectFlag value will be not changed,
+        // since it has reset only termination case.
+        state->connectedState = STATE_DISCONNECTED;
+        state->sendState = STATE_SEND_NONE;
+    }
+    oc_mutex_unlock(deviceListMutex);
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CALERemoveDeviceState(const char* remoteAddress,
+                                 u_arraylist_t *deviceList)
+{
+    OIC_LOG(DEBUG, TAG, "CALERemoveDeviceState");
+    VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
+    VERIFY_NON_NULL(deviceList, TAG, "deviceList is null");
+
+    uint32_t length = u_arraylist_length(deviceList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        CALEState_t* state = (CALEState_t*) u_arraylist_get(deviceList, index);
+        if (!state)
+        {
+            OIC_LOG(ERROR, TAG, "CALEState_t object is null");
+            continue;
+        }
+
+        if (!strcasecmp(state->address, remoteAddress))
+        {
+            OIC_LOG_V(DEBUG, TAG, "remove state : %s", state->address);
+
+            CALEState_t* targetState  = (CALEState_t*)u_arraylist_remove(deviceList,
+                                                                         index);
+            if (NULL == targetState)
+            {
+                OIC_LOG(ERROR, TAG, "List removal failed.");
+                return CA_STATUS_FAILED;
+            }
+
+            OICFree(targetState);
+            return CA_STATUS_OK;
+        }
+    }
+    return CA_STATUS_OK;
+}
+
+CALEState_t* CALEGetStateInfo(const char* remoteAddress,
+                              u_arraylist_t *deviceList)
+{
+    VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
+    VERIFY_NON_NULL_RET(deviceList, TAG, "deviceList is null", NULL);
+
+    uint32_t length = u_arraylist_length(deviceList);
+
+    for (uint32_t index = 0; index < length; index++)
+    {
+        CALEState_t* state = (CALEState_t*) u_arraylist_get(deviceList, index);
+        if (!state)
+        {
+            OIC_LOG(ERROR, TAG, "CALEState_t object is null");
+            continue;
+        }
+
+        if (!strcasecmp(state->address, remoteAddress))
+        {
+            return state;
+        }
+        OIC_LOG_V(DEBUG, TAG, "state addr[%s, %d]", state->address, index);
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in deviceStateList", remoteAddress, length);
+    return NULL;
+}
+
+bool CALEIsValidState(const char* remoteAddress,
+                      uint16_t state_type,
+                      uint16_t target_state,
+                      u_arraylist_t *deviceList,
+                      oc_mutex deviceListMutex)
+{
+    OIC_LOG_V(DEBUG, TAG, "CALEIsValidState : type[%d], target state[%d]",
+              state_type, target_state);
+    VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
+    VERIFY_NON_NULL_RET(deviceList, TAG, "deviceList is null", false);
+
+    oc_mutex_lock(deviceListMutex);
+    CALEState_t* state = CALEGetStateInfo(remoteAddress, deviceList);
+    if (NULL == state)
+    {
+        OIC_LOG(DEBUG, TAG, "state is not updated yet");
+        oc_mutex_unlock(deviceListMutex);
+        return false;
+    }
+
+    uint16_t curValue = 0;
+    switch(state_type)
+    {
+        case CA_LE_CONNECTION_STATE:
+            curValue = state->connectedState;
+            break;
+        case CA_LE_SEND_STATE:
+            curValue = state->sendState;
+            break;
+        default:
+            break;
+    }
+
+    if (target_state == curValue)
+    {
+        oc_mutex_unlock(deviceListMutex);
+        return true;
+    }
+    else
+    {
+        oc_mutex_unlock(deviceListMutex);
+        return false;
+    }
+
+    oc_mutex_unlock(deviceListMutex);
+    return false;
+}
+
+
+CAResult_t CALESetFlagToState(JNIEnv *env, jstring jni_address, jint state_idx, jboolean flag,
+                              u_arraylist_t *deviceList, oc_mutex deviceListMutex)
+{
+    OIC_LOG(DEBUG, TAG, "IN - CALESetFlagToState");
+    VERIFY_NON_NULL(env, TAG, "env");
+    VERIFY_NON_NULL(jni_address, TAG, "jni_address");
+    VERIFY_NON_NULL(deviceList, TAG, "deviceList");
+
+    oc_mutex_lock(deviceListMutex);
+
+    char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
+    if (!address)
+    {
+        OIC_LOG(ERROR, TAG, "address is not available");
+        CACheckJNIException(env);
+        return CA_STATUS_FAILED;
+    }
+
+    if (CALEIsDeviceInList(address, deviceList))
+    {
+        CALEState_t* curState = CALEGetStateInfo(address, deviceList);
+        if(!curState)
+        {
+            OIC_LOG(ERROR, TAG, "curState is null");
+            (*env)->ReleaseStringUTFChars(env, jni_address, address);
+            oc_mutex_unlock(deviceListMutex);
+            return CA_STATUS_FAILED;
+        }
+        OIC_LOG_V(INFO, TAG, "%d flag is set : %d", state_idx, flag);
+
+        switch(state_idx)
+        {
+            case CA_LE_AUTO_CONNECT_FLAG:
+                curState->autoConnectFlag = flag;
+                break;
+            case CA_LE_DESCRIPTOR_FOUND:
+                curState->isDescriptorFound = flag;
+                break;
+            default:
+                break;
+        }
+    }
+
+    (*env)->ReleaseStringUTFChars(env, jni_address, address);
+    oc_mutex_unlock(deviceListMutex);
+    OIC_LOG(DEBUG, TAG, "OUT - CALESetFlagToState");
+    return CA_STATUS_OK;
+}
+
+jboolean CALEGetFlagFromState(JNIEnv *env, jstring jni_address, jint state_idx,
+                              u_arraylist_t *deviceList, oc_mutex deviceListMutex)
+{
+    OIC_LOG(DEBUG, TAG, "IN - CALEGetFlagFromState");
+    VERIFY_NON_NULL_RET(env, TAG, "env", false);
+    VERIFY_NON_NULL_RET(jni_address, TAG, "jni_address", false);
+    VERIFY_NON_NULL_RET(deviceList, TAG, "deviceList", false);
+
+    oc_mutex_lock(deviceListMutex);
+
+    char* address = (char*)(*env)->GetStringUTFChars(env, jni_address, NULL);
+    if (!address)
+    {
+        OIC_LOG(ERROR, TAG, "address is not available");
+        CACheckJNIException(env);
+        oc_mutex_unlock(deviceListMutex);
+        return JNI_FALSE;
+    }
+
+    CALEState_t* curState = CALEGetStateInfo(address, deviceList);
+    (*env)->ReleaseStringUTFChars(env, jni_address, address);
+    if(!curState)
+    {
+        OIC_LOG(INFO, TAG, "there is no information. auto connect flag is false");
+        oc_mutex_unlock(deviceListMutex);
+        return JNI_FALSE;
+    }
+
+    jboolean ret = JNI_FALSE;
+    switch(state_idx)
+    {
+        case CA_LE_AUTO_CONNECT_FLAG:
+            ret = curState->autoConnectFlag;
+            break;
+        case CA_LE_DESCRIPTOR_FOUND:
+            ret = curState->isDescriptorFound;
+            break;
+        default:
+            break;
+    }
+    oc_mutex_unlock(deviceListMutex);
+
+    OIC_LOG_V(INFO, TAG, "%d flag is %d", state_idx, ret);
+    OIC_LOG(DEBUG, TAG, "OUT - CALEGetFlagFromState");
+    return ret;
+}
+
+CAResult_t CALESetMtuSize(const char* address, uint16_t mtuSize,
+                          u_arraylist_t *deviceList, oc_mutex deviceListMutex)
+
+{
+    VERIFY_NON_NULL(address, TAG, "address is null");
+    VERIFY_NON_NULL(deviceList, TAG, "deviceList is null");
+
+    oc_mutex_lock(deviceListMutex);
+    if (CALEIsDeviceInList(address, deviceList))
+    {
+        CALEState_t* curState = CALEGetStateInfo(address, deviceList);
+        if(!curState)
+        {
+            OIC_LOG(ERROR, TAG, "curState is null");
+            oc_mutex_unlock(deviceListMutex);
+            return CA_STATUS_FAILED;
+        }
+
+        curState->mtuSize = mtuSize;
+        OIC_LOG_V(INFO, TAG, "update state - addr: %s, mtu: %d",
+                  curState->address, curState->mtuSize);
+    }
+    else
+    {
+        OIC_LOG(ERROR, TAG, "there is no state info in the list");
+    }
+    oc_mutex_unlock(deviceListMutex);
+    return CA_STATUS_OK;
+}
+
+uint16_t CALEGetMtuSize(const char* address, u_arraylist_t *deviceList, oc_mutex deviceListMutex)
+{
+    VERIFY_NON_NULL_RET(address, TAG, "address is null", CA_DEFAULT_BLE_MTU_SIZE);
+    VERIFY_NON_NULL_RET(deviceList, TAG, "deviceList is null", CA_DEFAULT_BLE_MTU_SIZE);
+
+    oc_mutex_lock(deviceListMutex);
+    if (CALEIsDeviceInList(address, deviceList))
+    {
+        CALEState_t* curState = CALEGetStateInfo(address, deviceList);
+        if(!curState)
+        {
+            OIC_LOG(ERROR, TAG, "curState is null");
+            oc_mutex_unlock(deviceListMutex);
+            return CA_DEFAULT_BLE_MTU_SIZE;
+        }
+
+        OIC_LOG_V(INFO, TAG, "state - addr: %s, mtu: %d",
+                  curState->address, curState->mtuSize);
+        oc_mutex_unlock(deviceListMutex);
+        return curState->mtuSize;
+    }
+
+    oc_mutex_unlock(deviceListMutex);
+    return CA_DEFAULT_BLE_MTU_SIZE;
+}
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/android/calestate.h b/resource/csdk/connectivity/src/bt_le_adapter/android/calestate.h
new file mode 100644 (file)
index 0000000..7a72aa3
--- /dev/null
@@ -0,0 +1,178 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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 BT LE communications.
+ */
+#ifndef CA_LE_LIST_H_
+#define CA_LE_LIST_H_
+
+#include "cacommon.h"
+#include "cathreadpool.h" /* for thread pool */
+#include "octhread.h"
+#include "uarraylist.h"
+#include "jni.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef struct le_state_info
+{
+    char address[CA_MACADDR_SIZE];
+    uint16_t connectedState;
+    uint16_t sendState;
+    jboolean autoConnectFlag;
+    jboolean isDescriptorFound;
+    uint16_t mtuSize;
+} CALEState_t;
+
+/**
+ * update new state information.
+ * @param[in]   address               remote address.
+ * @param[in]   state_type            state type.
+ * @param[in]   target_state          state index to update.
+ * @param[in]   deviceList            target device list.
+ * @param[in]   deviceListMutex       target device list mutex.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEUpdateDeviceState(const char* address,
+                                 uint16_t state_type,
+                                 uint16_t target_state,
+                                 u_arraylist_t *deviceList,
+                                 oc_mutex deviceListMutex);
+
+/**
+ * check whether the remote address is existed or not.
+ * @param[in]   address               remote address.
+ * @param[in]   deviceList            target device list.
+ * @return  true or false.
+ */
+bool CALEIsDeviceInList(const char* remoteAddress,
+                        u_arraylist_t *deviceList);
+
+/**
+ * remove all device states.
+ * @param[in]   deviceList            target device list.
+ * @param[in]   deviceListMutex       target device list mutex.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALERemoveAllDeviceState(u_arraylist_t *deviceList,
+                                    oc_mutex deviceListMutex);
+
+/**
+ * Reset values of device state for all of devices.
+ * this method has to be invoked when BT adapter is disabled.
+ * @param[in]   deviceList            target device list.
+ * @param[in]   deviceListMutex       target device list mutex.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEResetDeviceStateForAll(u_arraylist_t *deviceList,
+                                      oc_mutex deviceListMutex);
+
+/**
+ * remove the device state for a remote device.
+ * @param[in]   remoteAddress         remote address.
+ * @param[in]   deviceList            target device list.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALERemoveDeviceState(const char* remoteAddress,
+                                 u_arraylist_t *deviceList);
+
+/**
+ * get state information for a remote device.
+ * @param[in]   remoteAddress         remote address.
+ * @param[in]   deviceList            target device list.
+ * @return  CALEState_t.
+ */
+CALEState_t* CALEGetStateInfo(const char* remoteAddressm,
+                              u_arraylist_t *deviceList);
+
+/**
+ * check whether the remote address has same state with target state.
+ * @param[in]   remoteAddress         remote address.
+ * @param[in]   state_type            state_type.
+ * @param[in]   target_state          state index to check.
+ * @param[in]   deviceList            target device list.
+ * @param[in]   deviceListMutex       target device list mutex.
+ * @return  true or false.
+ */
+bool CALEIsValidState(const char* remoteAddress,
+                      uint16_t state_type,
+                      uint16_t target_state,
+                      u_arraylist_t *deviceList,
+                      oc_mutex deviceListMutex);
+
+
+/**
+ * set flag into State List.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   jni_address           remote address.
+ * @param[in]   state_idx             state index.
+ * @param[in]   flag                  auto connect flag.
+ * @param[in]   deviceList            target device list.
+ * @param[in]   deviceListMutex       target device list mutex.
+ */
+CAResult_t CALESetFlagToState(JNIEnv *env, jstring jni_address,
+                              jint state_idx, jboolean flag,
+                              u_arraylist_t *deviceList,
+                              oc_mutex deviceListMutex);
+
+/**
+ * get flag from State List.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   jni_address           remote address.
+ * @param[in]   state_idx             state index.
+ * @param[in]   deviceList            target device list.
+ * @param[in]   deviceListMutex       target device list mutex.
+ * @return  current flag;
+ */
+jboolean CALEGetFlagFromState(JNIEnv *env, jstring jni_address, jint state_idx,
+                              u_arraylist_t *deviceList, oc_mutex deviceListMutex);
+
+/**
+ * This function is used to set MTU size
+ * which negotiated between client and server device.
+ * @param[in]   address               remote address.
+ * @param[in]   mtuSize               MTU size.
+ * @param[in]   deviceList            target device list.
+ * @param[in]   deviceListMutex       target device list mutex.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALESetMtuSize(const char* address, uint16_t mtuSize,
+                          u_arraylist_t *deviceList, oc_mutex deviceListMutex);
+
+/**
+ * get MTU size.
+ * @param[in] address      the address of the remote device.
+ * @param[in]   deviceList            target device list.
+ * @param[in]   deviceListMutex       target device list mutex.
+ * @return  mtu size negotiated from remote device.
+ */
+uint16_t CALEGetMtuSize(const char* address,
+                        u_arraylist_t *deviceList,
+                        oc_mutex deviceListMutex);
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* CA_LESERVER_H_ */
index d863f9e..04c5f8b 100644 (file)
@@ -39,7 +39,7 @@ jobject CALEGetUuidFromString(JNIEnv *env, const char* uuid)
     if (!jni_cid_UUID)
     {
         OIC_LOG(ERROR, TAG, "jni_cid_UUID is not available");
-        return NULL;
+        goto error_exit;
     }
 
     jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_UUID, "fromString",
@@ -48,14 +48,14 @@ jobject CALEGetUuidFromString(JNIEnv *env, const char* uuid)
     if (!jni_mid_fromString)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_fromString is not available");
-        return NULL;
+        goto error_exit;
     }
 
     jstring str_uuid = (*env)->NewStringUTF(env, uuid);
     if (!str_uuid)
     {
         OIC_LOG(ERROR, TAG, "str_uuid is not available");
-        return NULL;
+        goto error_exit;
     }
 
     jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_UUID, jni_mid_fromString,
@@ -63,10 +63,14 @@ jobject CALEGetUuidFromString(JNIEnv *env, const char* uuid)
     if (!jni_obj_uuid)
     {
         OIC_LOG(ERROR, TAG, "Fail to get jni uuid object");
-        return NULL;
+        goto error_exit;
     }
 
     return jni_obj_uuid;
+
+error_exit:
+    CACheckJNIException(env);
+    return NULL;
 }
 
 jobject CALEGetParcelUuid(JNIEnv *env, jobject uuid)
@@ -78,7 +82,7 @@ jobject CALEGetParcelUuid(JNIEnv *env, jobject uuid)
     if (!jni_cid_ParcelUuid)
     {
         OIC_LOG(ERROR, TAG, "jni_cid_ParcelUuid is not available");
-        return NULL;
+        goto error_exit;
     }
 
     jmethodID jni_mid_ParcelUuid = (*env)->GetMethodID(env, jni_cid_ParcelUuid, "<init>",
@@ -86,17 +90,64 @@ jobject CALEGetParcelUuid(JNIEnv *env, jobject uuid)
     if (!jni_mid_ParcelUuid)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_ParcelUuid is not available");
-        return NULL;
+        goto error_exit;
     }
 
     jobject jni_ParcelUuid = (*env)->NewObject(env, jni_cid_ParcelUuid, jni_mid_ParcelUuid, uuid);
     if (!jni_ParcelUuid)
     {
         OIC_LOG(ERROR, TAG, "Fail to get jni ParcelUuid");
-        return NULL;
+        goto error_exit;
     }
 
     return jni_ParcelUuid;
+error_exit:
+    CACheckJNIException(env);
+    return NULL;
+}
+
+jobject CALEGetParcelUuidFromString(JNIEnv *env, const char* uuid)
+{
+    VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
+    VERIFY_NON_NULL_RET(uuid, TAG, "uuid is null", NULL);
+
+    jclass jni_cid_ParcelUuid = (*env)->FindClass(env, "android/os/ParcelUuid");
+    if (!jni_cid_ParcelUuid)
+    {
+        OIC_LOG(ERROR, TAG, "jni_cid_ParcelUuid is not available");
+        goto error_exit;
+    }
+
+    jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_ParcelUuid,
+                                                             "fromString",
+                                                             "(Ljava/lang/String;)"
+                                                             "Landroid/os/ParcelUuid;");
+    if (!jni_mid_fromString)
+    {
+        OIC_LOG(ERROR, TAG, "jni_mid_fromString is not available");
+        goto error_exit;
+    }
+
+    jstring str_uuid = (*env)->NewStringUTF(env, uuid);
+    if (!str_uuid)
+    {
+        OIC_LOG(ERROR, TAG, "str_uuid is not available");
+        goto error_exit;
+    }
+
+    jobject jni_obj_parcelUuid = (*env)->CallStaticObjectMethod(env, jni_cid_ParcelUuid,
+                                                                jni_mid_fromString,
+                                                                str_uuid);
+    if (!jni_obj_parcelUuid)
+    {
+        OIC_LOG(ERROR, TAG, "Fail to get jni uuid object");
+        goto error_exit;
+    }
+
+    return jni_obj_parcelUuid;
+error_exit:
+    CACheckJNIException(env);
+    return NULL;
 }
 
 bool CALEIsBondedDevice(JNIEnv *env, jobject bluetoothDevice)
@@ -114,7 +165,7 @@ bool CALEIsBondedDevice(JNIEnv *env, jobject bluetoothDevice)
     }
 
     jint jni_bondState = (jint)(*env)->CallIntMethod(env, bluetoothDevice, jni_mid_getBondState);
-
+    CACheckJNIException(env);
     OIC_LOG_V(DEBUG, TAG, "bond state is %d", jni_bondState);
 
     if (BOND_BONDED == jni_bondState)
@@ -139,19 +190,19 @@ jobjectArray CALEGetBondedDevices(JNIEnv *env)
     if (!jni_cid_BTAdapter)
     {
         OIC_LOG(ERROR, TAG, "getBondedDevices: jni_cid_BTAdapter is null");
-        return NULL;
+        goto error_exit;
     }
 
     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
                                                                     "getDefaultAdapter",
                                                                     METHODID_OBJECTNONPARAM);
-
+    CACheckJNIException(env);
     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
                                                                jni_mid_getDefaultAdapter);
     if (!jni_obj_BTAdapter)
     {
         OIC_LOG(ERROR, TAG, "getBondedDevices: bluetooth adapter is null");
-        return NULL;
+        goto error_exit;
     }
 
     // Get a list of currently paired devices
@@ -161,7 +212,7 @@ jobjectArray CALEGetBondedDevices(JNIEnv *env)
     if (!jni_mid_getBondedDevices)
     {
         OIC_LOG(ERROR, TAG, "getBondedDevices: jni_mid_getBondedDevicesr is null");
-        return NULL;
+        goto error_exit;
     }
 
     jobject jni_obj_setPairedDevices = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
@@ -169,7 +220,7 @@ jobjectArray CALEGetBondedDevices(JNIEnv *env)
     if (!jni_obj_setPairedDevices)
     {
         OIC_LOG(ERROR, TAG, "getBondedDevices: jni_obj_setPairedDevices is null");
-        return NULL;
+        goto error_exit;
     }
 
     jmethodID jni_mid_toArray = CAGetJNIMethodID(env, "java/util/Set", "toArray",
@@ -185,10 +236,14 @@ jobjectArray CALEGetBondedDevices(JNIEnv *env)
     if (!jni_arrayPairedDevices)
     {
         OIC_LOG(ERROR, TAG, "getBondedDevices: jni_arrayPairedDevices is null");
-        return NULL;
+        goto error_exit;
     }
 
     return jni_arrayPairedDevices;
+
+error_exit:
+    CACheckJNIException(env);
+    return NULL;
 }
 
 jint CALEGetBTStateOnInfo(JNIEnv *env)
@@ -199,6 +254,7 @@ jint CALEGetBTStateOnInfo(JNIEnv *env)
     if (!jni_cid_BTAdapter)
     {
         OIC_LOG(ERROR, TAG, "getBTStateOnInfo: jni_cid_BTAdapter is null");
+        CACheckJNIException(env);
         return -1;
     }
 
@@ -206,10 +262,12 @@ jint CALEGetBTStateOnInfo(JNIEnv *env)
     if (!jni_fid_stateon)
     {
         OIC_LOG(ERROR, TAG, "get_field_state is not available");
+        CACheckJNIException(env);
         return -1;
     }
 
     jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTAdapter, jni_fid_stateon);
+    CACheckJNIException(env);
     OIC_LOG_V(DEBUG, TAG, "bluetooth.STATE_ON state integer value : %d", jni_int_val);
 
     return jni_int_val;
@@ -236,6 +294,7 @@ jint CALEGetBuildVersion(JNIEnv *env)
     if (!jni_cls_version)
     {
         OIC_LOG(ERROR, TAG, "jni_cls_version is null");
+        CACheckJNIException(env);
         return -1;
     }
 
@@ -243,10 +302,12 @@ jint CALEGetBuildVersion(JNIEnv *env)
     if (!jni_fid_sdk)
     {
         OIC_LOG(ERROR, TAG, "jni_fid_sdk is null");
+        CACheckJNIException(env);
         return -1;
     }
 
     jint jni_int_sdk = (*env)->GetStaticIntField(env, jni_cls_version, jni_fid_sdk);
+    CACheckJNIException(env);
     OIC_LOG_V(DEBUG, TAG, "sdk version is %d", jni_int_sdk);
 
     return jni_int_sdk;
@@ -262,6 +323,7 @@ jint CALEGetBuildVersionCodeForName(JNIEnv *env, const char* versionName)
     if (!jni_cls_version)
     {
         OIC_LOG(ERROR, TAG, "jni_cls_version is null");
+        CACheckJNIException(env);
         return -1;
     }
 
@@ -269,10 +331,12 @@ jint CALEGetBuildVersionCodeForName(JNIEnv *env, const char* versionName)
     if (!jni_fid_version)
     {
         OIC_LOG(ERROR, TAG, "jni_fid_version is null");
+        CACheckJNIException(env);
         return -1;
     }
 
     jint jni_int_version = (*env)->GetStaticIntField(env, jni_cls_version, jni_fid_version);
+    CACheckJNIException(env);
     OIC_LOG_V(DEBUG, TAG, "version [%s] is %d",versionName, jni_int_version);
 
     return jni_int_version;
@@ -286,6 +350,7 @@ jboolean CALEIsEnableBTAdapter(JNIEnv *env)
     if (!jni_cid_BTAdapter)
     {
         OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter: jni_cid_BTAdapter is null");
+        CACheckJNIException(env);
         return JNI_FALSE;
     }
 
@@ -295,6 +360,7 @@ jboolean CALEIsEnableBTAdapter(JNIEnv *env)
     if (!jni_mid_getDefaultAdapter)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
+        CACheckJNIException(env);
         (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
         return JNI_FALSE;
     }
@@ -304,6 +370,7 @@ jboolean CALEIsEnableBTAdapter(JNIEnv *env)
     if (!jni_obj_BTAdapter)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
+        CACheckJNIException(env);
         (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
         return JNI_FALSE;
     }
@@ -313,12 +380,14 @@ jboolean CALEIsEnableBTAdapter(JNIEnv *env)
     if (!jni_mid_isEnable)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_isEnable is null");
+        CACheckJNIException(env);
         (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
         (*env)->DeleteLocalRef(env, jni_obj_BTAdapter);
         return JNI_FALSE;
     }
 
     jboolean jni_isEnable = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter, jni_mid_isEnable);
+    CACheckJNIException(env);
     OIC_LOG_V(DEBUG, TAG, "adapter state is %d", jni_isEnable);
 
     (*env)->DeleteLocalRef(env, jni_cid_BTAdapter);
@@ -345,6 +414,7 @@ jstring CALEGetAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
     if (!jni_address)
     {
         OIC_LOG(ERROR, TAG, "jni_address is null");
+        CACheckJNIException(env);
         return NULL;
     }
 
@@ -361,6 +431,7 @@ jint CALEGetConstantsValue(JNIEnv *env, const char* classType, const char* name)
     if (!jni_cid)
     {
         OIC_LOG(ERROR, TAG, "jni_cid is null");
+        CACheckJNIException(env);
         return -1;
     }
 
@@ -369,15 +440,18 @@ jint CALEGetConstantsValue(JNIEnv *env, const char* classType, const char* name)
     if (!jni_fieldID)
     {
         OIC_LOG(ERROR, TAG, "jni_fieldID is null");
+        CACheckJNIException(env);
         return -1;
     }
 
-    return (*env)->GetStaticIntField(env, jni_cid, jni_fieldID);
+    jint jni_id = (*env)->GetStaticIntField(env, jni_cid, jni_fieldID);
+    CACheckJNIException(env);
+    return jni_id;
 }
 
 jobject CALEGetRemoteDevice(JNIEnv *env, jstring address)
 {
-    OIC_LOG(DEBUG, TAG, "IN - CALEGetRemoteDevice");
+    OIC_LOG(DEBUG, TAG, "CALEGetRemoteDevice");
 
     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
     VERIFY_NON_NULL_RET(address, TAG, "address is null", NULL);
@@ -386,7 +460,7 @@ jobject CALEGetRemoteDevice(JNIEnv *env, jstring address)
     if (!jni_cid_BTAdapter)
     {
         OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
-        return NULL;
+        goto error_exit;
     }
 
     // get remote bt adapter method
@@ -396,7 +470,7 @@ jobject CALEGetRemoteDevice(JNIEnv *env, jstring address)
     if (!jni_mid_getDefaultAdapter)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
-        return NULL;
+        goto error_exit;
     }
 
     // gat bt adapter object
@@ -405,7 +479,7 @@ jobject CALEGetRemoteDevice(JNIEnv *env, jstring address)
     if (!jni_obj_BTAdapter)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
-        return NULL;
+        goto error_exit;
     }
 
     jmethodID jni_mid_getRemoteDevice = (*env)->GetMethodID(env, jni_cid_BTAdapter,
@@ -414,7 +488,7 @@ jobject CALEGetRemoteDevice(JNIEnv *env, jstring address)
     if (!jni_mid_getRemoteDevice)
     {
         OIC_LOG(ERROR, TAG, "jni_mid_getRemoteDevice is null");
-        return NULL;
+        goto error_exit;
     }
 
     jobject jni_obj_device = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
@@ -423,16 +497,18 @@ jobject CALEGetRemoteDevice(JNIEnv *env, jstring address)
     if (!jni_obj_device)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_device is null");
-        return NULL;
+        goto error_exit;
     }
-
-    OIC_LOG(DEBUG, TAG, "OUT - CALEGetRemoteDevice");
     return jni_obj_device;
+
+error_exit:
+    CACheckJNIException(env);
+    return NULL;
 }
 
 jstring CALEGetAddressFromGatt(JNIEnv *env, jobject gatt)
 {
-    OIC_LOG(DEBUG, TAG, "IN - CALEGetAddressFromGatt");
+    OIC_LOG(DEBUG, TAG, "CALEGetAddressFromGatt");
 
     VERIFY_NON_NULL_RET(env, TAG, "env is null", NULL);
     VERIFY_NON_NULL_RET(gatt, TAG, "gatt is null", NULL);
@@ -449,6 +525,7 @@ jstring CALEGetAddressFromGatt(JNIEnv *env, jobject gatt)
     if (!jni_obj_device)
     {
         OIC_LOG(ERROR, TAG, "jni_obj_device is null");
+        CACheckJNIException(env);
         return NULL;
     }
 
@@ -459,6 +536,5 @@ jstring CALEGetAddressFromGatt(JNIEnv *env, jobject gatt)
         return NULL;
     }
 
-    OIC_LOG(DEBUG, TAG, "OUT - CALEGetAddressFromGatt");
     return jni_address;
 }
index dd01468..fef040f 100644 (file)
@@ -52,7 +52,8 @@ static const char CLASSPATH_BT_GATT[] = "android/bluetooth/BluetoothGatt";
 static const char CLASSPATH_BT_ADAPTER[] = "android/bluetooth/BluetoothAdapter";
 static const char CLASSPATH_BT_DEVICE[] = "android/bluetooth/BluetoothDevice";
 static const char CLASSPATH_BT_UUID[] = "java/util/UUID";
-
+static const char CLASSPATH_LE_SCANNER[] = "android/bluetooth/le/BluetoothLeScanner";
+static const char CLASSPATH_LE_SCANSETTINGS[] = "android/bluetooth/le/ScanSettings";
 
 static const char METHODID_OBJECTNONPARAM[] = "()Landroid/bluetooth/BluetoothAdapter;";
 static const char METHODID_BT_DEVICE[] = "()Landroid/bluetooth/BluetoothDevice;";
@@ -69,6 +70,15 @@ static const uint16_t STATE_CONNECTED = 3;
 static const uint16_t STATE_SERVICE_CONNECTED = 2;
 static const uint16_t STATE_DISCONNECTED = 1;
 
+static const uint16_t GATT_ERROR = 133;
+
+static const uint16_t STATE_SEND_NONE = 1;
+static const uint16_t STATE_SEND_SUCCESS = 2;
+static const uint16_t STATE_SEND_FAIL = 3;
+static const uint16_t STATE_SENDING = 4;
+static const uint16_t STATE_SEND_PREPARING = 5;
+static const uint16_t STATE_SEND_MTU_NEGO_SUCCESS = 6;
+
 /**
  * get uuid(jni object) from uuid(character).
  * @param[in]   env              JNI interface pointer.
@@ -86,6 +96,14 @@ jobject CALEGetUuidFromString(JNIEnv *env, const char* uuid);
 jobject CALEGetParcelUuid(JNIEnv *env, jobject uuid);
 
 /**
+ * get parcel uuid object from uuid string value.
+ * @param[in]   env              JNI interface pointer.
+ * @param[in]   uuid             uuid (const char*).
+ * @return  parcel uuid object.
+ */
+jobject CALEGetParcelUuidFromString(JNIEnv *env, const char* uuid);
+
+/**
  * get address from a local device.
  * @param[in]   env              JNI interface pointer.
  * @return  local address.
index d776c4f..6d86fc2 100644 (file)
  ******************************************************************/
 
 #include <jni.h>
-/* Header for class org_iotivity_ca_caLeClientInterface */
+/* Header for class org_iotivity_ca_CaLeClientInterface */
 
-#ifndef CA_Included_org_iotivity_ca_caLeClientInterface_H_
-#define CA_Included_org_iotivity_ca_caLeClientInterface_H_
+#ifndef CA_Included_org_iotivity_ca_CaLeClientInterface_H_
+#define CA_Included_org_iotivity_ca_CaLeClientInterface_H_
 #ifdef __cplusplus
 extern "C"
 {
 #endif
 
 /*
- * Class:     org_iotivity_ca_caLeClientInterface
+ * Class:     org_iotivity_ca_CaLeClientInterface
  * Method:    caLeRegisterLeScanCallback
  * Signature: (Landroid/bluetooth/BluetoothAdapter/LeScanCallback;)V
  */
 JNIEXPORT void JNICALL
-Java_org_iotivity_ca_caLeClientInterface_caLeRegisterLeScanCallback
+Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallback
+(JNIEnv *, jobject, jobject);
+
+/*
+ * Class:     org_iotivity_ca_CaLeClientInterface
+ * Method:    caLeRegisterLeScanCallback
+ * Signature: (Landroid/bluetooth/le/ScanCallback;)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterLeScanCallbackForV21
 (JNIEnv *, jobject, jobject);
 
 /*
@@ -43,47 +52,56 @@ Java_org_iotivity_ca_caLeClientInterface_caLeRegisterLeScanCallback
  * Signature: (Landroid/bluetooth/BluetoothGattCallback;)V
  */
 JNIEXPORT void JNICALL
-Java_org_iotivity_ca_caLeClientInterface_caLeRegisterGattCallback
+Java_org_iotivity_ca_CaLeClientInterface_caLeRegisterGattCallback
 (JNIEnv *, jobject, jobject);
 
 /*
- * Class:     org_iotivity_ca_caLeClientInterface
+ * Class:     org_iotivity_ca_CaLeClientInterface
  * Method:    caLeScanCallback
  * Signature: (Landroid/bluetooth/BluetoothDevice;)V
  */
 JNIEXPORT void JNICALL
-Java_org_iotivity_ca_caLeClientInterface_caLeScanCallback
+Java_org_iotivity_ca_CaLeClientInterface_caLeScanCallback
 (JNIEnv *, jobject, jobject);
 
 /*
+ * Class:     org_iotivity_ca_CaLeClientInterface
+ * Method:    caLeScanFailedCallback
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaLeClientInterface_caLeScanFailedCallback
+(JNIEnv *, jobject, jint);
+
+/*
  * Class:     org_iotivity_ca_caLeClientInterface
  * Method:    caLeGattConnectionStateChangeCallback
  * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
  */
 JNIEXPORT void JNICALL
-Java_org_iotivity_ca_caLeClientInterface_caLeGattConnectionStateChangeCallback
+Java_org_iotivity_ca_CaLeClientInterface_caLeGattConnectionStateChangeCallback
 (JNIEnv *, jobject, jobject, jint, jint);
 
 /*
- * Class:     org_iotivity_ca_caLeClientInterface
+ * Class:     org_iotivity_ca_CaLeClientInterface
  * Method:    caLeGattNWConnectionStateChangeCallback
  * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
  */
 JNIEXPORT void JNICALL
-Java_org_iotivity_ca_caLeClientInterface_caLeGattNWConnectionStateChangeCallback
+Java_org_iotivity_ca_CaLeClientInterface_caLeGattNWConnectionStateChangeCallback
 (JNIEnv *, jobject, jobject, jint, jint);
 
 /*
- * Class:     org_iotivity_ca_caLeClientInterface
+ * Class:     org_iotivity_ca_CaLeClientInterface
  * Method:    caLeGattServicesDiscoveredCallback
  * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
  */
 JNIEXPORT void JNICALL
-Java_org_iotivity_ca_caLeClientInterface_caLeGattServicesDiscoveredCallback
+Java_org_iotivity_ca_CaLeClientInterface_caLeGattServicesDiscoveredCallback
 (JNIEnv *, jobject, jobject, jint);
 
 /*
- * Class:     org_iotivity_ca_caLeClientInterface
+ * Class:     org_iotivity_ca_CaLeClientInterface
  * Method:    caLeGattNWServicesDiscoveredCallback
  * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
  */
@@ -91,52 +109,52 @@ JNIEXPORT void JNICALL
 Java_org_iotivity_ca_CaLeClientInterface_caLeGattNWServicesDiscoveredCallback
 (JNIEnv *, jobject, jobject, jint);
 /*
- * Class:     org_iotivity_ca_caLeClientInterface
+ * Class:     org_iotivity_ca_CaLeClientInterface
  * Method:    caLeGattCharacteristicWritjclasseCallback
  * Signature: (Landroid/bluetooth/BluetoothGatt;[BI)V
  */
 JNIEXPORT void JNICALL
-Java_org_iotivity_ca_caLeClientInterface_caLeGattCharacteristicWriteCallback
+Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicWriteCallback
 (JNIEnv *, jobject, jobject, jbyteArray, jint);
 
 /*
- * Class:     org_iotivity_ca_caLeClientInterface
+ * Class:     org_iotivity_ca_CaLeClientInterface
  * Method:    caLeGattCharacteristicChangedCallback
  * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
  */
 JNIEXPORT void JNICALL
-Java_org_iotivity_ca_caLeClientInterface_caLeGattCharacteristicChangedCallback
+Java_org_iotivity_ca_CaLeClientInterface_caLeGattCharacteristicChangedCallback
 (JNIEnv *, jobject, jobject, jbyteArray);
 
 /*
- * Class:     org_iotivity_ca_caLeClientInterface
+ * Class:     org_iotivity_ca_CaLeClientInterface
  * Method:    caLeGattDescriptorWriteCallback
  * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
  */
 JNIEXPORT void JNICALL
-Java_org_iotivity_ca_caLeClientInterface_caLeGattDescriptorWriteCallback
+Java_org_iotivity_ca_CaLeClientInterface_caLeGattDescriptorWriteCallback
 (JNIEnv *, jobject, jobject, jint);
 
 /*
- * Class:     org_iotivity_ca_caLeClientInterface
+ * Class:     org_iotivity_ca_CaLeClientInterface
  * Method:    caLeStateChangedCallback
  * Signature: (I)V
  */
 JNIEXPORT void JNICALL
-Java_org_iotivity_ca_caLeClientInterface_caLeStateChangedCallback
+Java_org_iotivity_ca_CaLeClientInterface_caLeStateChangedCallback
 (JNIEnv *, jobject, jint);
 
 /*
- * Class:     org_iotivity_ca_caLeClientInterface
+ * Class:     org_iotivity_ca_CaLeClientInterface
  * Method:    caLeBondStateChangedCallback
  * Signature: (Ljava/lang/String;)V
  */
 JNIEXPORT void JNICALL
-Java_org_iotivity_ca_caLeClientInterface_caLeBondStateChangedCallback
+Java_org_iotivity_ca_CaLeClientInterface_caLeBondStateChangedCallback
 (JNIEnv *, jobject, jstring);
 
 /*
- * Class:     org_iotivity_ca_caLeClientInterface
+ * Class:     org_iotivity_ca_CaLeClientInterface
  * Method:    caManagerLeGattConnectionStateChangeCB
  * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
  */
@@ -145,7 +163,7 @@ Java_org_iotivity_ca_CaLeClientInterface_caManagerLeGattConnectionStateChangeCB
 (JNIEnv *, jobject, jobject, jint, jint);
 
 /*
- * Class:     org_iotivity_ca_caLeClientInterface
+ * Class:     org_iotivity_ca_CaLeClientInterface
  * Method:    caManagerAdapterStateChangedCallback
  * Signature: (I)V
  */
@@ -154,7 +172,7 @@ Java_org_iotivity_ca_CaLeClientInterface_caManagerAdapterStateChangedCallback
 (JNIEnv *, jobject, jint);
 
 /*
- * Class:     org_iotivity_ca_caLeClientInterface
+ * Class:     org_iotivity_ca_CaLeClientInterface
  * Method:    caManagerBondStateChangedCallback
  * Signature: (Landroid/bluetooth/BluetoothDevice;)V
  */
@@ -163,7 +181,7 @@ Java_org_iotivity_ca_CaLeClientInterface_caManagerBondStateChangedCallback
 (JNIEnv *, jobject, jobject);
 
 /*
- * Class:     org_iotivity_ca_jar_caleinterface
+ * Class:     org_iotivity_ca_CaLeClientInterface
  * Method:    caManagerLeServicesDiscoveredCallback
  * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
  */
@@ -172,7 +190,7 @@ Java_org_iotivity_ca_CaLeClientInterface_caManagerLeServicesDiscoveredCallback
 (JNIEnv *, jobject, jobject, jint);
 
 /*
- * Class:     org_iotivity_ca_jar_caleinterface
+ * Class:     org_iotivity_ca_CaLeClientInterface
  * Method:    caManagerLeRemoteRssiCallback
  * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
  */
@@ -180,6 +198,16 @@ JNIEXPORT void JNICALL
 Java_org_iotivity_ca_CaLeClientInterface_caManagerLeRemoteRssiCallback
 (JNIEnv *, jobject, jobject, jint, jint);
 
+/*
+ * Class:     org_iotivity_ca_CaLeClientInterface
+ * Method:    caLeGattMtuChangedCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaLeClientInterface_caLeGattMtuChangedCallback
+(JNIEnv *, jobject, jobject, jint, jint);
+
+
 #ifdef __cplusplus
 }
 #endif
index e00b788..904d1a7 100644 (file)
  ******************************************************************/
 
 #include <jni.h>
-/* Header for class org_iotivity_ca_caLeServerInterface */
+/* Header for class org_iotivity_ca_CaLeServerInterface */
 
-#ifndef CA_Included_org_iotivity_ca_caLeServerInterface_H_
-#define CA_Included_org_iotivity_ca_caLeServerInterface_H_
+#ifndef CA_Included_org_iotivity_ca_CaLeServerInterface_H_
+#define CA_Included_org_iotivity_ca_CaLeServerInterface_H_
 #ifdef __cplusplus
 extern "C"
 {
 #endif
 
 /*
- * Class:     org_iotivity_ca_caLeServerInterface
+ * Class:     org_iotivity_ca_CaLeServerInterface
  * Method:    caLeRegisterGattServerCallback
  * Signature: (Landroid/bluetooth/BluetoothGattServerCallback;)V
  */
 JNIEXPORT void JNICALL
-Java_org_iotivity_ca_caLeServerInterface_caLeRegisterGattServerCallback
+Java_org_iotivity_ca_CaLeServerInterface_caLeRegisterGattServerCallback
 (JNIEnv *, jobject, jobject);
 
 /*
- * Class:     org_iotivity_ca_caLeServerInterface
+ * Class:     org_iotivity_ca_CaLeServerInterface
  * Method:    caLeRegisterBluetoothLeAdvertiseCallback
  * Signature: (Landroid/bluetooth/le/AdvertiseCallback;)V
  */
 JNIEXPORT void JNICALL
-Java_org_iotivity_ca_caLeServerInterface_caLeRegisterBluetoothLeAdvertiseCallback
+Java_org_iotivity_ca_CaLeServerInterface_caLeRegisterBluetoothLeAdvertiseCallback
 (JNIEnv *, jobject, jobject);
 
 /*
- * Class:     org_iotivity_ca_caLeServerInterface
+ * Class:     org_iotivity_ca_CaLeServerInterface
  * Method:    caLeGattServerConnectionStateChangeCallback
  * Signature: (Landroid/bluetooth/BluetoothDevice;II)V
  */
 JNIEXPORT void JNICALL
-Java_org_iotivity_ca_caLeServerInterface_caLeGattServerConnectionStateChangeCallback
+Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerConnectionStateChangeCallback
 (JNIEnv *, jobject, jobject, jint, jint);
 
 /*
- * Class:     org_iotivity_ca_caLeServerInterface
+ * Class:     org_iotivity_ca_CaLeServerInterface
  * Method:    caLeGattServerNWConnectionStateChangeCallback
  * Signature: (Landroid/bluetooth/BluetoothDevice;II)V
  */
 JNIEXPORT void JNICALL
-Java_org_iotivity_ca_caLeServerInterface_caLeGattServerNWConnectionStateChangeCallback
+Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerNWConnectionStateChangeCallback
 (JNIEnv *, jobject, jobject, jint, jint);
 
 /*
- * Class:     org_iotivity_ca_caLeServerInterface
+ * Class:     org_iotivity_ca_CaLeServerInterface
  * Method:    caLeGattServerServiceAddedCallback
  * Signature: (ILandroid/bluetooth/BluetoothGattService;)V
  */
 JNIEXPORT void JNICALL
-Java_org_iotivity_ca_caLeServerInterface_caLeGattServerServiceAddedCallback
+Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerServiceAddedCallback
 (JNIEnv *, jobject, jint, jobject);
 
 /*
- * Class:     org_iotivity_ca_caLeServerInterface
+ * Class:     org_iotivity_ca_CaLeServerInterface
  * Method:    caLeGattServerCharacteristicReadRequestCallback
  * Signature: (Landroid/bluetooth/BluetoothDevice;[B)V
  */
 JNIEXPORT void JNICALL
-Java_org_iotivity_ca_caLeServerInterface_caLeGattServerCharacteristicReadRequestCallback
+Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerCharacteristicReadRequestCallback
 (JNIEnv *, jobject, jobject, jbyteArray);
 
 /*
- * Class:     org_iotivity_ca_caLeServerInterface
+ * Class:     org_iotivity_ca_CaLeServerInterface
  * Method:    caLeGattServerCharacteristicWriteRequestCallback
- * Signature: (Landroid/bluetooth/BluetoothDevice;[B)V
+ * Signature: (Landroid/bluetooth/BluetoothDevice;[BII[B)V
  */
 JNIEXPORT void JNICALL
-Java_org_iotivity_ca_caLeServerInterface_caLeGattServerCharacteristicWriteRequestCallback
-(JNIEnv *, jobject, jobject, jbyteArray);
+Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerCharacteristicWriteRequestCallback
+(JNIEnv *, jobject, jobject, jbyteArray, jint, jint, jbyteArray);
 
 /*
- * Class:     org_iotivity_ca_caLeServerInterface
+ * Class:     org_iotivity_ca_CaLeServerInterface
  * Method:    caLeGattServerNotificationSentCallback
  * Signature: (Landroid/bluetooth/BluetoothDevice;I)V
  */
 JNIEXPORT void JNICALL
-Java_org_iotivity_ca_caLeServerInterface_caLeGattServerNotificationSentCallback
+Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerNotificationSentCallback
 (JNIEnv *, jobject, jobject, jint);
 
 /*
- * Class:     org_iotivity_ca_caLeServerInterface
+ * Class:     org_iotivity_ca_CaLeServerInterface
  * Method:    caLeAdvertiseStartSuccessCallback
  * Signature: (Landroid/bluetooth/le/AdvertiseSettings;)V
  */
 JNIEXPORT void JNICALL
-Java_org_iotivity_ca_caLeServerInterface_caLeAdvertiseStartSuccessCallback
+Java_org_iotivity_ca_CaLeServerInterface_caLeAdvertiseStartSuccessCallback
 (JNIEnv *, jobject, jobject);
 
 /*
- * Class:     org_iotivity_ca_caLeServerInterface
+ * Class:     org_iotivity_ca_CaLeServerInterface
  * Method:    caLeAdvertiseStartFailureCallback
  * Signature: (I)V
  */
 JNIEXPORT void JNICALL
-Java_org_iotivity_ca_caLeServerInterface_caLeAdvertiseStartFailureCallback
+Java_org_iotivity_ca_CaLeServerInterface_caLeAdvertiseStartFailureCallback
 (JNIEnv *, jobject, jint);
 
+/*
+ * Class:     org_iotivity_ca_CaLeServerInterface
+ * Method:    caLeGattServerMtuChangedCallback
+ * Signature: (Landroid/bluetooth/BluetoothDevice;I)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_ca_CaLeServerInterface_caLeGattServerMtuChangedCallback
+(JNIEnv *, jobject, jobject, jint);
 
 #ifdef __cplusplus
 }
old mode 100644 (file)
new mode 100755 (executable)
index 04703a9..3176f83
 
 #include "caleinterface.h"
 #include "cacommon.h"
-#include "camutex.h"
+#include "octhread.h"
 #include "caadapterutils.h"
+#ifdef __WITH_DTLS__
+#include "ca_adapter_net_ssl.h"
+#endif
 #ifndef SINGLE_THREAD
 #include "caqueueingthread.h"
 #endif
@@ -48,8 +51,7 @@
 /**
  * Stores information of all the senders.
  *
- * This structure will be used to track and defragment all incoming
- * data packet.
+ * This structure will be used to track and defragment all incoming data packet.
  */
 typedef struct
 {
@@ -68,6 +70,11 @@ typedef enum
 } CABLEAdapter_t;
 
 /**
+ * mtu size to use in fragmentation logic.
+ * default value is 20 byte.
+ */
+static uint16_t g_mtuSize = CA_DEFAULT_BLE_MTU_SIZE;
+/**
  * Callback to provide the status of the network change to CA layer.
  */
 static CAAdapterChangeCallback g_networkCallback = NULL;
@@ -93,23 +100,27 @@ static char g_localBLEAddress[18] = { 0 };
  */
 static CABLEAdapter_t g_adapterType = ADAPTER_EMPTY;
 
+#ifdef __WITH_DTLS__
+static CADataType_t g_dataType = CA_REQUEST_DATA;
+#endif
+
 /**
  * Mutex to synchronize the task to be executed on the GattServer
  * function calls.
  */
-static ca_mutex g_bleIsServerMutex = NULL;
+static oc_mutex g_bleIsServerMutex = NULL;
 
 /**
  * Mutex to synchronize the callback to be called for the network
  * changes.
  */
-static ca_mutex g_bleNetworkCbMutex = NULL;
+static oc_mutex g_bleNetworkCbMutex = NULL;
 
 /**
  * Mutex to synchronize the updates of the local LE address of the
  * adapter.
  */
-static ca_mutex g_bleLocalAddressMutex = NULL;
+static oc_mutex g_bleLocalAddressMutex = NULL;
 
 /**
  * Reference to thread pool.
@@ -119,28 +130,33 @@ static ca_thread_pool_t g_bleAdapterThreadPool = NULL;
 /**
  * Mutex to synchronize the task to be pushed to thread pool.
  */
-static ca_mutex g_bleAdapterThreadPoolMutex = NULL;
+static oc_mutex g_bleAdapterThreadPoolMutex = NULL;
 
 /**
  * Mutex to synchronize the queing of the data from SenderQueue.
  */
-static ca_mutex g_bleClientSendDataMutex = NULL;
+static oc_mutex g_bleClientSendDataMutex = NULL;
 
 /**
  * Mutex to synchronize the queing of the data from ReceiverQueue.
  */
-static ca_mutex g_bleReceiveDataMutex = NULL;
+static oc_mutex g_bleClientReceiveDataMutex = NULL;
 
 /**
  * Mutex to synchronize the queing of the data from SenderQueue.
  */
-static ca_mutex g_bleServerSendDataMutex = NULL;
+static oc_mutex g_bleServerSendDataMutex = NULL;
+
+/**
+ * Mutex to synchronize the queing of the data from ReceiverQueue.
+ */
+static oc_mutex g_bleServerReceiveDataMutex = NULL;
 
 /**
  * Mutex to synchronize the callback to be called for the
  * adapterReqResponse.
  */
-static ca_mutex g_bleAdapterReqRespCbMutex = NULL;
+static oc_mutex g_bleAdapterReqRespCbMutex = NULL;
 
 /**
  * Callback to be called when network packet received from either
@@ -153,6 +169,14 @@ static CANetworkPacketReceivedCallback g_networkPacketReceivedCallback = NULL;
  */
 static CAErrorHandleCallback g_errorHandler = NULL;
 
+#ifdef __WITH_DTLS__
+static void CALESecureReceiveDataCB(const CASecureEndpoint_t *endpoint,
+                                 const void *data, size_t dataLength);
+
+static ssize_t CALESecureSendDataCB(CAEndpoint_t *endpoint,
+                             const void *data, size_t dataLength);
+#endif
+
 #ifdef SINGLE_THREAD
 /**
  * Pointer to defragment received data from single threaded routine.
@@ -263,31 +287,44 @@ static void CALEErrorHandler(const char *remoteAddress,
 
 #ifndef SINGLE_THREAD
 /**
- * Stop condition of recvhandler.
+ * Stop condition of Server recvhandler.
  */
-static bool g_dataBleReceiverHandlerState = false;
+static bool g_dataBleServerReceiverHandlerState = false;
 
 /**
- * Sender information.
+ * Stop condition of Client recvhandler.
+ */
+static bool g_dataBleClientReceiverHandlerState = false;
+
+/**
+ * Sender information of Server.
  */
 static u_arraylist_t *g_bleServerSenderInfo = NULL;
 
+/**
+ * Sender information of Client.
+ */
 static u_arraylist_t *g_bleClientSenderInfo = NULL;
 
 /**
+ * Queue to process the outgoing packets from GATTServer.
+ */
+static CAQueueingThread_t *g_bleServerSendQueueHandle = NULL;
+
+/**
  * Queue to process the outgoing packets from GATTClient.
  */
 static CAQueueingThread_t *g_bleClientSendQueueHandle = NULL;
 
 /**
- * Queue to process the incoming packets.
+ * Queue to process the incoming packets from GATTServer.
  */
-static CAQueueingThread_t *g_bleReceiverQueue = NULL;
+static CAQueueingThread_t *g_bleServerReceiverQueue = NULL;
 
 /**
- * Queue to process the outgoing packets from GATTServer.
+ * Queue to process the incoming packets from GATTClient.
  */
-static CAQueueingThread_t *g_bleServerSendQueueHandle = NULL;
+static CAQueueingThread_t *g_bleClientReceiverQueue = NULL;
 
 /**
  * This function will be associated with the sender queue for
@@ -316,16 +353,39 @@ static void CALEServerSendDataThread(void *threadData);
 static void CALEClientSendDataThread(void *threadData);
 
 /**
- * This function will be associated with the receiver queue.
- *
  * This function will defragment the received data from each sender
  * respectively and will send it up to CA layer.  Respective sender's
  * header will provide the length of the data sent.
  *
+ * @param[in] threadData   Data pushed to the queue which contains the
+ *                         info about RemoteEndpoint and Data.
+ * @param[in] receiverType Whether receiver is server or client.
+ */
+static void CALEDataReceiverHandler(void *threadData, CABLEAdapter_t receiverType);
+
+/**
+ * This function will be associated with the receiver queue for
+ * GattServer.
+ *
+ * This function will call the function CALEDataReceiverHandler()
+ * with server type to defragment the received data.
+ *
  * @param[in] threadData Data pushed to the queue which contains the
  *                       info about RemoteEndpoint and Data.
  */
-static void CALEDataReceiverHandler(void *threadData);
+static void CALEServerDataReceiverHandler(void *threadData);
+
+/**
+ * This function will be associated with the receiver queue for
+ * GattClient.
+ *
+ * This function will call the function CALEDataReceiverHandler()
+ * with client type to defragment the received data.
+ *
+ * @param[in] threadData Data pushed to the queue which contains the
+ *                       info about RemoteEndpoint and Data.
+ */
+static void CALEClientDataReceiverHandler(void *threadData);
 
 /**
  * This function will stop all queues created for GattServer and
@@ -396,8 +456,8 @@ static CAResult_t CAInitLEClientSenderQueue();
 
 /**
  * This function will initialize the Receiver queue for
- * LEAdapter. This will initialize the queue to process the function
- * CABLEDataReceiverHandler() when ever the task is added to this
+ * GattServer. This will initialize the queue to process the function
+ * CALEServerDataReceiverHandler() when ever the task is added to this
  * queue.
  *
  * @return ::CA_STATUS_OK or Appropriate error code
@@ -406,7 +466,21 @@ static CAResult_t CAInitLEClientSenderQueue();
  * @retval ::CA_STATUS_FAILED Operation failed
  *
  */
-static CAResult_t CAInitLEReceiverQueue();
+static CAResult_t CAInitLEServerReceiverQueue();
+
+/**
+ * This function will initialize the Receiver queue for
+ * GattClient. This will initialize the queue to process the function
+ * CALEClientDataReceiverHandler() 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 arguments
+ * @retval ::CA_STATUS_FAILED Operation failed
+ *
+ */
+static CAResult_t CAInitLEClientReceiverQueue();
 
 /**
  * This function will create the Data required to send it in the
@@ -449,7 +523,7 @@ static void CALEDataDestroyer(void *data, uint32_t size);
  * @param[in] address        target address to remove data in queue.
  */
 static void CALERemoveSendQueueData(CAQueueingThread_t *queueHandle,
-                                    ca_mutex mutex,
+                                    oc_mutex mutex,
                                     const char* address);
 
 /**
@@ -495,15 +569,13 @@ static CAResult_t CALEGetPortsFromSenderInfo(const char *leAddress,
 
 static CAResult_t CAInitLEServerQueues()
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
-
-    ca_mutex_lock(g_bleAdapterThreadPoolMutex);
+    oc_mutex_lock(g_bleAdapterThreadPoolMutex);
 
     CAResult_t result = CAInitLEServerSenderQueue();
     if (CA_STATUS_OK != result)
     {
         OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleServerSenderQueue failed");
-        ca_mutex_unlock(g_bleAdapterThreadPoolMutex);
+        oc_mutex_unlock(g_bleAdapterThreadPoolMutex);
         return CA_STATUS_FAILED;
     }
 
@@ -511,38 +583,34 @@ static CAResult_t CAInitLEServerQueues()
     if (!g_bleServerSenderInfo)
     {
         OIC_LOG(ERROR, CALEADAPTER_TAG, "memory allocation failed!");
-        ca_mutex_unlock(g_bleAdapterThreadPoolMutex);
+        oc_mutex_unlock(g_bleAdapterThreadPoolMutex);
         return CA_MEMORY_ALLOC_FAILED;
     }
 
-    result = CAInitLEReceiverQueue();
+    result = CAInitLEServerReceiverQueue();
     if (CA_STATUS_OK != result)
     {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitLEReceiverQueue failed");
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitLEServerReceiverQueue failed");
         u_arraylist_free(&g_bleServerSenderInfo);
-        ca_mutex_unlock(g_bleAdapterThreadPoolMutex);
+        oc_mutex_unlock(g_bleAdapterThreadPoolMutex);
         return CA_STATUS_FAILED;
     }
 
-    g_dataBleReceiverHandlerState = true;
+    g_dataBleServerReceiverHandlerState = true;
 
-    ca_mutex_unlock(g_bleAdapterThreadPoolMutex);
-
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+    oc_mutex_unlock(g_bleAdapterThreadPoolMutex);
     return CA_STATUS_OK;
 }
 
 static CAResult_t CAInitLEClientQueues()
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
-
-    ca_mutex_lock(g_bleAdapterThreadPoolMutex);
+    oc_mutex_lock(g_bleAdapterThreadPoolMutex);
 
     CAResult_t result = CAInitLEClientSenderQueue();
     if (CA_STATUS_OK != result)
     {
         OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitBleClientSenderQueue failed");
-        ca_mutex_unlock(g_bleAdapterThreadPoolMutex);
+        oc_mutex_unlock(g_bleAdapterThreadPoolMutex);
         return CA_STATUS_FAILED;
     }
 
@@ -550,71 +618,108 @@ static CAResult_t CAInitLEClientQueues()
     if (!g_bleClientSenderInfo)
     {
         OIC_LOG(ERROR, CALEADAPTER_TAG, "memory allocation failed!");
-        ca_mutex_unlock(g_bleAdapterThreadPoolMutex);
+        oc_mutex_unlock(g_bleAdapterThreadPoolMutex);
         return CA_MEMORY_ALLOC_FAILED;
     }
 
-    result = CAInitLEReceiverQueue();
+    result = CAInitLEClientReceiverQueue();
     if (CA_STATUS_OK != result)
     {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitLEReceiverQueue failed");
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "CAInitLEClientReceiverQueue failed");
         u_arraylist_free(&g_bleClientSenderInfo);
-        ca_mutex_unlock(g_bleAdapterThreadPoolMutex);
+        oc_mutex_unlock(g_bleAdapterThreadPoolMutex);
         return CA_STATUS_FAILED;
     }
 
-    g_dataBleReceiverHandlerState = true;
+    g_dataBleClientReceiverHandlerState = true;
 
-    ca_mutex_unlock(g_bleAdapterThreadPoolMutex);
+    oc_mutex_unlock(g_bleAdapterThreadPoolMutex);
+    return CA_STATUS_OK;
+}
+
+static CAResult_t CAInitLEServerReceiverQueue()
+{
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__);
+    // Check if the message queue is already initialized
+    if (g_bleServerReceiverQueue)
+    {
+        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Already queue is initialized!");
+        return CA_STATUS_OK;
+    }
+
+    // Create recv message queue
+    g_bleServerReceiverQueue = (CAQueueingThread_t *) OICMalloc(sizeof(CAQueueingThread_t));
+    if (!g_bleServerReceiverQueue)
+    {
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed!");
+        return CA_MEMORY_ALLOC_FAILED;
+    }
+
+    if (CA_STATUS_OK != CAQueueingThreadInitialize(g_bleServerReceiverQueue,
+                                                   g_bleAdapterThreadPool,
+                                                   CALEServerDataReceiverHandler,
+                                                   CALEDataDestroyer))
+    {
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to Initialize server receiver queue thread");
+        OICFree(g_bleServerReceiverQueue);
+        g_bleServerReceiverQueue = NULL;
+        return CA_STATUS_FAILED;
+    }
+
+    if (CA_STATUS_OK != CAQueueingThreadStart(g_bleServerReceiverQueue))
+    {
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_thread_pool_add_task failed ");
+        OICFree(g_bleServerReceiverQueue);
+        g_bleServerReceiverQueue = NULL;
+        return CA_STATUS_FAILED;
+    }
 
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
     return CA_STATUS_OK;
 }
 
-static CAResult_t CAInitLEReceiverQueue()
+static CAResult_t CAInitLEClientReceiverQueue()
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN - CAInitLEReceiverQueue");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__);
     // Check if the message queue is already initialized
-    if (g_bleReceiverQueue)
+    if (g_bleClientReceiverQueue)
     {
         OIC_LOG(DEBUG, CALEADAPTER_TAG, "Already queue is initialized!");
         return CA_STATUS_OK;
     }
 
     // Create recv message queue
-    g_bleReceiverQueue = (CAQueueingThread_t *) OICMalloc(sizeof(CAQueueingThread_t));
-    if (!g_bleReceiverQueue)
+    g_bleClientReceiverQueue = (CAQueueingThread_t *) OICMalloc(sizeof(CAQueueingThread_t));
+    if (!g_bleClientReceiverQueue)
     {
         OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed!");
         return CA_MEMORY_ALLOC_FAILED;
     }
 
-    if (CA_STATUS_OK != CAQueueingThreadInitialize(g_bleReceiverQueue,
+    if (CA_STATUS_OK != CAQueueingThreadInitialize(g_bleClientReceiverQueue,
                                                    g_bleAdapterThreadPool,
-                                                   CALEDataReceiverHandler,
+                                                   CALEClientDataReceiverHandler,
                                                    CALEDataDestroyer))
     {
-        OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to Initialize send queue thread");
-        OICFree(g_bleReceiverQueue);
-        g_bleReceiverQueue = NULL;
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to Initialize client receiver queue thread");
+        OICFree(g_bleClientReceiverQueue);
+        g_bleClientReceiverQueue = NULL;
         return CA_STATUS_FAILED;
     }
 
-    if (CA_STATUS_OK != CAQueueingThreadStart(g_bleReceiverQueue))
+    if (CA_STATUS_OK != CAQueueingThreadStart(g_bleClientReceiverQueue))
     {
         OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_thread_pool_add_task failed ");
-        OICFree(g_bleReceiverQueue);
-        g_bleReceiverQueue = NULL;
+        OICFree(g_bleClientReceiverQueue);
+        g_bleClientReceiverQueue = NULL;
         return CA_STATUS_FAILED;
     }
 
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
     return CA_STATUS_OK;
 }
 
 static CAResult_t CAInitLEServerSenderQueue()
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN - CAInitLEServerSenderQueue");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__);
     // Check if the message queue is already initialized
     if (g_bleServerSendQueueHandle)
     {
@@ -641,7 +746,6 @@ static CAResult_t CAInitLEServerSenderQueue()
         return CA_STATUS_FAILED;
     }
 
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
     return CA_STATUS_OK;
 }
 
@@ -670,7 +774,7 @@ static void CALEClearSenderInfo()
 
 static CAResult_t CAInitLEClientSenderQueue()
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN - CAInitLEClientSenderQueue");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__);
 
     if (g_bleClientSendQueueHandle)
     {
@@ -695,29 +799,32 @@ static CAResult_t CAInitLEClientSenderQueue()
         g_bleClientSendQueueHandle = NULL;
         return CA_STATUS_FAILED;
     }
-
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT - CAInitLEClientSenderQueue");
     return CA_STATUS_OK;
 }
 
 static void CAStopLEQueues()
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN - CAStopLEQueues");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__);
 
-    ca_mutex_lock(g_bleReceiveDataMutex);
-    if (NULL != g_bleReceiverQueue)
+    oc_mutex_lock(g_bleServerReceiveDataMutex);
+    if (NULL != g_bleServerReceiverQueue)
     {
-        CAQueueingThreadStop(g_bleReceiverQueue);
+        CAQueueingThreadStop(g_bleServerReceiverQueue);
     }
-    ca_mutex_unlock(g_bleReceiveDataMutex);
+    oc_mutex_unlock(g_bleServerReceiveDataMutex);
 
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT - CAStopLEQueues");
+    oc_mutex_lock(g_bleClientReceiveDataMutex);
+    if (NULL != g_bleClientReceiverQueue)
+    {
+        CAQueueingThreadStop(g_bleClientReceiverQueue);
+    }
+    oc_mutex_unlock(g_bleClientReceiveDataMutex);
+
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__);
 }
 
 static void CATerminateLEQueues()
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
-
     CAQueueingThreadDestroy(g_bleClientSendQueueHandle);
     OICFree(g_bleClientSendQueueHandle);
     g_bleClientSendQueueHandle = NULL;
@@ -726,13 +833,15 @@ static void CATerminateLEQueues()
     OICFree(g_bleServerSendQueueHandle);
     g_bleServerSendQueueHandle = NULL;
 
-    CAQueueingThreadDestroy(g_bleReceiverQueue);
-    OICFree(g_bleReceiverQueue);
-    g_bleReceiverQueue = NULL;
+    CAQueueingThreadDestroy(g_bleServerReceiverQueue);
+    OICFree(g_bleServerReceiverQueue);
+    g_bleServerReceiverQueue = NULL;
 
-    CALEClearSenderInfo();
+    CAQueueingThreadDestroy(g_bleClientReceiverQueue);
+    OICFree(g_bleClientReceiverQueue);
+    g_bleClientReceiverQueue = NULL;
 
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+    CALEClearSenderInfo();
 }
 
 static CAResult_t CALEGetSenderInfo(const char *leAddress,
@@ -777,35 +886,51 @@ static CAResult_t CALEGetSenderInfo(const char *leAddress,
     return CA_STATUS_FAILED;
 }
 
-static void CALEDataReceiverHandler(void *threadData)
+static void CALEDataReceiverHandler(void *threadData, CABLEAdapter_t receiverType)
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN - CALEDataReceiverHandler");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__);
 
-    ca_mutex_lock(g_bleReceiveDataMutex);
+    oc_mutex bleReceiveDataMutex = NULL;
+    bool dataBleReceiverHandlerState = false;
 
-    if (g_dataBleReceiverHandlerState)
+    switch (receiverType)
     {
-        OIC_LOG(DEBUG, CALEADAPTER_TAG, "checking for DE Fragmentation");
+        case ADAPTER_CLIENT:
+            bleReceiveDataMutex = g_bleClientReceiveDataMutex;
+            dataBleReceiverHandlerState = g_dataBleClientReceiverHandlerState;
+            break;
+        case ADAPTER_SERVER:
+            bleReceiveDataMutex = g_bleServerReceiveDataMutex;
+            dataBleReceiverHandlerState = g_dataBleServerReceiverHandlerState;
+            break;
+        default:
+            OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Unsupported receiver type : %d", receiverType);
+            return;
+    }
+
+    oc_mutex_lock(bleReceiveDataMutex);
 
+    if (dataBleReceiverHandlerState)
+    {
         CALEData_t *bleData = (CALEData_t *) threadData;
         if (!bleData)
         {
             OIC_LOG(DEBUG, CALEADAPTER_TAG, "Invalid bleData!");
-            ca_mutex_unlock(g_bleReceiveDataMutex);
+            oc_mutex_unlock(bleReceiveDataMutex);
             return;
         }
 
         if (!(bleData->senderInfo))
         {
             OIC_LOG(ERROR, CALEADAPTER_TAG, "sender info is not available");
-            ca_mutex_unlock(g_bleReceiveDataMutex);
+            oc_mutex_unlock(bleReceiveDataMutex);
             return;
         }
 
         if (!(bleData->remoteEndpoint))
         {
-            OIC_LOG(ERROR, CALEADAPTER_TAG, "Client RemoteEndPoint NULL!!");
-            ca_mutex_unlock(g_bleReceiveDataMutex);
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "RemoteEndPoint NULL!!");
+            oc_mutex_unlock(bleReceiveDataMutex);
             return;
         }
 
@@ -819,7 +944,7 @@ static void CALEDataReceiverHandler(void *threadData)
         uint16_t destPort = 0;
 
         CAParseHeader(bleData->data, &startFlag, &sourcePort, &secureFlag, &destPort);
-        OIC_LOG_V(DEBUG, CALEADAPTER_TAG,
+        OIC_LOG_V(INFO, CALEADAPTER_TAG,
                   "header info: startFlag[%X] sourcePort[%d] secureFlag[%X] destPort[%d]",
                   startFlag, sourcePort, secureFlag, destPort);
 
@@ -828,7 +953,7 @@ static void CALEDataReceiverHandler(void *threadData)
             OIC_LOG_V(ERROR, CALEADAPTER_TAG,
                       "this packet is not valid for this app(port mismatch[mine:%d, packet:%d])",
                       g_localBLESourcePort, destPort);
-            ca_mutex_unlock(g_bleReceiveDataMutex);
+            oc_mutex_unlock(bleReceiveDataMutex);
             return;
         }
 
@@ -866,7 +991,7 @@ static void CALEDataReceiverHandler(void *threadData)
             else
             {
                 OIC_LOG(ERROR, CALEADAPTER_TAG, "This packet is wrong packet! ignore.");
-                ca_mutex_unlock(g_bleReceiveDataMutex);
+                oc_mutex_unlock(bleReceiveDataMutex);
                 return;
             }
 
@@ -874,7 +999,7 @@ static void CALEDataReceiverHandler(void *threadData)
             if (!newSender)
             {
                 OIC_LOG(ERROR, CALEADAPTER_TAG, "Memory allocation failed for new sender");
-                ca_mutex_unlock(g_bleReceiveDataMutex);
+                oc_mutex_unlock(bleReceiveDataMutex);
                 return;
             }
             newSender->recvDataLen = 0;
@@ -890,15 +1015,15 @@ static void CALEDataReceiverHandler(void *threadData)
             {
                 OIC_LOG(ERROR, CALEADAPTER_TAG, "Total Data Length is parsed as 0!!!");
                 OICFree(newSender);
-                ca_mutex_unlock(g_bleReceiveDataMutex);
+                oc_mutex_unlock(bleReceiveDataMutex);
                 return;
             }
 
             size_t dataOnlyLen =
                 bleData->dataLen - (CA_BLE_HEADER_SIZE + CA_BLE_LENGTH_HEADER_SIZE);
-            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Total data to be accumulated [%u] bytes",
+            OIC_LOG_V(INFO, CALEADAPTER_TAG, "Total data to be accumulated [%u] bytes",
                       newSender->totalDataLen);
-            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "data received in the first packet [%zu] bytes",
+            OIC_LOG_V(INFO, CALEADAPTER_TAG, "data received in the first packet [%zu] bytes",
                       dataOnlyLen);
 
             newSender->defragData = OICCalloc(newSender->totalDataLen + 1,
@@ -908,12 +1033,19 @@ static void CALEDataReceiverHandler(void *threadData)
             {
                 OIC_LOG(ERROR, CALEADAPTER_TAG, "defragData is NULL!");
                 OICFree(newSender);
-                ca_mutex_unlock(g_bleReceiveDataMutex);
+                oc_mutex_unlock(bleReceiveDataMutex);
                 return;
             }
+            CATransportFlags_t flags = CA_DEFAULT_FLAGS;
+#ifdef __WITH_DTLS__
+            if (CA_BLE_PACKET_SECURE == secureFlag)
+            {
+                flags |= CA_SECURE;
+            }
+#endif
 
             const char *remoteAddress = bleData->remoteEndpoint->addr;
-            newSender->remoteEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
+            newSender->remoteEndpoint = CACreateEndpointObject(flags,
                                                                CA_ADAPTER_GATT_BTLE,
                                                                remoteAddress,
                                                                bleData->remoteEndpoint->port);
@@ -923,7 +1055,7 @@ static void CALEDataReceiverHandler(void *threadData)
                 OIC_LOG(ERROR, CALEADAPTER_TAG, "remoteEndpoint is NULL!");
                 OICFree(newSender->defragData);
                 OICFree(newSender);
-                ca_mutex_unlock(g_bleReceiveDataMutex);
+                oc_mutex_unlock(bleReceiveDataMutex);
                 return;
             }
 
@@ -933,7 +1065,7 @@ static void CALEDataReceiverHandler(void *threadData)
                 OICFree(newSender->defragData);
                 CAFreeEndpoint(newSender->remoteEndpoint);
                 OICFree(newSender);
-                ca_mutex_unlock(g_bleReceiveDataMutex);
+                oc_mutex_unlock(bleReceiveDataMutex);
                 return;
             }
             memcpy(newSender->defragData,
@@ -954,7 +1086,7 @@ static void CALEDataReceiverHandler(void *threadData)
                 OICFree(newSender->defragData);
                 CAFreeEndpoint(newSender->remoteEndpoint);
                 OICFree(newSender);
-                ca_mutex_unlock(g_bleReceiveDataMutex);
+                oc_mutex_unlock(bleReceiveDataMutex);
                 return;
             }
             senderInfo = newSender;
@@ -970,7 +1102,7 @@ static void CALEDataReceiverHandler(void *threadData)
                 u_arraylist_remove(bleData->senderInfo, senderIndex);
                 OICFree(senderInfo->defragData);
                 OICFree(senderInfo);
-                ca_mutex_unlock(g_bleReceiveDataMutex);
+                oc_mutex_unlock(bleReceiveDataMutex);
                 return;
             }
             OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Copying the data of length [%zu]",
@@ -979,13 +1111,13 @@ static void CALEDataReceiverHandler(void *threadData)
                    bleData->data + CA_BLE_HEADER_SIZE,
                    dataOnlyLen);
             senderInfo->recvDataLen += dataOnlyLen;
-            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "totalDatalength  [%d] received Datalen [%d]",
-                                                senderInfo->totalDataLen, senderInfo->recvDataLen);
+            OIC_LOG_V(INFO, CALEADAPTER_TAG, "totalDatalength  [%d] received Datalen [%d]",
+                      senderInfo->totalDataLen, senderInfo->recvDataLen);
         }
 
         if (senderInfo->totalDataLen == senderInfo->recvDataLen)
         {
-            ca_mutex_lock(g_bleAdapterReqRespCbMutex);
+            oc_mutex_lock(g_bleAdapterReqRespCbMutex);
             if (NULL == g_networkPacketReceivedCallback)
             {
                 OIC_LOG(ERROR, CALEADAPTER_TAG, "gReqRespCallback is NULL!");
@@ -993,43 +1125,109 @@ static void CALEDataReceiverHandler(void *threadData)
                 u_arraylist_remove(bleData->senderInfo, senderIndex);
                 OICFree(senderInfo->defragData);
                 OICFree(senderInfo);
-                ca_mutex_unlock(g_bleAdapterReqRespCbMutex);
-                ca_mutex_unlock(g_bleReceiveDataMutex);
+                oc_mutex_unlock(g_bleAdapterReqRespCbMutex);
+                oc_mutex_unlock(bleReceiveDataMutex);
                 return;
             }
 
-            OIC_LOG(DEBUG, CALEADAPTER_TAG, "[CALEDataReceiverHandler] Sending data up !");
+            OIC_LOG(DEBUG, CALEADAPTER_TAG, "[CALEDataReceiverHandler] Received data up !");
 
             const CASecureEndpoint_t tmp =
                 {
                     .endpoint = *senderInfo->remoteEndpoint
                 };
 
-            g_networkPacketReceivedCallback(&tmp,
-                                            senderInfo->defragData,
-                                            senderInfo->recvDataLen);
-            ca_mutex_unlock(g_bleAdapterReqRespCbMutex);
+            OIC_LOG_V(INFO, CALEADAPTER_TAG, "endpoint flags : %d", tmp.endpoint.flags);
+#ifdef __WITH_DTLS__
+            if (CA_SECURE & tmp.endpoint.flags)
+            {
+                OIC_LOG(DEBUG, CALEADAPTER_TAG, "Secure data received");
+                switch (receiverType)
+                {
+                    case ADAPTER_CLIENT:
+                        g_dataType = CA_REQUEST_DATA;
+                        break;
+                    case ADAPTER_SERVER:
+                        g_dataType = CA_RESPONSE_DATA;
+                        break;
+                    default:
+                        OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Unsupported rcvr type:%d",receiverType);
+                        oc_mutex_unlock(g_bleAdapterReqRespCbMutex);
+                        u_arraylist_remove(bleData->senderInfo, senderIndex);
+                        senderInfo->remoteEndpoint = NULL;
+                        senderInfo->defragData = NULL;
+                        OICFree(senderInfo);
+                        oc_mutex_unlock(bleReceiveDataMutex);
+                        return;
+                }
+
+                if (CA_STATUS_FAILED == CAdecryptSsl(&tmp,
+                                                senderInfo->defragData,
+                                                senderInfo->recvDataLen))
+                {
+                    OIC_LOG(ERROR, CALEADAPTER_TAG, "CAdecryptSsl failed");
+                }
+                else
+                {
+                    OIC_LOG(DEBUG, CALEADAPTER_TAG, "CAdecryptSsl successed");
+                }
+                OICFree(senderInfo->defragData);
+            }
+            else
+            {
+#endif
+                OIC_LOG(INFO, CALEADAPTER_TAG, "Non-Secure data received");
+                g_networkPacketReceivedCallback(&tmp,
+                                                senderInfo->defragData,
+                                                senderInfo->recvDataLen);
+#ifdef __WITH_DTLS__
+            }
+#endif
+
+            oc_mutex_unlock(g_bleAdapterReqRespCbMutex);
             u_arraylist_remove(bleData->senderInfo, senderIndex);
             senderInfo->remoteEndpoint = NULL;
             senderInfo->defragData = NULL;
             OICFree(senderInfo);
         }
     }
-    ca_mutex_unlock(g_bleReceiveDataMutex);
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+    oc_mutex_unlock(bleReceiveDataMutex);
+}
+
+
+static void CALEServerDataReceiverHandler(void *threadData)
+{
+    CALEDataReceiverHandler(threadData, ADAPTER_SERVER);
+}
+
+static void CALEClientDataReceiverHandler(void *threadData)
+{
+    CALEDataReceiverHandler(threadData, ADAPTER_CLIENT);
 }
 
 static void CALEServerSendDataThread(void *threadData)
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN - CALEServerSendDataThread");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__);
 
     CALEData_t * const bleData = (CALEData_t *) threadData;
     if (!bleData)
     {
-        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Invalid bledata!");
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "Invalid bledata!");
         return;
     }
 
+    if (!bleData->remoteEndpoint)
+    {
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "Invalid endpoint of bledata!");
+        return;
+    }
+
+#if defined(__TIZEN__) || defined(__ANDROID__)
+    // get MTU size
+    g_mtuSize = CALEServerGetMtuSize(bleData->remoteEndpoint->addr);
+#endif
+    OIC_LOG_V(INFO, CALEADAPTER_TAG, "MTU size [%d]", g_mtuSize);
+
     uint32_t midPacketCount = 0;
     size_t remainingLen = 0;
     size_t totalLength = 0;
@@ -1038,7 +1236,8 @@ static void CALEServerSendDataThread(void *threadData)
     CAResult_t result = CAGenerateVariableForFragmentation(bleData->dataLen,
                                                            &midPacketCount,
                                                            &remainingLen,
-                                                           &totalLength);
+                                                           &totalLength,
+                                                           g_mtuSize);
 
     if (CA_STATUS_OK != result)
     {
@@ -1062,9 +1261,10 @@ static void CALEServerSendDataThread(void *threadData)
 
     if (NULL != bleData->remoteEndpoint) //Unicast Data
     {
-        secureFlag = bleData->remoteEndpoint->flags == CA_SECURE ?
+        secureFlag = (bleData->remoteEndpoint->flags & CA_SECURE) ?
             CA_BLE_PACKET_SECURE : CA_BLE_PACKET_NON_SECURE;
 
+        OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "This Packet is secure? %d", secureFlag);
         result = CAGenerateHeader(dataHeader,
                                   CA_BLE_PACKET_START,
                                   g_localBLESourcePort,
@@ -1079,6 +1279,7 @@ static void CALEServerSendDataThread(void *threadData)
                                   secureFlag,
                                   CA_BLE_MULTICAST_PORT);
     }
+    OIC_LOG_V(INFO, CALEADAPTER_TAG, "header info: secureFlag[%X]", secureFlag);
 
     if (CA_STATUS_OK != result)
     {
@@ -1103,15 +1304,15 @@ static void CALEServerSendDataThread(void *threadData)
 
     uint32_t length = 0;
     uint32_t dataLen = 0;
-    if (CA_SUPPORTED_BLE_MTU_SIZE > totalLength)
+    if (g_mtuSize > totalLength)
     {
         length = totalLength;
         dataLen = bleData->dataLen;
     }
     else
     {
-        length = CA_SUPPORTED_BLE_MTU_SIZE;
-        dataLen = CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_HEADER_SIZE - CA_BLE_LENGTH_HEADER_SIZE;
+        length = g_mtuSize;
+        dataLen = g_mtuSize - CA_BLE_HEADER_SIZE - CA_BLE_LENGTH_HEADER_SIZE;
     }
 
     result = CAMakeFirstDataSegment(dataSegment,
@@ -1153,7 +1354,7 @@ static void CALEServerSendDataThread(void *threadData)
 
         OIC_LOG_V(DEBUG,
                   CALEADAPTER_TAG,
-                  "Server Sent data length [%u]",
+                  "Server Sent Unicast First Data - data length [%zu]",
                   length);
 
         result = CAGenerateHeader(dataHeader,
@@ -1173,16 +1374,13 @@ static void CALEServerSendDataThread(void *threadData)
         for (index = 0; index < iter; index++)
         {
             // Send the remaining header.
-            OIC_LOG_V(DEBUG,
-                      CALEADAPTER_TAG,
-                      "Sending the chunk number [%u]",
-                      index);
-
             result = CAMakeRemainDataSegment(dataSegment,
+                                             g_mtuSize - CA_BLE_HEADER_SIZE,
                                              bleData->data,
-                                             CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_HEADER_SIZE,
+                                             bleData->dataLen,
                                              index,
-                                             dataHeader);
+                                             dataHeader,
+                                             g_mtuSize);
 
             if (CA_STATUS_OK != result)
             {
@@ -1196,7 +1394,7 @@ static void CALEServerSendDataThread(void *threadData)
                 CAUpdateCharacteristicsToGattClient(
                     bleData->remoteEndpoint->addr,
                     dataSegment,
-                    CA_SUPPORTED_BLE_MTU_SIZE);
+                    g_mtuSize);
 
             if (CA_STATUS_OK != result)
             {
@@ -1206,20 +1404,20 @@ static void CALEServerSendDataThread(void *threadData)
                 return;
             }
             OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Server Sent data length [%d]",
-                                               CA_SUPPORTED_BLE_MTU_SIZE);
+                                               g_mtuSize);
         }
 
-        if (remainingLen && (totalLength > CA_SUPPORTED_BLE_MTU_SIZE))
+        if (remainingLen && (totalLength > g_mtuSize))
         {
             // send the last segment of the data (Ex: 22 bytes of 622
             // bytes of data when MTU is 200)
-            OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending the last chunk");
-
             result = CAMakeRemainDataSegment(dataSegment,
-                                             bleData->data,
                                              remainingLen,
+                                             bleData->data,
+                                             bleData->dataLen,
                                              index,
-                                             dataHeader);
+                                             dataHeader,
+                                             g_mtuSize);
 
             if (CA_STATUS_OK != result)
             {
@@ -1246,120 +1444,64 @@ static void CALEServerSendDataThread(void *threadData)
                                result);
                 return;
             }
-            OIC_LOG_V(DEBUG, CALEADAPTER_TAG,
-                      "Server Sent data length [%zu]", remainingLen + CA_BLE_HEADER_SIZE);
+            OIC_LOG_V(DEBUG,
+                      CALEADAPTER_TAG,
+                      "Server Sent Unicast Last Data - data length [%zu]",
+                      remainingLen + CA_BLE_HEADER_SIZE);
         }
      }
     else
     {
         OIC_LOG(DEBUG, CALEADAPTER_TAG, "Server Sending Multicast data");
-        result = CAUpdateCharacteristicsToAllGattClients(dataSegment, length);
-        if (CA_STATUS_OK != result)
-        {
-            OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Update characteristics failed, result [%d]",
-                      result);
-            CALEErrorHandler(NULL, bleData->data, bleData->dataLen, result);
-            return;
-        }
-        OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Server Sent data length [%d]", length);
-
-        result = CAGenerateHeader(dataHeader,
-                                  CA_BLE_PACKET_NOT_START,
-                                  g_localBLESourcePort,
-                                  secureFlag,
-                                  CA_BLE_MULTICAST_PORT);
-
-        if (CA_STATUS_OK != result)
-        {
-            OIC_LOG_V(ERROR, CALEADAPTER_TAG,
-                      "CAGenerateHeader failed, result [%d]", result);
-            g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
-            return;
-        }
-
-        for (index = 0; index < iter; index++)
-        {
-            // Send the remaining header.
-            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Sending the chunk number [%d]", index);
-
-            result = CAMakeRemainDataSegment(dataSegment,
-                                             bleData->data,
-                                             CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_HEADER_SIZE,
-                                             index,
-                                             dataHeader);
-
-            if (CA_STATUS_OK != result)
-            {
-                OIC_LOG_V(ERROR, CALEADAPTER_TAG,
-                            "Making data segment failed, result [%d]", result);
-                g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
-                return;
-            }
-
-            result = CAUpdateCharacteristicsToAllGattClients(
-                         dataSegment,
-                         CA_SUPPORTED_BLE_MTU_SIZE);
-
-            if (CA_STATUS_OK != result)
-            {
-                OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Update characteristics failed, result [%d]",
-                          result);
-                CALEErrorHandler(NULL, bleData->data, bleData->dataLen, result);
-                return;
-            }
-            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Server Sent data length [%u]",
-                      CA_SUPPORTED_BLE_MTU_SIZE);
-        }
-
-        if (remainingLen && (totalLength > CA_SUPPORTED_BLE_MTU_SIZE))
-        {
-            // send the last segment of the data
-            OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending the last chunk");
-
-            result = CAMakeRemainDataSegment(dataSegment,
-                                             bleData->data,
-                                             remainingLen,
-                                             index,
-                                             dataHeader);
-
-            if (CA_STATUS_OK != result)
-            {
-                OIC_LOG_V(ERROR, CALEADAPTER_TAG,
-                            "Making data segment failed, result [%d]", result);
-                g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
-                return;
-            }
-
-            result = CAUpdateCharacteristicsToAllGattClients(
-                         dataSegment,
-                         remainingLen + CA_BLE_HEADER_SIZE);
-
-            if (CA_STATUS_OK != result)
-            {
-                OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Update characteristics failed, result [%d]",
-                          result);
-                CALEErrorHandler(NULL, bleData->data, bleData->dataLen, result);
-                return;
-            }
-            OIC_LOG_V(DEBUG, CALEADAPTER_TAG,
-                      "Server Sent data length [%zu]", remainingLen + CA_BLE_HEADER_SIZE);
-        }
+        OIC_LOG(DEBUG, CALEADAPTER_TAG, "BLE Multicast is not supported");
     }
 
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT - CALEServerSendDataThread");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__);
 }
 
 static void CALEClientSendDataThread(void *threadData)
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN - CALEClientSendDataThread");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__);
 
     CALEData_t *bleData = (CALEData_t *) threadData;
     if (!bleData)
     {
-        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Invalid bledata!");
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "Invalid bledata!");
         return;
     }
 
+    if (!bleData->remoteEndpoint)
+    {
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "Invalid endpoint of bledata!");
+        return;
+    }
+
+#if defined(__TIZEN__) || defined(__ANDROID__)
+    // get MTU size
+    if (false == CALEClientIsConnected(bleData->remoteEndpoint->addr))
+    {
+        // triggering to gatt connect and MTU negotiation
+        CAResult_t res = CALEClientSendNegotiationMessage(
+                bleData->remoteEndpoint->addr);
+
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG_V(ERROR,
+                      CALEADAPTER_TAG,
+                      "CALEClientSendNegotiationMessage has failed, result [%d]",
+                      res);
+
+            g_errorHandler(bleData->remoteEndpoint,
+                           bleData->data,
+                           bleData->dataLen,
+                           res);
+            return;
+        }
+    }
+    g_mtuSize = CALEClientGetMtuSize(bleData->remoteEndpoint->addr);
+#endif
+    OIC_LOG_V(INFO, CALEADAPTER_TAG, "MTU size [%d]", g_mtuSize);
+
     uint32_t midPacketCount = 0;
     size_t remainingLen = 0;
     size_t totalLength = 0;
@@ -1368,7 +1510,8 @@ static void CALEClientSendDataThread(void *threadData)
     CAResult_t result = CAGenerateVariableForFragmentation(bleData->dataLen,
                                                            &midPacketCount,
                                                            &remainingLen,
-                                                           &totalLength);
+                                                           &totalLength,
+                                                           g_mtuSize);
 
     if (CA_STATUS_OK != result)
     {
@@ -1387,9 +1530,10 @@ static void CALEClientSendDataThread(void *threadData)
 
     if (NULL != bleData->remoteEndpoint) //Unicast Data
     {
-        secureFlag = bleData->remoteEndpoint->flags == CA_SECURE ?
+        secureFlag = (bleData->remoteEndpoint->flags & CA_SECURE) ?
             CA_BLE_PACKET_SECURE : CA_BLE_PACKET_NON_SECURE;
 
+        OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "This Packet is secure? %d", secureFlag);
         result = CAGenerateHeader(dataHeader,
                                   CA_BLE_PACKET_START,
                                   g_localBLESourcePort,
@@ -1405,6 +1549,8 @@ static void CALEClientSendDataThread(void *threadData)
                                   CA_BLE_MULTICAST_PORT);
     }
 
+    OIC_LOG_V(INFO, CALEADAPTER_TAG, "header info: secureFlag[%X]", secureFlag);
+
     if (CA_STATUS_OK != result)
     {
         OIC_LOG_V(ERROR, CALEADAPTER_TAG,
@@ -1428,15 +1574,15 @@ static void CALEClientSendDataThread(void *threadData)
 
     uint32_t length = 0;
     uint32_t dataLen = 0;
-    if (CA_SUPPORTED_BLE_MTU_SIZE > totalLength)
+    if (g_mtuSize > totalLength)
     {
         length = totalLength;
         dataLen = bleData->dataLen;
     }
     else
     {
-        length = CA_SUPPORTED_BLE_MTU_SIZE;
-        dataLen = CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_HEADER_SIZE - CA_BLE_LENGTH_HEADER_SIZE;
+        length = g_mtuSize;
+        dataLen = g_mtuSize - CA_BLE_HEADER_SIZE - CA_BLE_LENGTH_HEADER_SIZE;
     }
 
     result = CAMakeFirstDataSegment(dataSegment,
@@ -1463,133 +1609,30 @@ static void CALEClientSendDataThread(void *threadData)
                 dataSegment,
                 length,
                 LE_UNICAST,
-                0);
-
-        if (CA_STATUS_OK != result)
-        {
-            OIC_LOG_V(ERROR,
-                      CALEADAPTER_TAG,
-                      "Update characteristics failed, result [%d]",
-                      result);
-            g_errorHandler(bleData->remoteEndpoint,
-                           bleData->data,
-                           bleData->dataLen,
-                           result);
-            return;
-        }
-
-        OIC_LOG_V(DEBUG,
-                  CALEADAPTER_TAG,
-                  "Client Sent Data length  is [%u]",
-                  length);
-
-        result = CAGenerateHeader(dataHeader,
-                                  CA_BLE_PACKET_NOT_START,
-                                  g_localBLESourcePort,
-                                  secureFlag,
-                                  bleData->remoteEndpoint->port);
-
-        if (CA_STATUS_OK != result)
-        {
-            OIC_LOG_V(ERROR, CALEADAPTER_TAG,
-                      "CAGenerateHeader failed, result [%d]", result);
-            g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
-            return;
-        }
-
-        for (index = 0; index < iter; index++)
-        {
-            result = CAMakeRemainDataSegment(dataSegment,
-                                             bleData->data,
-                                             CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_HEADER_SIZE,
-                                             index,
-                                             dataHeader);
-
-            if (CA_STATUS_OK != result)
-            {
-                OIC_LOG_V(ERROR, CALEADAPTER_TAG,
-                            "Making data segment failed, result [%d]", result);
-                g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
-                return;
-            }
-
-            // Send the remaining header.
-            result = CAUpdateCharacteristicsToGattServer(
-                     bleData->remoteEndpoint->addr,
-                     dataSegment,
-                     CA_SUPPORTED_BLE_MTU_SIZE,
-                     LE_UNICAST, 0);
-
-            if (CA_STATUS_OK != result)
-            {
-                OIC_LOG_V(ERROR,
-                          CALEADAPTER_TAG,
-                          "Update characteristics failed, result [%d]",
-                          result);
-                g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
-                return;
-            }
-            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Client Sent Data length  is [%d]",
-                                               CA_SUPPORTED_BLE_MTU_SIZE);
-        }
-
-        if (remainingLen && (totalLength > CA_SUPPORTED_BLE_MTU_SIZE))
-        {
-            // send the last segment of the data (Ex: 22 bytes of 622
-            // bytes of data when MTU is 200)
-            OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending the last chunk");
-
-            result = CAMakeRemainDataSegment(dataSegment,
-                                             bleData->data,
-                                             remainingLen,
-                                             index,
-                                             dataHeader);
-
-            if (CA_STATUS_OK != result)
-            {
-                OIC_LOG_V(ERROR, CALEADAPTER_TAG,
-                            "Making data segment failed, result [%d]", result);
-                g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
-                return;
-            }
-
-            result = CAUpdateCharacteristicsToGattServer(
-                     bleData->remoteEndpoint->addr,
-                     dataSegment,
-                     remainingLen + CA_BLE_HEADER_SIZE,
-                     LE_UNICAST, 0);
-
-            if (CA_STATUS_OK != result)
-            {
-                OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Update characteristics failed, result [%d]",
-                                                   result);
-                g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
-                return;
-            }
-            OIC_LOG_V(DEBUG, CALEADAPTER_TAG,
-                      "Client Sent Data length  is [%zu]", remainingLen + CA_BLE_HEADER_SIZE);
-        }
-    }
-    else
-    {
-        //Sending Mulitcast Data
-        // Send the first segment with the header.
-        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending Multicast Data");
-        result = CAUpdateCharacteristicsToAllGattServers(dataSegment, length);
+                0);
+
         if (CA_STATUS_OK != result)
         {
-            OIC_LOG_V(ERROR, CALEADAPTER_TAG,
-                      "Update characteristics (all) failed, result [%d]", result);
-            CALEErrorHandler(NULL, bleData->data, bleData->dataLen, result);
-            return ;
+            OIC_LOG_V(ERROR,
+                      CALEADAPTER_TAG,
+                      "Update characteristics failed, result [%d]",
+                      result);
+            g_errorHandler(bleData->remoteEndpoint,
+                           bleData->data,
+                           bleData->dataLen,
+                           result);
+            return;
         }
-        OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Client Sent Data length  is [%d]", length);
+        OIC_LOG_V(DEBUG,
+                  CALEADAPTER_TAG,
+                  "Client Sent Unicast First Data - data length [%zu]",
+                  length);
 
         result = CAGenerateHeader(dataHeader,
                                   CA_BLE_PACKET_NOT_START,
                                   g_localBLESourcePort,
                                   secureFlag,
-                                  0);
+                                  bleData->remoteEndpoint->port);
 
         if (CA_STATUS_OK != result)
         {
@@ -1599,14 +1642,15 @@ static void CALEClientSendDataThread(void *threadData)
             return;
         }
 
-        // Send the remaining header.
         for (index = 0; index < iter; index++)
         {
             result = CAMakeRemainDataSegment(dataSegment,
+                                             g_mtuSize - CA_BLE_HEADER_SIZE,
                                              bleData->data,
-                                             CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_HEADER_SIZE,
+                                             bleData->dataLen,
                                              index,
-                                             dataHeader);
+                                             dataHeader,
+                                             g_mtuSize);
 
             if (CA_STATUS_OK != result)
             {
@@ -1616,32 +1660,40 @@ static void CALEClientSendDataThread(void *threadData)
                 return;
             }
 
-            result = CAUpdateCharacteristicsToAllGattServers(
-                         dataSegment,
-                         CA_SUPPORTED_BLE_MTU_SIZE);
+            // Send the remaining header.
+            result = CAUpdateCharacteristicsToGattServer(
+                     bleData->remoteEndpoint->addr,
+                     dataSegment,
+                     g_mtuSize,
+                     LE_UNICAST, 0);
 
             if (CA_STATUS_OK != result)
             {
-                OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Update characteristics failed, result [%d]",
+                OIC_LOG_V(ERROR,
+                          CALEADAPTER_TAG,
+                          "Update characteristics failed, result [%d]",
                           result);
-                CALEErrorHandler(NULL, bleData->data, bleData->dataLen, result);
+                g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
                 return;
             }
-            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Client Sent Data length  is [%d]",
-                      CA_SUPPORTED_BLE_MTU_SIZE);
+            OIC_LOG_V(DEBUG,
+                      CALEADAPTER_TAG,
+                      "Client Sent Unicast %d Data - data(mtu) length [%zu]",
+                      index + 1,
+                      g_mtuSize);
         }
 
-        if (remainingLen && (totalLength > CA_SUPPORTED_BLE_MTU_SIZE))
+        if (remainingLen && (totalLength > g_mtuSize))
         {
             // send the last segment of the data (Ex: 22 bytes of 622
             // bytes of data when MTU is 200)
-            OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending the last chunk");
-
             result = CAMakeRemainDataSegment(dataSegment,
-                                             bleData->data,
                                              remainingLen,
+                                             bleData->data,
+                                             bleData->dataLen,
                                              index,
-                                             dataHeader);
+                                             dataHeader,
+                                             g_mtuSize);
 
             if (CA_STATUS_OK != result)
             {
@@ -1651,24 +1703,33 @@ static void CALEClientSendDataThread(void *threadData)
                 return;
             }
 
-            result =
-                CAUpdateCharacteristicsToAllGattServers(
-                    dataSegment,
-                    remainingLen + CA_BLE_HEADER_SIZE);
+            result = CAUpdateCharacteristicsToGattServer(
+                     bleData->remoteEndpoint->addr,
+                     dataSegment,
+                     remainingLen + CA_BLE_HEADER_SIZE,
+                     LE_UNICAST, 0);
 
             if (CA_STATUS_OK != result)
             {
-                OIC_LOG_V(ERROR, CALEADAPTER_TAG,
-                          "Update characteristics (all) failed, result [%d]", result);
-                CALEErrorHandler(NULL, bleData->data, bleData->dataLen, result);
+                OIC_LOG_V(ERROR, CALEADAPTER_TAG, "Update characteristics failed, result [%d]",
+                                                   result);
+                g_errorHandler(bleData->remoteEndpoint, bleData->data, bleData->dataLen, result);
                 return;
             }
-            OIC_LOG_V(DEBUG, CALEADAPTER_TAG,
-                      "Client Sent Data length  is [%zu]", remainingLen + CA_BLE_HEADER_SIZE);
+            OIC_LOG_V(DEBUG,
+                      CALEADAPTER_TAG,
+                      "Client Sent Unicast Last Data - data length [%zu]",
+                      remainingLen + CA_BLE_HEADER_SIZE);
         }
     }
+    else
+    {
+        //Sending Mulitcast Data
+        OIC_LOG(DEBUG, CALEADAPTER_TAG, "Client Sending Multicast Data");
+        OIC_LOG(DEBUG, CALEADAPTER_TAG, "BLE Multicast is not supported");
+    }
 
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT - CABLEClientSendDataThread");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__);
 }
 
 static CALEData_t *CACreateLEData(const CAEndpoint_t *remoteEndpoint,
@@ -1717,7 +1778,7 @@ static void CALEDataDestroyer(void *data, uint32_t size)
 {
     if ((size_t)size < sizeof(CALEData_t *))
     {
-        OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+        OIC_LOG_V(DEBUG, CALEADAPTER_TAG,
                   "Destroy data too small %p %d", data, size);
     }
     CALEData_t *ledata = (CALEData_t *) data;
@@ -1730,7 +1791,7 @@ static void CALEDataDestroyer(void *data, uint32_t size)
 static void CALEDataReceiverHandlerSingleThread(const uint8_t *data,
                                                 uint32_t dataLen)
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__);
 
     VERIFY_NON_NULL(data, CALEADAPTER_TAG, "Param data is NULL");
 
@@ -1840,15 +1901,16 @@ static void CALEDataReceiverHandlerSingleThread(const uint8_t *data,
                data + CA_BLE_HEADER_SIZE,
                dataOnlyLen);
         g_singleThreadReceiveData->recvDataLen += dataOnlyLen;
-        OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "totalDatalength  [%d] received Datalen [%d]",
+        OIC_LOG_V(INFO, CALEADAPTER_TAG, "totalDatalength  [%d] received Datalen [%d]",
                 g_singleThreadReceiveData->totalDataLen, g_singleThreadReceiveData->recvDataLen);
     }
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__);
 }
 
 static CAResult_t CALEServerSendDataSingleThread(const uint8_t *data,
                                                  uint32_t dataLen)
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__););
 
     VERIFY_NON_NULL(data, CALEADAPTER_TAG, "Param data is NULL");
 
@@ -1860,7 +1922,8 @@ static CAResult_t CALEServerSendDataSingleThread(const uint8_t *data,
     CAResult_t result = CAGenerateVariableForFragmentation(dataLen,
                                                            &midPacketCount,
                                                            &remainingLen,
-                                                           &totalLength);
+                                                           &totalLength,
+                                                           g_mtuSize);
 
     if (CA_STATUS_OK != result)
     {
@@ -1908,15 +1971,15 @@ static CAResult_t CALEServerSendDataSingleThread(const uint8_t *data,
 
     uint32_t length = 0;
     uint32_t dataOnlyLen = 0;
-    if (CA_SUPPORTED_BLE_MTU_SIZE > totalLength)
+    if (g_mtuSize > totalLength)
     {
         length = totalLength;
         dataOnlyLen = dataLen;
     }
     else
     {
-        length = CA_SUPPORTED_BLE_MTU_SIZE;
-        dataOnlyLen = CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_HEADER_SIZE - CA_BLE_LENGTH_HEADER_SIZE;
+        length = g_mtuSize;
+        dataOnlyLen = g_mtuSize - CA_BLE_HEADER_SIZE - CA_BLE_LENGTH_HEADER_SIZE;
     }
 
     result = CAMakeFirstDataSegment(dataSegment,
@@ -1960,10 +2023,12 @@ static CAResult_t CALEServerSendDataSingleThread(const uint8_t *data,
     for (uint32_t iter = 0; iter < dataLimit; iter++)
     {
         result = CAMakeRemainDataSegment(dataSegment,
+                                         g_mtuSize - CA_BLE_HEADER_SIZE,
                                          data,
-                                         CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_HEADER_SIZE,
+                                         dataLen,
                                          iter,
-                                         dataHeader);
+                                         dataHeader,
+                                         g_mtuSize);
 
         if (CA_STATUS_OK != result)
         {
@@ -1974,7 +2039,7 @@ static CAResult_t CALEServerSendDataSingleThread(const uint8_t *data,
 
         result = CAUpdateCharacteristicsToAllGattClients(
                      dataSegment,
-                     CA_SUPPORTED_BLE_MTU_SIZE);
+                     g_mtuSize);
 
         if (CA_STATUS_OK != result)
         {
@@ -1985,16 +2050,18 @@ static CAResult_t CALEServerSendDataSingleThread(const uint8_t *data,
         CALEDoEvents();
     }
 
-    if (remainingLen && (totalLength > CA_SUPPORTED_BLE_MTU_SIZE))
+    if (remainingLen && (totalLength > g_mtuSize))
     {
         // send the last segment of the data
         OIC_LOG(DEBUG, CALEADAPTER_TAG, "Sending the last chunk");
 
         result = CAMakeRemainDataSegment(dataSegment,
-                                         data,
                                          remainingLen,
+                                         data,
+                                         dataLen,
                                          dataLimit,
-                                         dataHeader);
+                                         dataHeader,
+                                         g_mtuSize);
 
         if (CA_STATUS_OK != result)
         {
@@ -2021,24 +2088,24 @@ static CAResult_t CALEServerSendDataSingleThread(const uint8_t *data,
 
 static CAResult_t CAInitLEAdapterMutex()
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN - CAInitLEAdapterMutex");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__);
 
     if (NULL == g_bleIsServerMutex)
     {
-        g_bleIsServerMutex = ca_mutex_new();
+        g_bleIsServerMutex = oc_mutex_new();
         if (NULL == g_bleIsServerMutex)
         {
-            OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed");
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "oc_mutex_new failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_bleNetworkCbMutex)
     {
-        g_bleNetworkCbMutex = ca_mutex_new();
+        g_bleNetworkCbMutex = oc_mutex_new();
         if (NULL == g_bleNetworkCbMutex)
         {
-            OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed");
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "oc_mutex_new failed");
             CATerminateLEAdapterMutex();
             return CA_STATUS_FAILED;
         }
@@ -2046,10 +2113,10 @@ static CAResult_t CAInitLEAdapterMutex()
 
     if (NULL == g_bleLocalAddressMutex)
     {
-        g_bleLocalAddressMutex = ca_mutex_new();
+        g_bleLocalAddressMutex = oc_mutex_new();
         if (NULL == g_bleLocalAddressMutex)
         {
-            OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed");
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "oc_mutex_new failed");
             CATerminateLEAdapterMutex();
             return CA_STATUS_FAILED;
         }
@@ -2057,10 +2124,10 @@ static CAResult_t CAInitLEAdapterMutex()
 
     if (NULL == g_bleAdapterThreadPoolMutex)
     {
-        g_bleAdapterThreadPoolMutex = ca_mutex_new();
+        g_bleAdapterThreadPoolMutex = oc_mutex_new();
         if (NULL == g_bleAdapterThreadPoolMutex)
         {
-            OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed");
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "oc_mutex_new failed");
             CATerminateLEAdapterMutex();
             return CA_STATUS_FAILED;
         }
@@ -2068,10 +2135,10 @@ static CAResult_t CAInitLEAdapterMutex()
 
     if (NULL == g_bleClientSendDataMutex)
     {
-        g_bleClientSendDataMutex = ca_mutex_new();
+        g_bleClientSendDataMutex = oc_mutex_new();
         if (NULL == g_bleClientSendDataMutex)
         {
-            OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed");
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "oc_mutex_new failed");
             CATerminateLEAdapterMutex();
             return CA_STATUS_FAILED;
         }
@@ -2079,10 +2146,10 @@ static CAResult_t CAInitLEAdapterMutex()
 
     if (NULL == g_bleServerSendDataMutex)
     {
-        g_bleServerSendDataMutex = ca_mutex_new();
+        g_bleServerSendDataMutex = oc_mutex_new();
         if (NULL == g_bleServerSendDataMutex)
         {
-            OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed");
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "oc_mutex_new failed");
             CATerminateLEAdapterMutex();
             return CA_STATUS_FAILED;
         }
@@ -2090,58 +2157,68 @@ static CAResult_t CAInitLEAdapterMutex()
 
     if (NULL == g_bleAdapterReqRespCbMutex)
     {
-        g_bleAdapterReqRespCbMutex = ca_mutex_new();
+        g_bleAdapterReqRespCbMutex = oc_mutex_new();
         if (NULL == g_bleAdapterReqRespCbMutex)
         {
-            OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed");
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "oc_mutex_new failed");
             CATerminateLEAdapterMutex();
             return CA_STATUS_FAILED;
         }
     }
 
-    if (NULL == g_bleReceiveDataMutex)
+    if (NULL == g_bleServerReceiveDataMutex)
+    {
+        g_bleServerReceiveDataMutex = oc_mutex_new();
+        if (NULL == g_bleServerReceiveDataMutex)
+        {
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "oc_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_bleClientReceiveDataMutex)
     {
-        g_bleReceiveDataMutex = ca_mutex_new();
-        if (NULL == g_bleReceiveDataMutex)
+        g_bleClientReceiveDataMutex = oc_mutex_new();
+        if (NULL == g_bleClientReceiveDataMutex)
         {
-            OIC_LOG(ERROR, CALEADAPTER_TAG, "ca_mutex_new failed");
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "oc_mutex_new failed");
             return CA_STATUS_FAILED;
         }
     }
 
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
     return CA_STATUS_OK;
 }
 
 static void CATerminateLEAdapterMutex()
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN - CATerminateLEAdapterMutex");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__);
 
-    ca_mutex_free(g_bleIsServerMutex);
+    oc_mutex_free(g_bleIsServerMutex);
     g_bleIsServerMutex = NULL;
 
-    ca_mutex_free(g_bleNetworkCbMutex);
+    oc_mutex_free(g_bleNetworkCbMutex);
     g_bleNetworkCbMutex = NULL;
 
-    ca_mutex_free(g_bleLocalAddressMutex);
+    oc_mutex_free(g_bleLocalAddressMutex);
     g_bleLocalAddressMutex = NULL;
 
-    ca_mutex_free(g_bleAdapterThreadPoolMutex);
+    oc_mutex_free(g_bleAdapterThreadPoolMutex);
     g_bleAdapterThreadPoolMutex = NULL;
 
-    ca_mutex_free(g_bleClientSendDataMutex);
+    oc_mutex_free(g_bleClientSendDataMutex);
     g_bleClientSendDataMutex = NULL;
 
-    ca_mutex_free(g_bleServerSendDataMutex);
+    oc_mutex_free(g_bleServerSendDataMutex);
     g_bleServerSendDataMutex = NULL;
 
-    ca_mutex_free(g_bleAdapterReqRespCbMutex);
+    oc_mutex_free(g_bleAdapterReqRespCbMutex);
     g_bleAdapterReqRespCbMutex = NULL;
 
-    ca_mutex_free(g_bleReceiveDataMutex);
-    g_bleReceiveDataMutex = NULL;
+    oc_mutex_free(g_bleServerReceiveDataMutex);
+    g_bleServerReceiveDataMutex = NULL;
 
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+    oc_mutex_free(g_bleClientReceiveDataMutex);
+    g_bleClientReceiveDataMutex = NULL;
 }
 
 /**
@@ -2345,7 +2422,14 @@ static CAResult_t CALEAdapterClientSendData(const CAEndpoint_t *remoteEndpoint,
 
 static CAResult_t CALEAdapterGattServerStart()
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "Before CAStartLEGattServer");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__);
+
+    if (caglobals.bleFlags & CA_LE_SERVER_DISABLE)
+    {
+        OIC_LOG_V(INFO, CALEADAPTER_TAG, "server flag of configure is disable [%d]",
+                  caglobals.bleFlags);
+        return CA_STATUS_OK;
+    }
 
     CAResult_t result = CAStartLEGattServer();
 
@@ -2356,9 +2440,9 @@ static CAResult_t CALEAdapterGattServerStart()
     */
     if (CA_STATUS_OK == result)
     {
-        ca_mutex_lock(g_bleServerSendDataMutex);
+        oc_mutex_lock(g_bleServerSendDataMutex);
         result = CAQueueingThreadStart(g_bleServerSendQueueHandle);
-        ca_mutex_unlock(g_bleServerSendDataMutex);
+        oc_mutex_unlock(g_bleServerSendDataMutex);
 
         if (CA_STATUS_OK != result)
         {
@@ -2375,18 +2459,32 @@ static CAResult_t CALEAdapterGattServerStart()
 
 static CAResult_t CALEAdapterGattServerStop()
 {
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__);
+
+    if (caglobals.bleFlags & CA_LE_SERVER_DISABLE)
+    {
+        OIC_LOG_V(INFO, CALEADAPTER_TAG, "server flag of configure is disable [%d]",
+                  caglobals.bleFlags);
+        return CA_STATUS_OK;
+    }
+
 #ifndef SINGLE_THREAD
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "CALEAdapterGattServerStop");
 
-    CAResult_t result = CAStopLEGattServer();
-    ca_mutex_lock(g_bleServerSendDataMutex);
-    if (CA_STATUS_OK == result)
+    oc_mutex_lock(g_bleServerSendDataMutex);
+    CAResult_t res = CAQueueingThreadStop(g_bleServerSendQueueHandle);
+    if (CA_STATUS_OK != res)
     {
-        result = CAQueueingThreadStop(g_bleServerSendQueueHandle);
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "CAQueueingThreadStop has failed");
     }
-    ca_mutex_unlock(g_bleServerSendDataMutex);
+    oc_mutex_unlock(g_bleServerSendDataMutex);
 
-    return result;
+    res = CAStopLEGattServer();
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "CAStopLEGattServer has failed");
+    }
+
+    return res;
 #else
     return CAStopLEGattServer();
 #endif
@@ -2394,7 +2492,7 @@ static CAResult_t CALEAdapterGattServerStop()
 
 static CAResult_t CALEAdapterGattClientStart()
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "Before CAStartLEGattClient");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__);
 
     CAResult_t result = CAStartLEGattClient();
 
@@ -2405,9 +2503,9 @@ static CAResult_t CALEAdapterGattClientStart()
     */
     if (CA_STATUS_OK == result)
     {
-        ca_mutex_lock(g_bleClientSendDataMutex);
+        oc_mutex_lock(g_bleClientSendDataMutex);
         result = CAQueueingThreadStart(g_bleClientSendQueueHandle);
-        ca_mutex_unlock(g_bleClientSendDataMutex);
+        oc_mutex_unlock(g_bleClientSendDataMutex);
 
         if (CA_STATUS_OK != result)
         {
@@ -2424,12 +2522,12 @@ static CAResult_t CALEAdapterGattClientStart()
 static CAResult_t CALEAdapterGattClientStop()
 {
 #ifndef SINGLE_THREAD
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "CALEAdapterGattClientStop");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__);
     CAStopLEGattClient();
 
-    ca_mutex_lock(g_bleClientSendDataMutex);
+    oc_mutex_lock(g_bleClientSendDataMutex);
     CAResult_t result = CAQueueingThreadStop(g_bleClientSendQueueHandle);
-    ca_mutex_unlock(g_bleClientSendDataMutex);
+    oc_mutex_unlock(g_bleClientSendDataMutex);
 
     return result;
 #else
@@ -2439,6 +2537,92 @@ static CAResult_t CALEAdapterGattClientStop()
 #endif
 }
 
+#ifdef __WITH_DTLS__
+static ssize_t CALESecureSendDataCB(CAEndpoint_t *endpoint, const void *data, size_t dataLen)
+{
+    VERIFY_NON_NULL(endpoint, CALEADAPTER_TAG, "endpoint is NULL");
+    VERIFY_NON_NULL(data, CALEADAPTER_TAG, "data is NULL");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__);
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "encrypted datalen = %d", dataLen);
+
+    CAResult_t result;
+    CADataType_t dataType = g_dataType;
+    ssize_t ret = 0;
+
+    if (ADAPTER_SERVER == g_adapterType ||
+            (ADAPTER_BOTH_CLIENT_SERVER == g_adapterType && CA_RESPONSE_DATA == dataType))
+    {
+        result = CALEAdapterServerSendData(endpoint, data, dataLen);
+        if (CA_STATUS_OK != result)
+        {
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "Send unicast data for server failed" );
+
+             if (g_errorHandler)
+             {
+                 g_errorHandler(endpoint, data, dataLen, result);
+             }
+             return ret;
+        }
+        ret = (ssize_t)dataLen;
+    }
+    else if (ADAPTER_CLIENT == g_adapterType ||
+            (ADAPTER_BOTH_CLIENT_SERVER == g_adapterType && CA_REQUEST_DATA == dataType) ||
+            (ADAPTER_BOTH_CLIENT_SERVER == g_adapterType && CA_RESPONSE_FOR_RES == dataType))
+    {
+        result = CALEAdapterClientSendData(endpoint, data, dataLen);
+        if (CA_STATUS_OK != result)
+        {
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "Send unicast data for client failed" );
+
+             if (g_errorHandler)
+             {
+                 g_errorHandler(endpoint, data, dataLen, result);
+             }
+             return ret;
+        }
+        ret = (ssize_t)dataLen;
+    }
+    else
+    {
+        OIC_LOG_V(ERROR, CALEADAPTER_TAG,
+                  "Can't Send Message adapterType = %d, dataType = %d", g_adapterType, dataType);
+        return ret;
+    }
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__);
+    return ret;
+}
+
+void CALESecureReceiveDataCB(const CASecureEndpoint_t *sep, const void *data,
+                          size_t dataLen)
+{
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__);
+
+    VERIFY_NON_NULL_VOID(sep, CALEADAPTER_TAG, "sep is NULL");
+    VERIFY_NON_NULL_VOID(data, CALEADAPTER_TAG, "data is NULL");
+
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG,
+              "Secure Data Receive - decrypted datalen = %d", dataLen);
+
+    if (dataLen <= 0)
+    {
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "incorrect dataLen, derecypt fail !");
+        return;
+    }
+
+    OIC_LOG_BUFFER(DEBUG, CALEADAPTER_TAG, data, dataLen);
+
+    if (g_networkPacketReceivedCallback)
+    {
+        OIC_LOG_V(DEBUG, CALEADAPTER_TAG,
+                  "[CALESecureReceiveDataCB] Secure flags = %d, %x",
+                  sep->endpoint.flags, sep->endpoint.flags);
+        OIC_LOG(DEBUG, CALEADAPTER_TAG,
+                  "[CALESecureReceiveDataCB] Received data up !");
+        g_networkPacketReceivedCallback(sep, data, dataLen);
+    }
+}
+#endif
+
 CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
                           CANetworkPacketReceivedCallback reqRespCallback,
                           CAAdapterChangeCallback netCallback,
@@ -2446,7 +2630,7 @@ CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
                           CAErrorHandleCallback errorCallback,
                           ca_thread_pool_t handle)
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__);
 
     //Input validation
     VERIFY_NON_NULL(registerCallback, CALEADAPTER_TAG, "RegisterConnectivity callback is null");
@@ -2470,8 +2654,6 @@ CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
     }
     CAInitializeLEAdapter();
 
-    CASetLEClientThreadPoolHandle(handle);
-
     result = CAInitializeLEGattClient();
     if (CA_STATUS_OK != result)
     {
@@ -2479,6 +2661,8 @@ CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
         return CA_STATUS_FAILED;
     }
 
+    CASetLEClientThreadPoolHandle(handle);
+
     CASetLEReqRespClientCallback(CALEAdapterClientReceivedData);
     CASetLEServerThreadPoolHandle(handle);
     result = CAInitializeLEGattServer();
@@ -2498,6 +2682,18 @@ CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
 
     g_errorHandler = errorCallback;
 
+#ifdef __WITH_DTLS__
+     if (CA_STATUS_OK != CAinitSslAdapter())
+    {
+        OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to init SSL adapter");
+    }
+    else
+    {
+        CAsetSslAdapterCallbacks(CALESecureReceiveDataCB, CALESecureSendDataCB,
+                                 CA_ADAPTER_GATT_BTLE);
+    }
+#endif
+
     static const CAConnectivityHandler_t connHandler =
         {
             .startAdapter = CAStartLE,
@@ -2514,27 +2710,25 @@ CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
         };
 
     registerCallback(connHandler);
-
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
-
     return CA_STATUS_OK;
 }
 
 static CAResult_t CAStartLE()
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "CAStartLE");
-
     return CAStartLEAdapter();
 }
 
 static CAResult_t CAStopLE()
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+#ifdef __WITH_DTLS__
+    CAdeinitSslAdapter();
+#endif
+
 #ifndef SINGLE_THREAD
     CAStopLEQueues();
 #endif
 
-    ca_mutex_lock(g_bleIsServerMutex);
+    oc_mutex_lock(g_bleIsServerMutex);
     switch (g_adapterType)
     {
         case ADAPTER_SERVER:
@@ -2550,16 +2744,13 @@ static CAResult_t CAStopLE()
         default:
             break;
     }
-    ca_mutex_unlock(g_bleIsServerMutex);
-
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
-
+    oc_mutex_unlock(g_bleIsServerMutex);
     return CAStopLEAdapter();
 }
 
 static void CATerminateLE()
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__);
 
     CASetLEReqRespServerCallback(NULL);
     CASetLEReqRespClientCallback(NULL);
@@ -2567,7 +2758,7 @@ static void CATerminateLE()
     CASetLEReqRespAdapterCallback(NULL);
     CATerminateLENetworkMonitor();
 
-    ca_mutex_lock(g_bleIsServerMutex);
+    oc_mutex_lock(g_bleIsServerMutex);
     switch (g_adapterType)
     {
         case ADAPTER_SERVER:
@@ -2584,19 +2775,30 @@ static void CATerminateLE()
             break;
     }
     g_adapterType = ADAPTER_EMPTY;
-    ca_mutex_unlock(g_bleIsServerMutex);
+    oc_mutex_unlock(g_bleIsServerMutex);
 
 #ifndef SINGLE_THREAD
     CATerminateLEQueues();
 #endif
-    CATerminateLEAdapterMutex();
 
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+#ifdef __WITH_DTLS__
+    CAsetSslAdapterCallbacks(NULL, NULL, CA_ADAPTER_GATT_BTLE);
+#endif
+
+    CATerminateLEAdapterMutex();
 }
 
 static CAResult_t CAStartLEListeningServer()
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN - CAStartLEListeningServer");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__);
+
+    if (caglobals.bleFlags & CA_LE_SERVER_DISABLE)
+    {
+        OIC_LOG_V(INFO, CALEADAPTER_TAG, "server flag of configure is disable [%d]",
+                  caglobals.bleFlags);
+        return CA_STATUS_OK;
+    }
+
 #ifndef ROUTING_GATEWAY
     CAResult_t result = CA_STATUS_OK;
 #ifndef SINGLE_THREAD
@@ -2608,7 +2810,7 @@ static CAResult_t CAStartLEListeningServer()
     }
 #endif
 
-    ca_mutex_lock(g_bleIsServerMutex);
+    oc_mutex_lock(g_bleIsServerMutex);
     switch (g_adapterType)
     {
         case ADAPTER_CLIENT:
@@ -2619,7 +2821,7 @@ static CAResult_t CAStartLEListeningServer()
         default:
             g_adapterType = ADAPTER_SERVER;
     }
-    ca_mutex_unlock(g_bleIsServerMutex);
+    oc_mutex_unlock(g_bleIsServerMutex);
 
     result = CAGetLEAdapterState();
     if (CA_STATUS_OK != result)
@@ -2637,7 +2839,7 @@ static CAResult_t CAStartLEListeningServer()
         result = CALEAdapterGattServerStart();
     }
 
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__);
     return result;
 #else
     // Routing Gateway only supports BLE client mode.
@@ -2654,7 +2856,7 @@ static CAResult_t CAStopLEListeningServer()
 
 static CAResult_t CAStartLEDiscoveryServer()
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN - CAStartLEDiscoveryServer");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__);
     CAResult_t result = CA_STATUS_OK;
 #ifndef SINGLE_THREAD
     result = CAInitLEClientQueues();
@@ -2665,7 +2867,7 @@ static CAResult_t CAStartLEDiscoveryServer()
     }
 #endif
 
-    ca_mutex_lock(g_bleIsServerMutex);
+    oc_mutex_lock(g_bleIsServerMutex);
     switch (g_adapterType)
     {
         case ADAPTER_SERVER:
@@ -2676,7 +2878,7 @@ static CAResult_t CAStartLEDiscoveryServer()
         default:
             g_adapterType = ADAPTER_CLIENT;
     }
-    ca_mutex_unlock(g_bleIsServerMutex);
+    oc_mutex_unlock(g_bleIsServerMutex);
 
     result = CAGetLEAdapterState();
     if (CA_STATUS_OK != result)
@@ -2694,17 +2896,15 @@ static CAResult_t CAStartLEDiscoveryServer()
         result = CALEAdapterGattClientStart();
     }
 
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__);
     return result;
 }
 
 static CAResult_t CAReadLEData()
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
 #ifdef SINGLE_THREAD
     CACheckLEData();
 #endif
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
     return CA_STATUS_OK;
 }
 
@@ -2713,7 +2913,8 @@ static int32_t CASendLEUnicastData(const CAEndpoint_t *endpoint,
                                    uint32_t dataLen,
                                    CADataType_t dataType)
 {
-    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN - CASendLEUnicastData : type(%d)", dataType);
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__);
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "type(%d)", dataType);
 
     //Input validation
     VERIFY_NON_NULL_RET(endpoint, CALEADAPTER_TAG, "Remote endpoint is null", -1);
@@ -2727,14 +2928,39 @@ static int32_t CASendLEUnicastData(const CAEndpoint_t *endpoint,
         OIC_LOG(ERROR, CALEADAPTER_TAG, "g_adapterType is Empty");
     }
 
-    ca_mutex_lock(g_bleIsServerMutex);
+    oc_mutex_lock(g_bleIsServerMutex);
     if (ADAPTER_SERVER == g_adapterType ||
             (ADAPTER_BOTH_CLIENT_SERVER == g_adapterType && CA_RESPONSE_DATA == dataType))
     {
+#ifdef __WITH_DTLS__
+        if (endpoint && endpoint->flags & CA_SECURE)
+        {
+            OIC_LOG(DEBUG, CALEADAPTER_TAG,
+                    "Response Data or server - secured data send(caadapternetdtlsencrypt) call");
+            OIC_LOG_BUFFER(DEBUG, CALEADAPTER_TAG, data, dataLen);
+            g_dataType = dataType;
+            oc_mutex_unlock(g_bleIsServerMutex);
+
+            result = CAencryptSsl(endpoint, data, dataLen);
+            if (CA_STATUS_OK != result)
+            {
+                OIC_LOG(ERROR, CALEADAPTER_TAG, "caadapternetdtlsencrypt failed!");
+                return -1;
+            }
+            return dataLen;
+        }
+        else
+        {
+            OIC_LOG(DEBUG, CALEADAPTER_TAG,
+                    "server or both - none secured data send(CALEAdapterServerSendData) call");
+            result = CALEAdapterServerSendData(endpoint, data, dataLen);
+        }
+#else
         result = CALEAdapterServerSendData(endpoint, data, dataLen);
+#endif
         if (CA_STATUS_OK != result)
         {
-            ca_mutex_unlock(g_bleIsServerMutex);
+            oc_mutex_unlock(g_bleIsServerMutex);
             OIC_LOG(ERROR, CALEADAPTER_TAG, "Send unicast data for server failed");
             if (g_errorHandler)
             {
@@ -2744,27 +2970,51 @@ static int32_t CASendLEUnicastData(const CAEndpoint_t *endpoint,
             return -1;
         }
     }
-
-    if (ADAPTER_CLIENT == g_adapterType ||
+    else if (ADAPTER_CLIENT == g_adapterType ||
             (ADAPTER_BOTH_CLIENT_SERVER == g_adapterType && CA_REQUEST_DATA == dataType) ||
             (ADAPTER_BOTH_CLIENT_SERVER == g_adapterType && CA_RESPONSE_FOR_RES == dataType))
     {
+#ifdef __WITH_DTLS__
+        if (endpoint && endpoint->flags & CA_SECURE)
+        {
+            OIC_LOG(DEBUG, CALEADAPTER_TAG,
+                    "Request Data or client - secured data send(caadapternetdtlsencrypt) call");
+            OIC_LOG_BUFFER(DEBUG, CALEADAPTER_TAG, data, dataLen);
+            g_dataType = dataType;
+            oc_mutex_unlock(g_bleIsServerMutex);
+
+            result = CAencryptSsl(endpoint, data, dataLen);
+            if (CA_STATUS_OK != result)
+            {
+                OIC_LOG(ERROR, CALEADAPTER_TAG, "caadapternetdtlsencrypt failed!");
+                return -1;
+            }
+            return dataLen;
+        }
+        else
+        {
+            OIC_LOG(DEBUG, CALEADAPTER_TAG,
+                    "client or both - none secured data send(CALEAdapterClientSendData) call");
+            result = CALEAdapterClientSendData(endpoint, data, dataLen);
+        }
+#else
         result = CALEAdapterClientSendData(endpoint, data, dataLen);
+#endif
         if (CA_STATUS_OK != result)
         {
-            ca_mutex_unlock(g_bleIsServerMutex);
+            oc_mutex_unlock(g_bleIsServerMutex);
             OIC_LOG(ERROR, CALEADAPTER_TAG, "Send unicast data for client failed" );
 
-             if (g_errorHandler)
-             {
-                 g_errorHandler(endpoint, data, dataLen, result);
-             }
+            if (g_errorHandler)
+            {
+                g_errorHandler(endpoint, data, dataLen, result);
+            }
             return -1;
         }
     }
-    ca_mutex_unlock(g_bleIsServerMutex);
+    oc_mutex_unlock(g_bleIsServerMutex);
 
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__);
     return dataLen;
 }
 
@@ -2773,7 +3023,7 @@ static int32_t CASendLEMulticastData(const CAEndpoint_t *endpoint,
                                      uint32_t dataLen,
                                      CADataType_t dataType)
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN - CASendLEMulticastData");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__);
 
     //Input validation
     VERIFY_NON_NULL_RET(data, CALEADAPTER_TAG, "Data is null", -1);
@@ -2792,14 +3042,14 @@ static int32_t CASendLEMulticastData(const CAEndpoint_t *endpoint,
         OIC_LOG(ERROR, CALEADAPTER_TAG, "g_adapterType is Empty");
     }
 
-    ca_mutex_lock(g_bleIsServerMutex);
+    oc_mutex_lock(g_bleIsServerMutex);
     if (ADAPTER_SERVER == g_adapterType ||
             (ADAPTER_BOTH_CLIENT_SERVER == g_adapterType && CA_RESPONSE_DATA == dataType))
     {
         result = CALEAdapterServerSendData(NULL, data, dataLen);
         if (CA_STATUS_OK != result)
         {
-            ca_mutex_unlock(g_bleIsServerMutex);
+            oc_mutex_unlock(g_bleIsServerMutex);
 
             OIC_LOG(ERROR, CALEADAPTER_TAG, "Send multicast data for server failed" );
 
@@ -2818,7 +3068,7 @@ static int32_t CASendLEMulticastData(const CAEndpoint_t *endpoint,
         result = CALEAdapterClientSendData(NULL, data, dataLen);
         if (CA_STATUS_OK != result)
         {
-            ca_mutex_unlock(g_bleIsServerMutex);
+            oc_mutex_unlock(g_bleIsServerMutex);
 
             OIC_LOG(ERROR, CALEADAPTER_TAG, "Send Multicast data for client failed" );
 
@@ -2829,15 +3079,15 @@ static int32_t CASendLEMulticastData(const CAEndpoint_t *endpoint,
             return -1;
         }
     }
-    ca_mutex_unlock(g_bleIsServerMutex);
+    oc_mutex_unlock(g_bleIsServerMutex);
 
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT - CASendLEMulticastData");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__);
     return dataLen;
 }
 
 static CAResult_t CAGetLEInterfaceInformation(CAEndpoint_t **info, uint32_t *size)
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__);
 
     VERIFY_NON_NULL(info, CALEADAPTER_TAG, "CALocalConnectivity info is null");
 
@@ -2877,27 +3127,27 @@ static CAResult_t CAGetLEInterfaceInformation(CAEndpoint_t **info, uint32_t *siz
     }
 
     OICStrcpy((*info)->addr, sizeof((*info)->addr), local_address);
-    ca_mutex_lock(g_bleLocalAddressMutex);
+    oc_mutex_lock(g_bleLocalAddressMutex);
     OICStrcpy(g_localBLEAddress, sizeof(g_localBLEAddress), local_address);
-    ca_mutex_unlock(g_bleLocalAddressMutex);
+    oc_mutex_unlock(g_bleLocalAddressMutex);
 
     (*info)->adapter = CA_ADAPTER_GATT_BTLE;
     *size = 1;
     OICFree(local_address);
 
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__);
     return CA_STATUS_OK;
 }
 
 static CAResult_t CALERegisterNetworkNotifications(CAAdapterChangeCallback netCallback,
                                                    CAConnectionChangeCallback connCallback)
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__);
 
-    ca_mutex_lock(g_bleNetworkCbMutex);
+    oc_mutex_lock(g_bleNetworkCbMutex);
     g_networkCallback = netCallback;
     g_connectionCallback = connCallback;
-    ca_mutex_unlock(g_bleNetworkCbMutex);
+    oc_mutex_unlock(g_bleNetworkCbMutex);
     CAResult_t res = CA_STATUS_OK;
     if (netCallback)
     {
@@ -2924,21 +3174,32 @@ static CAResult_t CALERegisterNetworkNotifications(CAAdapterChangeCallback netCa
             OIC_LOG(ERROR, CALEADAPTER_TAG, "CASetLENWConnectionStateChangedCb failed!");
         }
     }
+    else
+    {
+        res = CAUnSetLENWConnectionStateChangedCb();
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, CALEADAPTER_TAG, "CAUnSetLENWConnectionStateChangedCb failed!");
+        }
+    }
 
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__);
     return res;
 }
 
 static void CALEConnectionStateChangedCb(CATransportAdapter_t adapter, const char* address,
                                          bool isConnected)
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN - CALEConnectionStateChangedCb");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__);
 
     VERIFY_NON_NULL_VOID(address, CALEADAPTER_TAG, "address");
     (void)adapter;
 
+    CAEndpoint_t localEndpoint = { .adapter = CA_ADAPTER_GATT_BTLE };
+    OICStrcpy(localEndpoint.addr, sizeof(localEndpoint.addr), address);
+
 #ifdef __TIZEN__
-    ca_mutex_lock(g_bleIsServerMutex);
+    oc_mutex_lock(g_bleIsServerMutex);
     switch (g_adapterType)
     {
         case ADAPTER_SERVER:
@@ -2954,7 +3215,7 @@ static void CALEConnectionStateChangedCb(CATransportAdapter_t adapter, const cha
         default:
             break;
     }
-    ca_mutex_unlock(g_bleIsServerMutex);
+    oc_mutex_unlock(g_bleIsServerMutex);
 #endif
 
     if(!isConnected)
@@ -2985,28 +3246,27 @@ static void CALEConnectionStateChangedCb(CATransportAdapter_t adapter, const cha
                                     address);
         }
 #endif
-    }
 
-    CAEndpoint_t localEndpoint = { .adapter = CA_ADAPTER_GATT_BTLE };
-    OICStrcpy(localEndpoint.addr, sizeof(localEndpoint.addr), address);
+#ifdef __WITH_DTLS__
+        CAcloseSslConnection(&localEndpoint);
+#endif
+    }
 
-    ca_mutex_lock(g_bleNetworkCbMutex);
     if (g_connectionCallback)
     {
         g_connectionCallback(&localEndpoint, isConnected);
     }
-    ca_mutex_unlock(g_bleNetworkCbMutex);
 
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__);
 }
 
 static void CALEDeviceStateChangedCb(CAAdapterState_t adapter_state)
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN - CALEDeviceStateChangedCb");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__);
 
     if (CA_ADAPTER_ENABLED == adapter_state)
     {
-        ca_mutex_lock(g_bleIsServerMutex);
+        oc_mutex_lock(g_bleIsServerMutex);
         switch (g_adapterType)
         {
             case ADAPTER_SERVER:
@@ -3022,11 +3282,11 @@ static void CALEDeviceStateChangedCb(CAAdapterState_t adapter_state)
             default:
                 break;
         }
-        ca_mutex_unlock(g_bleIsServerMutex);
+        oc_mutex_unlock(g_bleIsServerMutex);
     }
     else
     {
-        ca_mutex_lock(g_bleIsServerMutex);
+        oc_mutex_lock(g_bleIsServerMutex);
         switch (g_adapterType)
         {
             case ADAPTER_SERVER:
@@ -3042,10 +3302,9 @@ static void CALEDeviceStateChangedCb(CAAdapterState_t adapter_state)
             default:
                 break;
         }
-        ca_mutex_unlock(g_bleIsServerMutex);
+        oc_mutex_unlock(g_bleIsServerMutex);
     }
 
-    ca_mutex_lock(g_bleNetworkCbMutex);
     if (NULL != g_networkCallback)
     {
         g_networkCallback(CA_ADAPTER_GATT_BTLE, adapter_state);
@@ -3054,17 +3313,14 @@ static void CALEDeviceStateChangedCb(CAAdapterState_t adapter_state)
     {
         OIC_LOG(ERROR, CALEADAPTER_TAG, "g_networkCallback is NULL");
     }
-    ca_mutex_unlock(g_bleNetworkCbMutex);
 
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__);
 }
 
 static CAResult_t CALEAdapterClientSendData(const CAEndpoint_t *remoteEndpoint,
                                             const uint8_t *data,
                                             uint32_t dataLen)
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
-
     VERIFY_NON_NULL(data, CALEADAPTER_TAG, "Param data is NULL");
 #ifndef SINGLE_THREAD
     VERIFY_NON_NULL_RET(g_bleClientSendQueueHandle, CALEADAPTER_TAG,
@@ -3074,10 +3330,6 @@ static CAResult_t CALEAdapterClientSendData(const CAEndpoint_t *remoteEndpoint,
                         "g_bleClientSendDataMutex is NULL",
                         CA_STATUS_FAILED);
 
-    VERIFY_NON_NULL_RET(g_bleClientSendQueueHandle, CALEADAPTER_TAG,
-                        "g_bleClientSendQueueHandle",
-                        CA_STATUS_FAILED);
-
     OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Data Sending to LE layer [%u]", dataLen);
 
     CALEData_t *bleData = CACreateLEData(remoteEndpoint, data, dataLen, NULL);
@@ -3087,11 +3339,10 @@ static CAResult_t CALEAdapterClientSendData(const CAEndpoint_t *remoteEndpoint,
         return CA_MEMORY_ALLOC_FAILED;
     }
     // Add message to send queue
-    ca_mutex_lock(g_bleClientSendDataMutex);
+    oc_mutex_lock(g_bleClientSendDataMutex);
     CAQueueingThreadAddData(g_bleClientSendQueueHandle, bleData, sizeof(CALEData_t));
-    ca_mutex_unlock(g_bleClientSendDataMutex);
+    oc_mutex_unlock(g_bleClientSendDataMutex);
 #endif
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
     return CA_STATUS_OK;
 }
 
@@ -3099,7 +3350,7 @@ static CAResult_t CALEAdapterServerSendData(const CAEndpoint_t *remoteEndpoint,
                                             const uint8_t *data,
                                             uint32_t dataLen)
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__);
 
     VERIFY_NON_NULL(data, CALEADAPTER_TAG, "Param data is NULL");
 
@@ -3139,13 +3390,13 @@ static CAResult_t CALEAdapterServerSendData(const CAEndpoint_t *remoteEndpoint,
     }
 
     // Add message to send queue
-    ca_mutex_lock(g_bleServerSendDataMutex);
+    oc_mutex_lock(g_bleServerSendDataMutex);
     CAQueueingThreadAddData(g_bleServerSendQueueHandle,
                             bleData,
                             sizeof(CALEData_t));
-    ca_mutex_unlock(g_bleServerSendDataMutex);
+    oc_mutex_unlock(g_bleServerSendDataMutex);
 #endif
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__);
     return CA_STATUS_OK;
 }
 
@@ -3154,7 +3405,7 @@ static CAResult_t CALEAdapterServerReceivedData(const char *remoteAddress,
                                                 uint32_t dataLength,
                                                 uint32_t *sentLength)
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__);
 
     //Input validation
     VERIFY_NON_NULL(data, CALEADAPTER_TAG, "Data is null");
@@ -3182,9 +3433,9 @@ static CAResult_t CALEAdapterServerReceivedData(const char *remoteAddress,
         g_singleThreadReceiveData = NULL;
     }
 #else
-    VERIFY_NON_NULL_RET(g_bleReceiverQueue,
+    VERIFY_NON_NULL_RET(g_bleServerReceiverQueue,
                         CALEADAPTER_TAG,
-                        "g_bleReceiverQueue",
+                        "g_bleServerReceiverQueue",
                         CA_STATUS_FAILED);
 
     //Add message to data queue
@@ -3203,7 +3454,7 @@ static CAResult_t CALEAdapterServerReceivedData(const char *remoteAddress,
     // Create bleData to add to queue
     OIC_LOG_V(DEBUG,
               CALEADAPTER_TAG,
-              "Data received from LE layer [%d]",
+              "Data received from LE Server layer [%d]",
               dataLength);
 
     CALEData_t * const bleData =
@@ -3218,11 +3469,11 @@ static CAResult_t CALEAdapterServerReceivedData(const char *remoteAddress,
 
     CAFreeEndpoint(remoteEndpoint);
     // Add message to receiver queue
-    CAQueueingThreadAddData(g_bleReceiverQueue, bleData, sizeof(CALEData_t));
+    CAQueueingThreadAddData(g_bleServerReceiverQueue, bleData, sizeof(CALEData_t));
 
     *sentLength = dataLength;
 #endif
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__);
     return CA_STATUS_OK;
 }
 
@@ -3231,14 +3482,12 @@ static CAResult_t CALEAdapterClientReceivedData(const char *remoteAddress,
                                                 uint32_t dataLength,
                                                 uint32_t *sentLength)
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
-
     //Input validation
     VERIFY_NON_NULL(data, CALEADAPTER_TAG, "Data is null");
     VERIFY_NON_NULL(sentLength, CALEADAPTER_TAG, "Sent data length holder is null");
 #ifndef SINGLE_THREAD
-    VERIFY_NON_NULL_RET(g_bleReceiverQueue, CALEADAPTER_TAG,
-                        "g_bleReceiverQueue",
+    VERIFY_NON_NULL_RET(g_bleClientReceiverQueue, CALEADAPTER_TAG,
+                        "g_bleClientReceiverQueue",
                         CA_STATUS_FAILED);
 
     //Add message to data queue
@@ -3251,11 +3500,15 @@ static CAResult_t CALEAdapterClientReceivedData(const char *remoteAddress,
         return CA_STATUS_FAILED;
     }
 
-    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "Data received from LE layer [%u]", dataLength);
-
     // Create bleData to add to queue
-    CALEData_t *bleData = CACreateLEData(remoteEndpoint, data,
-                                         dataLength, g_bleClientSenderInfo);
+    OIC_LOG_V(DEBUG,
+              CALEADAPTER_TAG,
+              "Data received from LE Client layer [%zu]",
+              dataLength);
+
+    CALEData_t * const bleData =
+        CACreateLEData(remoteEndpoint, data, dataLength, g_bleClientSenderInfo);
+
     if (!bleData)
     {
         OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to create bledata!");
@@ -3265,36 +3518,27 @@ static CAResult_t CALEAdapterClientReceivedData(const char *remoteAddress,
 
     CAFreeEndpoint(remoteEndpoint);
     // Add message to receiver queue
-    CAQueueingThreadAddData(g_bleReceiverQueue, bleData, sizeof(CALEData_t));
+    CAQueueingThreadAddData(g_bleClientReceiverQueue, bleData, sizeof(CALEData_t));
 
     *sentLength = dataLength;
 #endif
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
     return CA_STATUS_OK;
 }
 
 static void CASetLEAdapterThreadPoolHandle(ca_thread_pool_t handle)
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
-
-    ca_mutex_lock(g_bleAdapterThreadPoolMutex);
+    oc_mutex_lock(g_bleAdapterThreadPoolMutex);
     g_bleAdapterThreadPool = handle;
-    ca_mutex_unlock(g_bleAdapterThreadPoolMutex);
-
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+    oc_mutex_unlock(g_bleAdapterThreadPoolMutex);
 }
 
 static void CASetLEReqRespAdapterCallback(CANetworkPacketReceivedCallback callback)
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "IN");
-
-    ca_mutex_lock(g_bleAdapterReqRespCbMutex);
+    oc_mutex_lock(g_bleAdapterReqRespCbMutex);
 
     g_networkPacketReceivedCallback = callback;
 
-    ca_mutex_unlock(g_bleAdapterReqRespCbMutex);
-
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "OUT");
+    oc_mutex_unlock(g_bleAdapterReqRespCbMutex);
 }
 
 static void CALEErrorHandler(const char *remoteAddress,
@@ -3302,7 +3546,7 @@ static void CALEErrorHandler(const char *remoteAddress,
                              uint32_t dataLen,
                              CAResult_t result)
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "CALEErrorHandler IN");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__);
 
     VERIFY_NON_NULL_VOID(data, CALEADAPTER_TAG, "Data is null");
 
@@ -3316,19 +3560,19 @@ static void CALEErrorHandler(const char *remoteAddress,
 
     CAFreeEndpoint(rep);
 
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "CALEErrorHandler OUT");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__);
 }
 
 #ifndef SINGLE_THREAD
-static void CALERemoveSendQueueData(CAQueueingThread_t *queueHandle, ca_mutex mutex,
+static void CALERemoveSendQueueData(CAQueueingThread_t *queueHandle, oc_mutex mutex,
                                     const char* address)
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "CALERemoveSendQueueData");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__);
 
     VERIFY_NON_NULL_VOID(queueHandle, CALEADAPTER_TAG, "queueHandle");
     VERIFY_NON_NULL_VOID(address, CALEADAPTER_TAG, "address");
 
-    ca_mutex_lock(mutex);
+    oc_mutex_lock(mutex);
     while (u_queue_get_size(queueHandle->dataQueue) > 0)
     {
         OIC_LOG(DEBUG, CALEADAPTER_TAG, "get data from queue");
@@ -3338,7 +3582,7 @@ static void CALERemoveSendQueueData(CAQueueingThread_t *queueHandle, ca_mutex mu
             CALEData_t *bleData = (CALEData_t *) message->msg;
             if (bleData && bleData->remoteEndpoint)
             {
-                if (!strcmp(bleData->remoteEndpoint->addr, address))
+                if (!strcasecmp(bleData->remoteEndpoint->addr, address))
                 {
                     OIC_LOG(DEBUG, CALEADAPTER_TAG, "found the message of disconnected device");
                     if (NULL != queueHandle->destroy)
@@ -3355,12 +3599,12 @@ static void CALERemoveSendQueueData(CAQueueingThread_t *queueHandle, ca_mutex mu
             }
         }
     }
-    ca_mutex_unlock(mutex);
+    oc_mutex_unlock(mutex);
 }
 
 static void CALERemoveReceiveQueueData(u_arraylist_t *dataInfoList, const char* address)
 {
-    OIC_LOG(DEBUG, CALEADAPTER_TAG, "CALERemoveReceiveQueueData");
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "%s", __func__);
 
     VERIFY_NON_NULL_VOID(dataInfoList, CALEADAPTER_TAG, "dataInfoList");
     VERIFY_NON_NULL_VOID(address, CALEADAPTER_TAG, "address");
@@ -3374,10 +3618,17 @@ static void CALERemoveReceiveQueueData(u_arraylist_t *dataInfoList, const char*
         uint32_t arrayLength = u_arraylist_length(portList);
         for (uint32_t i = 0; i < arrayLength; i++)
         {
-            uint16_t port = (uint16_t)(uintptr_t)u_arraylist_get(portList, i);
-            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "port : %X", port);
+            uint16_t *port = (uint16_t *)u_arraylist_get(portList, i);
+            if (!port)
+            {
+                OIC_LOG(ERROR, CALEADAPTER_TAG, "Failed to get port from sender info !");
+                u_arraylist_destroy(portList);
+                return;
+            }
 
-            if (CA_STATUS_OK == CALEGetSenderInfo(address, port,
+            OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "port : %X", *port);
+
+            if (CA_STATUS_OK == CALEGetSenderInfo(address, *port,
                                                   dataInfoList, &senderInfo,
                                                   &senderIndex))
             {
@@ -3419,7 +3670,14 @@ static CAResult_t CALEGetPortsFromSenderInfo(const char *leAddress,
 
         if (!strncmp(info->remoteEndpoint->addr, leAddress, addrLength))
         {
-            u_arraylist_add(portList, (void *)(uintptr_t)info->remoteEndpoint->port);
+            uint16_t *port = (uint16_t *)OICMalloc(sizeof(uint16_t));
+            if (!port)
+            {
+                OIC_LOG(ERROR, CALEADAPTER_TAG, "memory allocation failed!");
+                return CA_MEMORY_ALLOC_FAILED;
+            }
+            *port = info->remoteEndpoint->port;
+            u_arraylist_add(portList, (void *)port);
         }
     }
 
@@ -3433,3 +3691,51 @@ static CAResult_t CALEGetPortsFromSenderInfo(const char *leAddress,
     }
 }
 #endif
+
+void CALEStartGattServer()
+{
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__);
+
+    oc_mutex_lock(g_bleIsServerMutex);
+    switch (g_adapterType)
+    {
+        case ADAPTER_SERVER:
+            CALEAdapterGattServerStart();
+             break;
+        case ADAPTER_CLIENT:
+            CALEAdapterGattClientStart();
+            break;
+        case ADAPTER_BOTH_CLIENT_SERVER:
+            CALEAdapterGattServerStart();
+            CALEAdapterGattClientStart();
+            break;
+        default:
+            break;
+    }
+    oc_mutex_unlock(g_bleIsServerMutex);
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__);
+}
+
+void CALEStopGattServer()
+{
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "IN %s", __func__);
+
+    oc_mutex_lock(g_bleIsServerMutex);
+    switch (g_adapterType)
+    {
+        case ADAPTER_SERVER:
+            CALEAdapterGattServerStop();
+            break;
+        case ADAPTER_CLIENT:
+            CALEAdapterGattClientStop();
+            break;
+        case ADAPTER_BOTH_CLIENT_SERVER:
+            CALEAdapterGattServerStop();
+            CALEAdapterGattClientStop();
+            break;
+        default:
+            break;
+    }
+    oc_mutex_unlock(g_bleIsServerMutex);
+    OIC_LOG_V(DEBUG, CALEADAPTER_TAG, "OUT %s", __func__);
+}
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/ios/SConscript b/resource/csdk/connectivity/src/bt_le_adapter/ios/SConscript
new file mode 100755 (executable)
index 0000000..019e4f2
--- /dev/null
@@ -0,0 +1,15 @@
+#######################################################
+#       Build BLE adapter for Android
+#######################################################
+
+Import('env', 'src_dir')
+import os.path
+
+root_dir = os.pardir
+env.PrependUnique(CPPPATH = [ os.path.join(src_dir, 'ios') ])
+
+src_files = [ 'caleclient.m',
+              'caleserver.m',
+              'calenwmonitor.m']
+
+Return('src_files')
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/ios/caleclient.h b/resource/csdk/connectivity/src/bt_le_adapter/ios/caleclient.h
new file mode 100644 (file)
index 0000000..97d6940
--- /dev/null
@@ -0,0 +1,509 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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 BT LE communications.
+ */
+#ifndef CA_LECLIENT_H_
+#define CA_LECLIENT_H_
+
+#include "cacommon.h"
+#include "cathreadpool.h"
+#include "uarraylist.h"
+
+#include "calenwmonitor.h"
+#include "caleutils.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+static const uint16_t GATT_ERROR = 133;
+
+static const uint16_t STATE_CHARACTER_SET = 2;
+static const uint16_t STATE_CHARACTER_UNSET = 1;
+static const uint16_t STATE_CHARACTER_NO_CHANGE = 0;
+
+static const uint16_t STATE_SEND_NONE = 0;
+static const uint16_t STATE_SEND_SUCCESS = 1;
+static const uint16_t STATE_SEND_FAILED = 2;
+
+typedef struct le_state_info
+{
+    char address[CA_MACADDR_SIZE];
+    int connectedState;
+    uint16_t notificationState;
+    uint16_t sendState;
+    bool autoConnectFlag;
+} CALEState_t;
+
+/**
+ * Callback to be notified on reception of any data from remote devices.
+ * @param[in]  address                MAC address of remote device.
+ * @param[in]  data                   Data received from remote device.
+ * @pre  Callback must be registered using CALESetCallback(CAPacketReceiveCallback callback)
+ */
+typedef void (*CAPacketReceiveCallback)(const char *address,
+                                        const uint8_t *data);
+
+typedef void (*CAManagerAdapterStateChangeCallback)(CBCentralManager *central);
+typedef void (*CAManagerConnectionCallback)(CBPeripheral *peripheral, const char *remote_address,
+                                            bool connected, NSError *error);
+typedef void (*CAManagerServiceDiscoveredCallback)(CBPeripheral *peripheral,
+                                                   const char *remote_address, NSError *error);
+
+/**
+ * initialize client for BLE.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientInitialize();
+
+/**
+ * terminate client for BLE.
+ */
+void CALEClientTerminate();
+
+
+/**
+ * for destroy sending routine.
+ * @param[in]   peripheral    remotePeripheral object
+ */
+void CALEClientSendFinish(CBPeripheral *peripheral);
+
+/**
+ * send data for unicast (interface).
+ * @param[in]   address               remote address.
+ * @param[in]   data                  data for transmission.
+ * @param[in]   dataLen               data length.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientSendUnicastMessage(const char *address,
+                                        const uint8_t *data,
+                                        const uint32_t dataLen);
+
+/**
+ * send data for multicast (interface).
+ * @param[in]   data                  data for transmission.
+ * @param[in]   dataLen               data length.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientSendMulticastMessage(const uint8_t *data, const uint32_t dataLen);
+
+/**
+ * start unicast server.
+ * @param[in]   address               remote address.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientStartUnicastServer(const char *address);
+
+/**
+ * start multicast server (start discovery).
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientStartMulticastServer();
+
+/**
+ * stop unicast server.
+ */
+void CALEClientStopUnicastServer();
+
+/**
+ * stop multicast server (stop discovery).
+ */
+void CALEClientStopMulticastServer();
+
+/**
+ * set this callback for receiving data packets from peer devices.
+ * @param[in]   callback              callback to be notified on reception of
+ *                                    unicast/multicast data packets.
+ */
+void CALEClientSetCallback(CAPacketReceiveCallback callback);
+
+void CALEClientSetCAManagerCallback(CAManagerAdapterStateChangeCallback adapterStateChangeCB,
+                                    CAManagerConnectionCallback connectionCB,
+                                    CAManagerServiceDiscoveredCallback serviceDiscoverdCB);
+
+/**
+ * waiting to get scanned device from BT Platform.
+ * if there is no scanned device in the list.
+ * @param[in]   address               LE address.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientIsThereScannedDevices(const char* address);
+
+/**
+ * send data for unicast (implement).
+ * @param[in]   address               remote address.
+ * @param[in]   data                  data for transmission.
+ * @param[in]   dataLen               data length.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientSendUnicastMessageImpl(const char *address,
+                                            const uint8_t *data,
+                                            const uint32_t dataLen);
+
+/**
+ * send data for multicast (implement).
+ * @param[in]   data                  data for transmission.
+ * @param[in]   dataLen               data length.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientSendMulticastMessageImpl(const uint8_t *data,
+                                              const uint32_t dataLen);
+
+/**
+ * check whether it is connected or not with remote address.
+ * @param[in]   address               remote address.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALECheckSendState(const char* address);
+
+/**
+ * send data to remote device.
+ * if it isn't connected yet. connect LE before try to send data.
+ * @param[in]   peripheral          remote peripheral object
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientSendData(CBPeripheral *peripheral);
+
+/**
+ * get address from bluetooth gatt object.
+ * @param[in]   peripheral        remote peripheral Object
+ * @return  bluetooth address.
+ */
+NSString *CALEClientGetAddressFromGattObj(CBPeripheral *peripheral);
+
+/**
+ * get remote address from bluetooth socket object.
+ * @param[in]   peripheral        remote peripheral Object
+ * @return  bluetooth address.
+ */
+NSString *CALEClientGetRemoteAddress(CBPeripheral *peripheral);
+
+/**
+ * close gatt.
+ * @param[in]   peripheral        remote peripheral Object
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientGattClose(CBPeripheral *peripheral);
+
+/**
+ * start to scan whole bluetooth devices (interface).
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientStartScan();
+
+/**
+ * stop scan (interface).
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientStopScan();
+
+/**
+ * set ble scanning flag.
+ * @param[in]   flag        scan flag.
+ */
+void CALEClientSetScanFlag(bool flag);
+
+/**
+ * set auto connect flag for connectGatt API.
+ * @param[in]   address           remote address.
+ * @param[in]   flag              auto connect flag.
+ */
+CAResult_t CALEClientSetAutoConnectFlag(const char *remoteAddress, bool flag);
+
+/**
+ * get auto connect flag.
+ * @param[in]   address           remote address.
+ * @return  current auto connect flag;
+ */
+bool CALEClientGetAutoConnectFlag(const char *address);
+
+/**
+ * connect to gatt server hosted.
+ * @param[in]   bluetoothDevice       bluetooth Device object.
+ * @param[in]   autoconnect           whether to directly connect to the remote device(false) or
+ *                                     to automatically connect as soon as the remote device
+ *                                     becomes available.
+ * @return  void
+ */
+CAResult_t CALEClientConnect(CBPeripheral *peripheral, bool autoconnect);
+
+/**
+ * disconnect to gatt server by a target device.
+ * @param[in]   peripheral        remote peripheral Object
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientDisconnect(CBPeripheral *peripheral);
+
+/**
+ * cancel to gatt connecting by a target device.
+ * @param[in]   peripheral        remote peripheral Object
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientConnectCancel(CBPeripheral *peripheral);
+
+/**
+ * set retreived peripheral to scan device list.
+ * @param[in]   peripheral        remote peripheral Object
+ * @return  ::remote_address.
+ */
+
+/**
+ * disconnect to gatt server by whole devices.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientDisconnectAll();
+
+/**
+ * disconnect to gatt server by selected address.
+ * @param[in]   remoteAddress         remote address.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientDisconnectforAddress(const char *remoteAddress);
+
+/**
+ * start discovery server.
+ * @param[in]   peripheral        remote peripheral Objectyy
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientDiscoverServices(CBPeripheral *peripheral);
+
+/**
+ * call CALESetValueAndWriteCharacteristic when connection is successful.
+ * @param[in]   peripheral        remote peripheral Objectyy
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientWriteCharacteristic(CBPeripheral *peripheral);
+
+
+/**
+ * create GattCharacteristic and call CALEClientWriteCharacteristicImpl
+ * for request to write gatt characteristic.
+ * @param[in]   peripheral        remote peripheral Objectyy
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+
+/**
+ * request to write gatt characteristic.
+ * @param[in]   peripheral        remote peripheral Objectyy
+ * @param[in]   characteristic    characteristic object that contain data to send.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientWriteCharacteristicImpl(CBPeripheral *peripheral,
+                                             CBCharacteristic *characteristic);
+
+/**
+ * enable notification for a target device.
+ * @param[in]   peripheral        remote peripheral Objectyy
+ * @param[in]   characteristic    characteristic object that contain data to send.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientSetCharacteristicNotification(CBPeripheral *peripheral,
+                                                   CBCharacteristic *characteristic);
+
+/**
+ * create gatt characteristic object.
+ * @param[in]   peripheral        remote peripheral Objectyy
+ * @return  CBCharacteristic handler
+ */
+CBCharacteristic *CALEClientCreateGattCharacteristic(CBPeripheral *peripheral);
+
+/**
+ * add device object to scan device list.
+ * @param[in]   device                bluetooth device object.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientAddScanDeviceToList(CBPeripheral *peripheral);
+
+/**
+ * check whether the device exist in list or not.
+ * @param[in]   remoteAddress         remote address.
+ * @return  true or false.
+ */
+bool CALEClientIsDeviceInScanDeviceList(const char *remoteAddress);
+
+/**
+ * remove all devices in scan device list.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientRemoveAllScanDevices();
+
+/**
+ * remove target device in scan device list.
+ * @param[in]   remoteAddress         remote address.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientRemoveDeviceInScanDeviceList(NSString *remoteAddress);
+
+/**
+ * add gatt object to gatt object list.
+ * @param[in]   gatt                  Gatt profile object.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientAddGattobjToList(CBPeripheral *peripheral);
+
+/**
+ * check whether the gatt object exist in list or not.
+ * @param[in]   remoteAddress         remote address.
+ * @return  true or false.
+ */
+bool CALEClientIsGattObjInList(const char *remoteAddress);
+
+/**
+ * get the gatt object.
+ * @param[in]   remoteAddress         remote address.
+ * @return  gatt object.
+ */
+CBPeripheral *CALEClientGetGattObjInList(const char* remoteAddress);
+
+/**
+ * remove all gatt objects in gatt object list.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientRemoveAllGattObjs();
+
+/**
+ * remove target device in gatt object list.
+ * @param[in]   gatt                  Gatt profile object.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientRemoveGattObj(CBPeripheral *peripheral);
+
+/**
+ * remove gatt object of target device for address in gatt object list.
+ * @param[in]   gatt                  Gatt profile object.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientRemoveGattObjForAddr(const char* addr);
+
+/**
+ * get ble address from Bluetooth device.
+ * @param[in]   bluetoothDevice       Bluetooth device.
+ * @return  ble address.
+ */
+NSString *CALEClientGetLEAddressFromBTDevice(CBPeripheral *peripheral);
+
+/**
+ * update new state information.
+ * @param[in]   address               remote address.
+ * @param[in]   connectedState        connection state.
+ * @param[in]   notificationState     whether characteristic notification already set or not.
+ * @param[in]   sendState             whether sending was success or not.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientUpdateDeviceState(const char* address,
+                                    uint32_t connectedState,
+                                    uint16_t notificationState,
+                                    uint16_t sendState);
+
+/**
+ * add new state to state list.
+ * @param[in]   state                 new state.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state);
+
+/**
+ * check whether the remote address is existed or not.
+ * @param[in]   address               remote address.
+ * @return  true or false.
+ */
+bool CALEClientIsDeviceInList(const char *remoteAddress);
+
+/**
+ * remove all device states.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientRemoveAllDeviceState();
+
+/**
+ * Reset values of device state for all of devices.
+ * this method has to be invoked when BT adapter is disabled.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientResetDeviceStateForAll();
+
+/**
+ * remove the device state for a remote device.
+ * @param[in]   remoteAddress         remote address.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress);
+
+/**
+ * get state information for a remote device.
+ * @param[in]   remoteAddress         remote address.
+ * @return  CALEState_t.
+ */
+CALEState_t* CALEClientGetStateInfo(const char* remoteAddress);
+
+/**
+ * check whether the remote address is connected or not.
+ * @param[in]   remoteAddress         remote address.
+ * @return  true or false.
+ */
+bool CALEClientIsConnectedDevice(const char* remoteAddress);
+
+/**
+ * check whether the remote address set CharacteristicNotification or not.
+ * @param[in]   remoteAddress         remote address.
+ * @return  true or false.
+ */
+bool CALEClientIsSetCharacteristic(const char* remoteAddress);
+
+/**
+ * create scan device list.
+ */
+void CALEClientCreateDeviceList();
+
+/**
+ * update the counter which data is sent to remote device.
+ */
+void CALEClientUpdateSendCnt();
+
+/**
+ * initialize mutex.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientInitGattMutexVaraibles();
+
+/**
+ * terminate mutex.
+ */
+void CALEClientTerminateGattMutexVariables();
+
+/**
+ * set send finish flag.
+ * @param[in]   flag        finish flag.
+ */
+void CALEClientSetSendFinishFlag(bool flag);
+
+static bool isEnableBtAdapter = false;
+bool CALEClientIsEnableBTAdapter();
+void CALEClientSetFlagBTAdapter(bool state);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* CA_LECLIENT_H_ */
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/ios/caleclient.m b/resource/csdk/connectivity/src/bt_le_adapter/ios/caleclient.m
new file mode 100644 (file)
index 0000000..f148899
--- /dev/null
@@ -0,0 +1,2954 @@
+/******************************************************************
+ *
+ * Copyright 2017 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 <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "caleclient.h"
+#include "caleserver.h"
+#include "caleutils.h"
+#include "caleinterface.h"
+#include "caadapterutils.h"
+
+#include "logger.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "cathreadpool.h" /* for thread pool */
+#include "octhread.h"
+#include "uarraylist.h"
+
+#define TAG PCF("OIC_CA_LE_CLIENT")
+
+#define MICROSECS_PER_SEC 1000000
+#define WAIT_TIME_WRITE_CHARACTERISTIC 10 * MICROSECS_PER_SEC
+
+#define TV_ADV_DATA_MIN_LEN            26
+
+#define TV_ADV_COMPANY_ID_INDEX1       0
+#define TV_ADV_COMPANY_ID_INDEX2       1
+#define TV_ADV_VERSION_INDEX           2
+#define TV_ADV_SERVICE_TYPE_INDEX      3
+#define PON_ADV_DEVICE_TYPE_INDEX      4
+#define OOB_AV_ADV_DEVICE_TYPE_INDEX   4
+#define OOB_TV_ADV_DEVICE_TYPE_INDEX   10
+#define TV_ADV_SCAN_RESP_LEN_INDEX     4
+#define TV_ADV_DEVICE_STATUS_INDEX     5
+
+#define TV_ADV_PON_MAC_BYTE_1          7
+#define TV_ADV_PON_MAC_BYTE_2          8
+#define TV_ADV_PON_MAC_BYTE_3          9
+#define TV_ADV_PON_MAC_BYTE_4          10
+#define TV_ADV_PON_MAC_BYTE_5          11
+#define TV_ADV_PON_MAC_BYTE_6          12
+
+#define AV_ADV_OOB_MAC_BYTE_1          7
+#define AV_ADV_OOB_MAC_BYTE_2          8
+#define AV_ADV_OOB_MAC_BYTE_3          9
+#define AV_ADV_OOB_MAC_BYTE_4          10
+#define AV_ADV_OOB_MAC_BYTE_5          11
+#define AV_ADV_OOB_MAC_BYTE_6          12
+
+#define PON_TV_AV_DIFF                 3  // TV mac is 7-12 bytes, av mac is 10-15 bytes
+
+#define TV_ADV_BD_ADDRTYPE_INDEX       19
+
+#define TV_ADV_OOB_MAC_BYTE_1          20
+#define TV_ADV_OOB_MAC_BYTE_2          21
+#define TV_ADV_OOB_MAC_BYTE_3          22
+#define TV_ADV_OOB_MAC_BYTE_4          23
+#define TV_ADV_OOB_MAC_BYTE_5          24
+#define TV_ADV_OOB_MAC_BYTE_6          25
+
+#define TV_ADV_COMPANY_ID1             0x75
+#define TV_ADV_COMPANY_ID2             0x00
+#define TV_ADV_VERSION                 0x42
+
+#define TV_ADV_SERVICE_ID_POWER        0x04
+#define TV_ADV_SERVICE_ID_OOB          0x09
+
+#define TV_ADV_DEVICE_TV               0x01
+#define TV_ADV_DEVICE_STATUS_ON        0x01
+#define TV_ADV_DEVICE_STATUS_UNKNOWN   0x20
+
+#define TV_ADV_BD_ADDR_ID              0x01
+#define TV_ADV_SCAN_RESP_LEN           0x06
+
+#define DEVICE_TYPE_TV                 1
+#define DEVICE_TYPE_AV                 3
+
+
+
+static ca_thread_pool_t g_threadPoolHandle = NULL;
+
+static u_arraylist_t *g_deviceList = NULL; // device list to have same UUID
+static u_arraylist_t *g_gattObjectList = NULL;
+static u_arraylist_t *g_deviceStateList = NULL;
+
+static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
+static CABLEErrorHandleCallback g_clientErrorCallback;
+
+static CAManagerAdapterStateChangeCallback g_caManagerAdapterStateChangeCallback = NULL;
+static CAManagerConnectionCallback g_caManagerConnectionCallback = NULL;
+static CAManagerServiceDiscoveredCallback g_caManagerServiceDiscoveredCallback = NULL;
+static dispatch_queue_t g_caManagerQueue = NULL;
+
+static NSString *mac_ref = @"AB:CD:EF:15:";
+int mac_add = 4096;
+
+static bool g_isStartedLEClient = false;
+static bool g_isStartedScan = false;
+
+static NSData* g_sendBuffer = nil;
+static uint32_t g_targetCnt = 0;
+static uint32_t g_currentSentCnt = 0;
+static bool g_isFinishedSendData = false;
+static oc_mutex g_SendFinishMutex = NULL;
+static oc_mutex g_threadMutex = NULL;
+static oc_cond g_threadCond = NULL;
+static oc_cond g_deviceDescCond = NULL;
+
+static oc_mutex g_threadSendMutex = NULL;
+static oc_mutex g_threadWriteCharacteristicMutex = NULL;
+static oc_cond g_threadWriteCharacteristicCond = NULL;
+static bool g_isSignalSetFlag = false;
+
+static oc_mutex g_bleReqRespClientCbMutex = NULL;
+static oc_mutex g_bleServerBDAddressMutex = NULL;
+
+static oc_mutex g_deviceListMutex = NULL;
+static oc_mutex g_gattObjectMutex = NULL;
+static oc_mutex g_deviceStateListMutex = NULL;
+
+static oc_mutex g_deviceScanRetryDelayMutex = NULL;
+static oc_cond g_deviceScanRetryDelayCond = NULL;
+
+static oc_mutex g_scanMutex = NULL;
+static oc_mutex waitMutex = NULL;
+
+static oc_mutex g_initializeMutex = NULL;
+static oc_cond g_initializeCond = NULL;
+
+static CABLEDataReceivedCallback g_CABLEClientDataReceivedCallback = NULL;
+
+@interface CBCentralIfClass:NSObject <CBCentralManagerDelegate>
+@end
+static id cbCentralIf;
+NSMutableArray *centralMgrs;
+NSMutableDictionary *cbPeripherals;
+NSMutableDictionary *cbServices;
+NSMutableDictionary *requestCharacs;
+NSMutableDictionary *responseCharacs;
+NSArray<CBUUID *> *g_uuidList;
+
+@implementation CBCentralIfClass
+static CBCentralManager *centralMgr = nil;
+
+- (void) CALEClientCreateCentralManager{
+    centralMgr = [[CBCentralManager alloc] initWithDelegate:self queue:nil
+                                           options:[NSDictionary dictionaryWithObject:
+                                           [NSNumber numberWithInt:0]
+                                                  forKey:CBCentralManagerOptionShowPowerAlertKey]];
+
+    centralMgrs = [NSMutableArray new];
+
+    cbPeripherals = [[NSMutableDictionary alloc] init];
+    cbServices = [[NSMutableDictionary alloc] init];
+    requestCharacs = [[NSMutableDictionary alloc] init];
+    responseCharacs = [[NSMutableDictionary alloc] init];
+}
+
+- (CAResult_t) CALEClientStartScanImpl{
+    OIC_LOG(DEBUG, TAG, "[CBCtrl] In - CALEClientStartScanImpl");
+    if ([centralMgrs count] == 0){
+        OIC_LOG(ERROR, TAG, "[CBCtrl] central manager is not available");
+        return CA_ADAPTER_NOT_ENABLED;
+    }else{
+        CALEClientSetScanFlag(true);
+
+        [centralMgr scanForPeripheralsWithServices:nil
+                    options:@{CBCentralManagerScanOptionAllowDuplicatesKey:@NO}];
+    }
+    return CA_STATUS_OK;
+}
+
+- (CAResult_t) CALEClientStartScanWithUUIDImpl: (NSArray<CBUUID*> *)uuids{
+    OIC_LOG(DEBUG, TAG, "[CBCtrl] In - CALEClientStartScanWithUUIDImpl");
+    if ([centralMgrs count] == 0){
+        OIC_LOG(ERROR, TAG, "[CBCtrl] central manager is not available");
+        return CA_ADAPTER_NOT_ENABLED;
+    }else{
+        CALEClientSetScanFlag(true);
+        [centralMgr scanForPeripheralsWithServices:uuids
+                                     options:@{CBCentralManagerScanOptionAllowDuplicatesKey:@YES}];
+    }
+    return CA_STATUS_OK;
+}
+
+- (CAResult_t) CALEClientStopScanImpl{
+    OIC_LOG(DEBUG, TAG, "[CBCtrl] In - CALEClientStopScanImpl");
+    if ([centralMgrs count] == 0){
+        OIC_LOG(ERROR, TAG, "[CBCtrl] central manager is not available");
+        return CA_ADAPTER_NOT_ENABLED;
+    }else{
+        CALEClientSetScanFlag(false);
+        [centralMgr stopScan];
+    }
+    return CA_STATUS_OK;
+}
+
+- (CAResult_t) CALEClientConnectImpl: (CBPeripheral *)peripheral{
+    if (peripheral == (id) [NSNull null]){
+        OIC_LOG(ERROR, TAG, "[CBCtrl] In - CALEClientConnectImpl: peripheral is null");
+    }else{
+        OIC_LOG(DEBUG, TAG, "[CBCtrl] In - CALEClientConnectImpl");
+        OIC_LOG_V(INFO, TAG, "peripheral name = %s", [[peripheral name] UTF8String]);
+
+        [centralMgr connectPeripheral: peripheral options:nil];
+        return CA_STATUS_OK;
+    }
+    return CA_STATUS_FAILED;
+}
+
+- (CAResult_t) CALEClientDiscoverServices: (CBPeripheral *)peripheral{
+    if (peripheral == (id) [NSNull null]){
+        OIC_LOG(ERROR, TAG, "[CBCtrl] In - CALEClientDiscoverServices: peripheral is null");
+    }else{
+        OIC_LOG_V(DEBUG, TAG, "[CBCtrl] In - CALEClientDiscoverServices: %s",
+                  [[cbPeripherals objectForKey:peripheral] UTF8String] );
+        OIC_LOG_V(INFO, TAG, "peripheral name = %s", [[peripheral name] UTF8String]);
+
+        [peripheral discoverServices:
+         @[[CBUUID UUIDWithString:[NSString stringWithUTF8String:OIC_GATT_SERVICE_UUID]]]];
+        return CA_STATUS_OK;
+    }
+    return CA_STATUS_FAILED;
+}
+
+-(CAResult_t) CALEClientSetNotifyCharacteristic: (CBPeripheral *)peripheral
+                                               : (CBCharacteristic *)characteristic{
+    if ((peripheral == (id) [NSNull null]) || (characteristic == (id) [NSNull null])){
+        OIC_LOG(ERROR, TAG, "[CBCtrl] CALEClientSetNotifyCharacteristic: parameter is null");
+    }else{
+        OIC_LOG(DEBUG, TAG, "[CBCtrl] CALEClientSetNotifyCharacteristic");
+        [peripheral setNotifyValue:YES forCharacteristic:characteristic];
+        return CA_STATUS_OK;
+    }
+    return CA_STATUS_FAILED;
+}
+
+- (void) CALEClientCancelPeripheralConnection: (CBPeripheral *)peripheral{
+    [centralMgr cancelPeripheralConnection:peripheral];
+}
+
+- (CAResult_t) CALEClientWriteValue:(CBPeripheral *)peripheral :(CBCharacteristic *)characteristic{
+    OIC_LOG(DEBUG, TAG, "[CBCtrl] CALEClientWriteRequest");
+    if ([characteristic.UUID isEqual: [CBUUID UUIDWithString:
+                           [NSString stringWithUTF8String:OIC_GATT_CHARACTERISTIC_REQUEST_UUID]]]){
+        if (g_sendBuffer == nil || g_sendBuffer == NULL || [g_sendBuffer length] <= 0){
+            OIC_LOG(ERROR, TAG, "[CBCtrl] g_sendbuffer size is 0!!!");
+            return CA_STATUS_FAILED;
+        }else{
+            NSUInteger len = [g_sendBuffer length];
+            OIC_LOG_V(DEBUG, TAG, "[CBCtrl] write data: size(%lu)", len);
+            uint8_t *data = (uint8_t*)malloc(len);
+            memcpy(data, [g_sendBuffer bytes], len);
+            OIC_LOG_BUFFER(DEBUG, TAG, data, len);
+            free(data);
+            [peripheral writeValue:g_sendBuffer
+                 forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
+            return CA_STATUS_OK;
+        }
+    }else{
+        OIC_LOG(ERROR, TAG, "[CBCtrl] requestUUID is different");
+    }
+    return CA_STATUS_FAILED;
+}
+
+
+- (NSString *) CALEClientGetMAC : (NSData*) data{
+
+    if([data length] >= TV_ADV_DATA_MIN_LEN)
+    {
+        const unsigned char *bytes = (unsigned char *)data.bytes;
+
+        int b1 = (int)bytes[TV_ADV_COMPANY_ID_INDEX1];
+        int b2 = (int)bytes[TV_ADV_COMPANY_ID_INDEX2];
+        int b4 = (int)bytes[TV_ADV_SERVICE_TYPE_INDEX];  //service type Power ON/OFF
+
+        if((b1 == TV_ADV_COMPANY_ID1) && (b2 == TV_ADV_COMPANY_ID2)
+           && (b4 == TV_ADV_SERVICE_ID_POWER))
+        {
+            // samsung && power service
+            int b5 = (int)bytes[PON_ADV_DEVICE_TYPE_INDEX];  //devive type, 1 = TV, 3 = AV
+            int index_offset = (b5 == DEVICE_TYPE_TV)? 0 : PON_TV_AV_DIFF;
+            NSMutableString* mac_address = [NSMutableString stringWithFormat:@""];
+            [mac_address appendFormat:@"%02x:%02x:%02x:%02x:%02x:%02x",
+             (int)bytes[TV_ADV_PON_MAC_BYTE_1 + index_offset],
+             (int)bytes[TV_ADV_PON_MAC_BYTE_2 + index_offset],
+             (int)bytes[TV_ADV_PON_MAC_BYTE_3 + index_offset],
+             (int)bytes[TV_ADV_PON_MAC_BYTE_4 + index_offset],
+             (int)bytes[TV_ADV_PON_MAC_BYTE_5 + index_offset],
+             (int)bytes[TV_ADV_PON_MAC_BYTE_6 + index_offset]];
+
+            OIC_LOG_V(INFO, TAG, "TV Power on/off MAC = %s", [mac_address UTF8String]);
+
+            return mac_address;
+        }
+
+        if((b1 == TV_ADV_COMPANY_ID1) && (b2 == TV_ADV_COMPANY_ID2)
+           && (b4 == TV_ADV_SERVICE_ID_OOB))
+        {
+            // samsung && oob
+            int b5 = (int)bytes[OOB_AV_ADV_DEVICE_TYPE_INDEX];  //devive type, 3 = AV // for TV this bit is in fact version number which is always 1 at this moment.
+                                                                //at this moment, there is no definitive way to detect TV or AV from OOB advertisement.
+            NSMutableString* mac_address = [NSMutableString stringWithFormat:@""];
+
+            if(b5 == DEVICE_TYPE_AV)
+            {
+                [mac_address appendFormat:@"%02x:%02x:%02x:%02x:%02x:%02x",
+                     (int)bytes[AV_ADV_OOB_MAC_BYTE_1],
+                     (int)bytes[AV_ADV_OOB_MAC_BYTE_2],
+                     (int)bytes[AV_ADV_OOB_MAC_BYTE_3],
+                     (int)bytes[AV_ADV_OOB_MAC_BYTE_4],
+                     (int)bytes[AV_ADV_OOB_MAC_BYTE_5],
+                     (int)bytes[AV_ADV_OOB_MAC_BYTE_6]];
+
+                OIC_LOG_V(INFO, TAG, "AV OOB MAC = %s", [mac_address UTF8String]);
+            }
+            else
+            {
+                [mac_address appendFormat:@"%02x:%02x:%02x:%02x:%02x:%02x",
+                     (int)bytes[TV_ADV_OOB_MAC_BYTE_1],
+                     (int)bytes[TV_ADV_OOB_MAC_BYTE_2],
+                     (int)bytes[TV_ADV_OOB_MAC_BYTE_3],
+                     (int)bytes[TV_ADV_OOB_MAC_BYTE_4],
+                     (int)bytes[TV_ADV_OOB_MAC_BYTE_5],
+                     (int)bytes[TV_ADV_OOB_MAC_BYTE_6]];
+
+                OIC_LOG_V(INFO, TAG, "TV OOB MAC = %s", [mac_address UTF8String]);
+            }
+
+            return mac_address;
+        }
+    }
+
+    NSString *Hex = [NSString stringWithFormat:@"0x%X", mac_add];
+    NSString *Hex_add = [Hex substringFromIndex:2];
+    NSString *first_add = [Hex_add substringToIndex:2];
+    NSString *second_add = [Hex_add substringFromIndex:2];
+    NSString *comma = @":";
+
+    NSString *MAC;
+    MAC = [NSString stringWithString:mac_ref];
+    MAC = [MAC stringByAppendingString:first_add];
+    MAC = [MAC stringByAppendingString:comma];
+    MAC = [MAC stringByAppendingString:second_add];
+
+    OIC_LOG_V(INFO, TAG, "MAC: %s", [MAC UTF8String]);
+
+    if(mac_add == 65535){
+        mac_add=256;
+    }else{
+        mac_add++;
+    }
+
+    return MAC;
+}
+
+- (NSString *) CALEGetAddressFromBTDevice: (CBPeripheral *)peripheral{
+    if (peripheral == (id) [NSNull null]){
+        OIC_LOG(ERROR, TAG, "[CBCtrl] In - CALEGetAddressFromBTDevice: peripheral is null");
+    }else{
+        return [cbPeripherals objectForKey: peripheral];
+    }
+    return nil;
+}
+
+#pragma mark - CBCentralManagerDelegate
+- (void)centralManagerDidUpdateState:(CBCentralManager *)central{
+    switch(central.state){
+        case CBCentralManagerStatePoweredOn:
+            OIC_LOG(DEBUG, TAG, "CBCentralManager update state --> Powered ON");
+
+            //if state callback is called before bt le client initialize done, wait signal.
+            if (!g_isStartedLEClient) {
+                OIC_LOG(INFO, TAG, "wait for finishing initialize..");
+
+                if (NULL == g_initializeMutex)
+                {
+                    g_initializeMutex = oc_mutex_new();
+                    if (NULL == g_initializeMutex)
+                    {
+                        OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+                    }
+                }
+
+                oc_mutex_lock(g_initializeMutex);
+                oc_cond_wait(g_initializeCond, g_initializeMutex);
+                oc_mutex_unlock(g_initializeMutex);
+            }
+
+            if (![centralMgrs containsObject: centralMgr]) {
+                centralMgr = central;
+                [centralMgrs addObject: centralMgr];
+            }
+
+            CALEClientSetFlagBTAdapter(true);
+            CALEClientNWStateChangeCallback(CALE_STATE_ON);
+
+            break;
+        case CBCentralManagerStateResetting:
+            OIC_LOG(DEBUG, TAG, "CBCentralManager update state --> StateResetting");
+            break;
+        case CBCentralManagerStateUnsupported:
+        case CBCentralManagerStateUnauthorized:
+        case CBCentralManagerStatePoweredOff:
+        default:
+            OIC_LOG(DEBUG, TAG, "CBCentralManager update state --> Not Available");
+            CALEClientSetFlagBTAdapter(false);
+            CALEClientResetDeviceStateForAll();
+
+            CALEClientRemoveAllGattObjs();
+            break;
+    }
+
+    if(g_caManagerQueue)
+    {
+        dispatch_async(g_caManagerQueue, ^{
+
+            if(g_caManagerAdapterStateChangeCallback)
+            {
+                g_caManagerAdapterStateChangeCallback(central);
+            }
+        });
+    }
+}
+
+- (void)centralManager:(CBCentralManager *)central
+ didDiscoverPeripheral:(CBPeripheral *)peripheral
+     advertisementData:(NSDictionary<NSString*, id> *) advertisementData
+                  RSSI:(NSNumber *) RSSI{
+    if (g_isStartedLEClient){
+        OIC_LOG_V(INFO, TAG, "[CBCtrl] didDiscoverPeripheral : peripheral name = %s", [[peripheral name] UTF8String]);
+
+        if([cbPeripherals objectForKey:peripheral] == nil && [self isValidUUID:advertisementData])
+        {
+
+            if ([cbPeripherals count] > 0){
+                OIC_LOG(DEBUG, TAG, "new peripheral");
+                [cbPeripherals setObject:[cbCentralIf CALEClientGetMAC:
+                                          [advertisementData objectForKey:
+                                           CBAdvertisementDataManufacturerDataKey]]
+                                  forKey:peripheral];
+                CALEClientAddScanDeviceToList(peripheral);
+            }else{
+                if (nil != cbCentralIf){
+                    OIC_LOG(DEBUG, TAG, "1st discovered peripheral");
+                    [cbPeripherals setObject:[cbCentralIf CALEClientGetMAC:
+                                              [advertisementData objectForKey:
+                                               CBAdvertisementDataManufacturerDataKey]]
+                                      forKey: peripheral];
+                    CALEClientAddScanDeviceToList(peripheral);
+                }
+            }
+        }
+    }else{
+        OIC_LOG(DEBUG, TAG, "[CBCtrl] g_isStertedLEClient == false");
+    }
+}
+
+- (void)centralManager:(CBCentralManager*)central
+  didConnectPeripheral:(CBPeripheral *)peripheral {
+    peripheral.delegate = self;
+
+    const char *address = [[cbCentralIf CALEGetAddressFromBTDevice: peripheral] UTF8String];
+    OIC_LOG_V(DEBUG, TAG, "[CBCtrl] didConnectPeripheral : connected peripheral = %s", address);
+
+    CALEState_t* curState = CALEClientGetStateInfo(address);
+    if (curState == NULL || curState->connectedState != STATE_CONNECTED) {
+        CALEClientUpdateDeviceState(address, STATE_CONNECTED,
+                                    STATE_CHARACTER_UNSET,STATE_SEND_NONE);
+
+        [cbCentralIf CALEClientDiscoverServices: peripheral];
+    }
+
+    if(g_caManagerQueue)
+    {
+        dispatch_async(g_caManagerQueue, ^{
+
+            if(g_caManagerConnectionCallback)
+            {
+                g_caManagerConnectionCallback(peripheral, address, true, nil);
+            }
+        });
+    }
+
+}
+
+- (void)centralManager: (CBCentralManager *)central
+didFailToConnectPeripheral: (CBPeripheral *)peripheral
+                 error:(NSError *)error{
+
+    OIC_LOG(ERROR, TAG, "[CBCtrl] didFailToConnectPeripheral & start scan");
+    if(error) {
+        OIC_LOG_V(ERROR, TAG, "didFailToConnectPeripheral, error desc = %s",
+                  [[error localizedDescription] UTF8String]);
+    }
+
+    CAResult_t res = CALEClientStartScan();
+    if (CA_STATUS_OK != res){
+        OIC_LOG(ERROR, TAG, "start scan error");
+        CALEClientSendFinish(peripheral);
+        return;
+    }
+
+    char *address = (char*)[[cbCentralIf CALEGetAddressFromBTDevice: peripheral] UTF8String];
+    if (!address){
+        CALEClientSendFinish(peripheral);
+        return;
+    }else{
+        res = CALEClientRemoveDeviceState(address);
+        if (CA_STATUS_OK != res){
+            OIC_LOG(ERROR, TAG, "removedevicestate error");
+            CALEClientSendFinish(peripheral);
+            return;
+        }
+    }
+}
+
+- (void)centralManager:(CBCentralManager *)central
+didDisconnectPeripheral:(CBPeripheral *)peripheral
+                 error:(NSError *)error{
+
+    if(error) {
+        OIC_LOG_V(ERROR, TAG, "didDisconnectPeripheral, error desc = %s",
+                  [[error localizedDescription] UTF8String]);
+    }
+
+    NSString *nsAddr = [cbPeripherals objectForKey:peripheral];
+    const char *address = [nsAddr UTF8String];
+
+    if(address){
+        CALEClientUpdateDeviceState(address, STATE_DISCONNECTED,
+                                    STATE_CHARACTER_UNSET,STATE_SEND_NONE);
+        OIC_LOG_V(DEBUG, TAG, "[CBCtrl] didDisconnectPeripheral : Peripheral address = %s", address);
+
+        if(g_caManagerQueue)
+        {
+            dispatch_async(g_caManagerQueue, ^{
+
+                if(g_caManagerConnectionCallback)
+                {
+                    g_caManagerConnectionCallback(peripheral, address, false, error);
+                }
+            });
+        }
+
+        CALEClientUpdateSendCnt();
+
+        if ( false == CALEClientGetAutoConnectFlag(address) )
+        {
+            CALEClientRemoveDeviceInScanDeviceList(nsAddr);
+        }
+    }
+}
+
+- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
+    if (error){
+        OIC_LOG_V(ERROR, TAG, "didDiscoverServices, error desc = %s",
+                  [[error localizedDescription] UTF8String]);
+        CALEClientSendFinish(peripheral);
+        return;
+    }
+    const char *address = [CALEClientGetAddressFromGattObj(peripheral) UTF8String];
+
+    OIC_LOG_V(INFO, TAG, "found service for - %s %s", address, [[peripheral name] UTF8String]);
+
+    if (!address){
+        CALEClientSendFinish(peripheral);
+        return;
+    }
+
+    if (!CALEClientIsSetCharacteristic(address)){
+        char *serviceUUID = NULL;
+
+        OIC_LOG_V(ERROR, TAG, "didDiscoverServices, #services = %lu",[peripheral.services count]);
+
+        if ([peripheral.services count] == 0) {
+            OIC_LOG(ERROR, TAG, "didDiscoverServices, no service found from peripheral");
+            CALEClientSendFinish(peripheral);
+            return;
+        }
+        else {
+            for (CBService *service in peripheral.services){
+                [cbServices setObject:service forKey:peripheral];
+
+                OIC_LOG(INFO, TAG, "discover characteristics");
+
+                [peripheral discoverCharacteristics:
+                 @[[CBUUID UUIDWithString:
+                    [NSString stringWithUTF8String:OIC_GATT_CHARACTERISTIC_REQUEST_UUID]],
+                   [CBUUID UUIDWithString:
+                    [NSString stringWithUTF8String:OIC_GATT_CHARACTERISTIC_RESPONSE_UUID]]]
+                 forService:service];
+            }
+        }
+    }else{
+        OIC_LOG(DEBUG, TAG, "already set characteristics");
+
+        if ( g_sendBuffer != nil ) {
+            CAResult_t res = CALEClientWriteCharacteristic(peripheral);
+            if (CA_STATUS_OK != res){
+                OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic failed");
+                CALEClientSendFinish(peripheral);
+                return;
+            }
+        }
+
+        if(g_caManagerQueue){
+            OIC_LOG(DEBUG, TAG, "Call caManagerServiceDiscoveredCallback");
+            dispatch_async(g_caManagerQueue, ^{
+
+                if(g_caManagerServiceDiscoveredCallback)
+                {
+                    g_caManagerServiceDiscoveredCallback(peripheral, address, error);
+                }
+            });
+        }
+    }
+}
+
+- (void)peripheral: (CBPeripheral *)peripheral
+didDiscoverCharacteristicsForService: (CBService *)service
+             error:(NSError *)error{
+
+    if(error){
+        OIC_LOG_V(ERROR, TAG, "[CBCtrl] didDiscoverCharacteristicsForService: error = %s",
+                  [[error localizedDescription] UTF8String]);
+        return;
+    }
+    OIC_LOG(DEBUG, TAG, "[CBCtrl] didDiscoverCharacteristicsForService");
+    const char *address = [[cbCentralIf CALEGetAddressFromBTDevice: peripheral] UTF8String];
+
+    for (CBCharacteristic *characteristic in service.characteristics){
+        if (!CALEClientIsSetCharacteristic(address)){
+            if ([characteristic.UUID isEqual:
+                 [CBUUID UUIDWithString:
+                  [NSString stringWithUTF8String:OIC_GATT_CHARACTERISTIC_RESPONSE_UUID]]]){
+                OIC_LOG_V(DEBUG, TAG, "[CBCtrl] find RESPONSE characteristic @%s", address);
+                [responseCharacs setObject:characteristic forKey:peripheral];
+
+                CAResult_t res = CALEClientSetCharacteristicNotification(peripheral,
+                                                                         characteristic);
+                if (CA_STATUS_OK != res){
+                    OIC_LOG(ERROR, TAG, "CALEClientSetCharacteristicNotification has failed");
+                    CALEClientSendFinish(peripheral);
+                    return;
+                }
+            }
+
+            if ([characteristic.UUID isEqual:
+                 [CBUUID UUIDWithString:
+                  [NSString stringWithUTF8String:OIC_GATT_CHARACTERISTIC_REQUEST_UUID]]]){
+                     OIC_LOG_V(DEBUG, TAG, "[CBCtrl] find REQUEST characteristic @%s", address);
+                     [requestCharacs setObject:characteristic forKey:peripheral];
+
+                     CAResult_t res = CALEClientUpdateDeviceState(address, STATE_CONNECTED,
+                                                              STATE_CHARACTER_SET, STATE_SEND_NONE);
+
+                     if (CA_STATUS_OK != res){
+                         OIC_LOG(ERROR, TAG, "CALEClientUpdataeDeviceState has failed");
+                         CALEClientSendFinish(peripheral);
+                         return;
+                     }
+
+                     res = CALEClientAddGattobjToList(peripheral);
+                     if (CA_STATUS_OK != res){
+                         OIC_LOG(ERROR, TAG, "CALEClientAddGattobjToList has failed");
+                         CALEClientSendFinish(peripheral);
+                         return;
+                     }
+
+                     if ( g_sendBuffer != nil ) {
+                         res = CALEClientWriteCharacteristic(peripheral);
+                         if (CA_STATUS_OK != res){
+                             OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
+                             CALEClientSendFinish(peripheral);
+                             return;
+                         }
+                     }
+                 }
+        }else{
+            CAResult_t res = CALEClientWriteCharacteristic(peripheral);
+            if (CA_STATUS_OK != res){
+                OIC_LOG(ERROR, TAG, "CALEClientWriteCharacteristic has failed");
+                CALEClientSendFinish(peripheral);
+                return;
+            }
+        }
+    }
+
+
+    if(g_caManagerQueue)
+    {
+        OIC_LOG(DEBUG, TAG, "Call caManagerServiceDiscoveredCallback");
+        dispatch_async(g_caManagerQueue, ^{
+
+            if(g_caManagerServiceDiscoveredCallback)
+            {
+                g_caManagerServiceDiscoveredCallback(peripheral, address, error);
+            }
+        });
+    }
+
+}
+
+- (void)peripheral: (CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic
+                  :(CBCharacteristic *)characteristic error:(NSError *)error{
+    if(error){
+        OIC_LOG_V(ERROR, TAG, "didUpdateNotificationStateForCharacteristic error = %s",
+                  [[error localizedDescription] UTF8String]);
+    } else {
+        OIC_LOG(INFO, TAG, "didUpdateNotificationStateForCharacteristic");
+    }
+}
+
+- (void)peripheral: (CBPeripheral *)peripheral
+didUpdateValueForCharacteristic: (CBCharacteristic *)characteristic
+             error:(NSError *)error{
+    if(error){
+        OIC_LOG_V(ERROR, TAG, "[CBCtrl] didUpdateValueForCharacteristic: ERROR = %s",
+                  [[error localizedDescription] UTF8String]);
+        return;
+    }
+
+    const char *address = [[cbPeripherals objectForKey: peripheral] UTF8String];
+    OIC_LOG_V(INFO, TAG, "[CBctrl] Update Value address: %s", address);
+
+    NSMutableData *nsData = [[NSMutableData alloc] init];
+    [nsData appendData:characteristic.value];
+    uint32_t len = [nsData length];
+    uint8_t *data = (uint8_t*) OICMalloc(len);
+    uint32_t sentLength = 0;
+    memcpy(data, (const uint8_t*)[nsData bytes], len);
+    [nsData release];
+    OIC_LOG_BUFFER(DEBUG, TAG, data, len);
+    oc_mutex_lock(g_bleServerBDAddressMutex);
+    g_CABLEClientDataReceivedCallback(address, data, len, &sentLength);
+    oc_mutex_unlock(g_bleServerBDAddressMutex);
+}
+
+-(bool) isValidUUID:(NSDictionary<NSString*, id> *) dict
+{
+    NSData* dat = [dict objectForKey:CBAdvertisementDataManufacturerDataKey];
+    if([dat length] >= TV_ADV_DATA_MIN_LEN)
+    {
+        const unsigned char *bytes = (unsigned char *)dat.bytes;
+
+        int b1 = (int)bytes[TV_ADV_COMPANY_ID_INDEX1];
+        int b2 = (int)bytes[TV_ADV_COMPANY_ID_INDEX2];
+        int b3 = (int)bytes[TV_ADV_VERSION_INDEX];
+        int b4 = (int)bytes[TV_ADV_SERVICE_TYPE_INDEX];
+
+        if((b1 == TV_ADV_COMPANY_ID1) && (b2 == TV_ADV_COMPANY_ID2) && (b3 == TV_ADV_VERSION) &&
+           (b4 == TV_ADV_SERVICE_ID_POWER || b4 == TV_ADV_SERVICE_ID_OOB))
+        {
+
+            int b6 = (int)bytes[TV_ADV_DEVICE_STATUS_INDEX];
+            if((b4 == TV_ADV_SERVICE_ID_POWER) && (b6 == TV_ADV_DEVICE_STATUS_UNKNOWN))
+            {
+                OIC_LOG(INFO, TAG, "discarded mode 4"); /*mac not available, dev status unknown
+                                              discard now to receive next adv_ind with status*/
+                return false;
+            }
+
+            int b5 = (int)bytes[TV_ADV_SCAN_RESP_LEN_INDEX];
+            int b20 = (int)bytes[TV_ADV_BD_ADDRTYPE_INDEX]; //address type
+            if(b4 == TV_ADV_SERVICE_ID_OOB &&
+               (b5 == TV_ADV_SCAN_RESP_LEN || b20 == TV_ADV_DEVICE_STATUS_UNKNOWN))
+            {
+                OIC_LOG_V(INFO, TAG, "discarded mode 9, b5 = %d", b5); /*mac not avilable
+                                 this is scan resp, discard now to receive next adv_ind*/
+                return false;
+            }
+
+            OIC_LOG_V(INFO, TAG, "Custom advertisement with mac, service type = %d", b4);
+            return true;
+        }
+    }
+
+    NSArray* arr = [dict objectForKey:CBAdvertisementDataServiceUUIDsKey];
+    if([arr count] > 0)
+    {
+        for(CBUUID *serv in arr) {
+            if([serv isEqual:[CBUUID UUIDWithString:
+                              [NSString stringWithUTF8String:OIC_GATT_SERVICE_UUID]]]){
+
+                OIC_LOG(INFO, TAG, "IoTivity Service Advertisement");
+                return true;
+            }
+        }
+    }
+
+    return false;
+}
+
+@end
+
+
+int ishexdigit(char var)
+{
+    if(var <= '9')
+    {
+        if(var >= '0') {
+          return 1;
+        } else {
+          return 0;
+        }
+    }
+    else if(var <= 'F')
+    {
+        if(var >= 'A') {
+          return 1;
+        } else {
+          return 0;
+        }
+    }
+    else if(var <= 'f')
+    {
+        if(var >= 'a') {
+          return 1;
+        } else {
+          return 0;
+        }
+    }
+
+    return 0;
+}
+
+int isMAC(const char *address)
+{
+    /*
+     * Check if the provided MAC address is valid.
+     * 1. The length of MAC address should always be 17.
+     * 2. Hyphens are expected at positions {3, 6, 9, 12, 15}.
+     * 3. The rest characters should be simple xdigits.
+     */
+    int hyphens[5] = {3, 6, 9, 12, 15};
+    if (strlen(address) != 17)
+    {
+        return 0;//Oops. The lenth doesn't match.
+    }
+
+    for (int i = 0, counter = 0; i < 17; i ++)
+    {
+        char var = address[i];
+        if (i == hyphens[counter] - 1)// Check if a hyphen is expected here.
+        {
+            // Yep. We need a hyphen here.
+            if (var != ':')
+            {
+                return 0;// Oops. The character is not a hyphen.
+            }
+            else
+            {
+                counter++;// Move on to the next expected hyphen position.
+            }
+        }
+        else
+        {
+            // Nope. The character here should be a simple xdigit
+            if (ishexdigit(var) == 0)
+            {
+                return 0;// Oops. The current character is not a hyphen.
+            }
+        }
+    }
+    return 1;// Seen'em all!
+}
+
+CAResult_t CALEClientInitialize()
+{
+    OIC_LOG(DEBUG, TAG, "IN - CALEClientInitialize");
+
+    CAResult_t ret = CALEClientInitGattMutexVaraibles();
+    if (CA_STATUS_OK != ret){
+        OIC_LOG(ERROR, TAG, "CALEClientInitGattMutexVaraibles has failed!");
+        CALEClientTerminateGattMutexVariables();
+
+        return ret;
+    }
+
+    // init cond for initialize logic
+    if (g_initializeCond == NULL) {
+        g_initializeCond = oc_cond_new();
+    }
+
+    cbCentralIf = [[CBCentralIfClass alloc] init];
+    [cbCentralIf CALEClientCreateCentralManager];
+
+    g_deviceDescCond = oc_cond_new();
+
+    // init mutex for send logic
+    g_threadCond = oc_cond_new();
+    g_threadWriteCharacteristicCond = oc_cond_new();
+    g_deviceScanRetryDelayCond = oc_cond_new();
+
+    CALEClientCreateDeviceList();
+
+    g_isStartedLEClient = true;
+
+    oc_cond_signal(g_initializeCond);
+
+    return CA_STATUS_OK;
+}
+
+void CALEClientTerminate()
+{
+    OIC_LOG(DEBUG, TAG, "IN - CALEClientTerminate");
+
+    if (g_sendBuffer != nil){
+        g_sendBuffer = nil;
+    }
+
+    CAResult_t ret = CALEClientRemoveAllDeviceState();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientRemoveAllDeviceState has failed");
+    }
+
+    ret = CALEClientRemoveAllScanDevices();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientRemoveAllScanDevices has failed");
+    }
+
+    ret = CALEClientRemoveAllGattObjs();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
+    }
+
+    CALEClientSetScanFlag(false);
+    CALEClientSetSendFinishFlag(true);
+
+    CALEClientTerminateGattMutexVariables();
+
+    oc_cond_free(g_deviceDescCond);
+    oc_cond_free(g_threadCond);
+    oc_cond_free(g_threadWriteCharacteristicCond);
+    oc_cond_free(g_deviceScanRetryDelayCond);
+    oc_cond_free(g_initializeCond);
+
+    g_deviceDescCond = NULL;
+    g_threadCond = NULL;
+    g_threadWriteCharacteristicCond = NULL;
+    g_deviceScanRetryDelayCond = NULL;
+    g_initializeCond = NULL;
+
+    g_isSignalSetFlag = false;
+
+    centralMgr.delegate = nil;
+    if ([centralMgrs count] != 0) {
+        for (CBCentralManager *mgr in centralMgrs){
+            [centralMgrs removeObject:mgr];
+        }
+    }
+
+    [cbCentralIf release];
+    cbCentralIf = nil;
+
+    OIC_LOG(DEBUG, TAG, "OUT - CALEClientTerminate");
+}
+
+void CALEClientSendFinish(CBPeripheral *peripheral)
+{
+    OIC_LOG(DEBUG, TAG, "CALEClientSendFinish");
+
+    if (peripheral)
+    {
+        CAResult_t res = CALEClientDisconnect(peripheral);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
+        }
+    }
+    CALEClientUpdateSendCnt();
+}
+
+CAResult_t CALEClientSendUnicastMessage(const char* address,
+                                        const uint8_t* data,
+                                        const uint32_t dataLen)
+{
+    OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessage(%s, %p)", address, data);
+    VERIFY_NON_NULL(address, TAG, "address is null");
+    VERIFY_NON_NULL(data, TAG, "data is null");
+
+    return CALEClientSendUnicastMessageImpl(address, data, dataLen);
+}
+
+CAResult_t CALEClientSendMulticastMessage(const uint8_t* data,
+                                          const uint32_t dataLen)
+{
+    OIC_LOG_V(DEBUG, TAG, "CALEClientSendMulticastMessage(%p)", data);
+    VERIFY_NON_NULL(data, TAG, "data is null");
+
+    CAResult_t ret = CALEClientSendMulticastMessageImpl(data, dataLen);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientSendMulticastMessageImpl has failed");
+    }
+
+    return ret;
+}
+
+CAResult_t CALEClientStartUnicastServer(const char* address)
+{
+    OIC_LOG_V(DEBUG, TAG, "it is not needed in this platform (%s)", address);
+
+    return CA_NOT_SUPPORTED;
+}
+
+CAResult_t CALEClientStartMulticastServer()
+{
+    OIC_LOG(DEBUG, TAG, "it is not needed in this platform");
+
+    return CA_NOT_SUPPORTED;
+}
+
+void CALEClientStopUnicastServer()
+{
+    OIC_LOG(DEBUG, TAG, "CALEClientStopUnicastServer");
+}
+
+void CALEClientStopMulticastServer()
+{
+    OIC_LOG(DEBUG, TAG, "CALEClientStopMulticastServer");
+}
+
+void CALEClientSetCallback(CAPacketReceiveCallback callback)
+{
+    g_packetReceiveCallback = callback;
+}
+
+void CALEClientSetCAManagerCallback(CAManagerAdapterStateChangeCallback adapterStateChangeCB,
+                                    CAManagerConnectionCallback connectionCB,
+                                    CAManagerServiceDiscoveredCallback serviceDiscoverdCB)
+{
+    VERIFY_NON_NULL_VOID(adapterStateChangeCB, TAG, "adapterStateChangeCB is null");
+    VERIFY_NON_NULL_VOID(connectionCB, TAG, "connectionCB is null");
+    VERIFY_NON_NULL_VOID(serviceDiscoverdCB, TAG, "serviceDiscoverdCB is null");
+
+    if (!g_caManagerQueue) {
+        g_caManagerQueue = dispatch_queue_create("com.caManager", DISPATCH_QUEUE_SERIAL);
+    }
+
+    g_caManagerAdapterStateChangeCallback = adapterStateChangeCB;
+    g_caManagerConnectionCallback = connectionCB;
+    g_caManagerServiceDiscoveredCallback = serviceDiscoverdCB;
+}
+
+
+void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
+{
+    g_clientErrorCallback = callback;
+}
+
+CAResult_t CALEClientIsThereScannedDevices(const char* address)
+{
+    if (!g_deviceList)
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientIsThereScannedDevices g_deviceList is null");
+        return CA_STATUS_FAILED;
+    }
+
+    if (0 == u_arraylist_length(g_deviceList) // multicast
+        || (address && !CALEClientIsDeviceInScanDeviceList(address))) // unicast
+    {
+        // Wait for LE peripherals to be discovered.
+
+        // Number of times to wait for discovery to complete.
+        static size_t const RETRIES = 7;
+
+        static uint64_t const TIMEOUT =
+        3 * MICROSECS_PER_SEC;  // Microseconds
+
+        bool devicesDiscovered = false;
+        for (size_t i = 0; i < RETRIES; ++i)
+        {
+            OIC_LOG(DEBUG, TAG, "waiting for target device");
+            if (oc_cond_wait_for(g_deviceDescCond,
+                                 g_threadSendMutex,
+                                 TIMEOUT) == OC_WAIT_SUCCESS)
+            {
+                oc_mutex_lock(g_deviceListMutex);
+                size_t scannedDeviceLen = u_arraylist_length(g_deviceList);
+                oc_mutex_unlock(g_deviceListMutex);
+
+                if (0 < scannedDeviceLen)
+                {
+                    if (!address  // multicast
+                        || (address && CALEClientIsDeviceInScanDeviceList(address))) // unicast
+                    {
+                        devicesDiscovered = true;
+                        break;
+                    }
+                    else
+                    {
+                        if (address)
+                        {
+                            OIC_LOG(INFO, TAG, "waiting..");
+
+                            oc_mutex_lock(g_deviceScanRetryDelayMutex);
+                            if (oc_cond_wait_for(g_deviceScanRetryDelayCond,
+                                                 g_deviceScanRetryDelayMutex,
+                                                 MICROSECS_PER_SEC) == OC_WAIT_SUCCESS)
+                            {
+                                OIC_LOG(INFO, TAG, "finish to waiting for target device");
+                                oc_mutex_unlock(g_deviceScanRetryDelayMutex);
+                                break;
+                            }
+                            oc_mutex_unlock(g_deviceScanRetryDelayMutex);
+                            // time out
+
+                            // checking whether a target device is found while waiting for time-out.
+                            if (CALEClientIsDeviceInScanDeviceList(address))
+                            {
+                                devicesDiscovered = true;
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        // time out for scanning devices
+        if (!devicesDiscovered)
+        {
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    return CA_STATUS_OK;
+}
+
+
+CAResult_t CALEClientSendUnicastMessageImpl(const char* address,
+                                            const uint8_t* data,
+                                            const uint32_t dataLen)
+{
+    OIC_LOG_V(DEBUG, TAG, "CALEClientSendUnicastMessageImpl: \n address: %s, data: %p",
+              address, data);
+    VERIFY_NON_NULL(address, TAG, "address is null");
+    VERIFY_NON_NULL(data, TAG, "data is null");
+
+    oc_mutex_lock(g_threadSendMutex);
+
+    CALEClientSetSendFinishFlag(false);
+
+    CAResult_t ret = CALEClientIsThereScannedDevices(address);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(INFO, TAG, "there is no scanned device");
+        goto error_exit;
+    }
+
+    const char *founded_address = NULL;
+    uint32_t length = u_arraylist_length(g_deviceList);
+    OIC_LOG_V(DEBUG, TAG, "g_deviceList : %d", length);
+    int is_mac = isMAC(address);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        CBPeripheral *peripheral = (CBPeripheral *)u_arraylist_get(g_deviceList, index);
+        if (!peripheral)
+        {
+            OIC_LOG(ERROR, TAG, "devicelist is empty");
+            goto error_exit;
+        }
+
+        const char *setAddress = NULL;
+        if(is_mac == 0)
+        {
+            setAddress = [[[peripheral identifier] UUIDString] UTF8String];
+        }
+        else  //address
+        {
+            setAddress = [[cbCentralIf CALEGetAddressFromBTDevice: peripheral] UTF8String];
+        }
+
+        if (!setAddress)
+        {
+            OIC_LOG(ERROR, TAG, "setAddress is null");
+            if(is_mac == 0) { continue; }
+            else { goto error_exit; }
+        }
+
+        OIC_LOG_V(DEBUG, TAG, "remote device address is %s, scanned peripheral = %s", setAddress,
+                  [[peripheral name] UTF8String]);
+
+        if (!strcmp(setAddress, address))
+        {
+            founded_address = [[cbCentralIf CALEGetAddressFromBTDevice: peripheral] UTF8String];
+
+            // connect to gatt server
+            OIC_LOG(DEBUG, TAG, "CALEClientSendUnicastMessageImpl --> stop scan");
+            ret = CALEClientStopScan();
+            if (CA_STATUS_OK != ret)
+            {
+                OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
+                goto error_exit;
+            }
+
+            if (g_sendBuffer != nil ){
+                g_sendBuffer = nil;
+            }
+            g_sendBuffer = [NSData dataWithBytes:(const uint8_t*)data length:dataLen];
+
+            OIC_LOG_V(DEBUG,TAG, "unicast send data size: %lu", [g_sendBuffer length]);
+            OIC_LOG_BUFFER(DEBUG,TAG,data,dataLen);
+
+            ret = CALEClientSendData(peripheral);
+            if (CA_STATUS_OK != ret)
+            {
+                OIC_LOG(ERROR, TAG, "CALEClientSendData in unicast is failed");
+                goto error_exit;
+            }
+
+            OIC_LOG(INFO, TAG, "wake up");
+            break;
+        }
+    }
+
+    OIC_LOG(DEBUG, TAG, "connection routine is finished for unicast");
+
+    // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
+    // if there is no connection state.
+    oc_mutex_lock(g_threadMutex);
+    if (!g_isFinishedSendData)
+    {
+        OIC_LOG(DEBUG, TAG, "waiting send finish signal");
+        oc_cond_wait(g_threadCond, g_threadMutex);
+        OIC_LOG(DEBUG, TAG, "the data was sent");
+    }
+    oc_mutex_unlock(g_threadMutex);
+
+    // start LE Scan again
+    ret = CALEClientStartScan();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
+        oc_mutex_unlock(g_threadSendMutex);
+        return ret;
+    }
+
+    oc_mutex_unlock(g_threadSendMutex);
+    OIC_LOG(INFO, TAG, "unicast - send logic has finished");
+    return CALECheckSendState(founded_address);
+
+    // error label.
+error_exit:
+
+    // start LE Scan again
+    if (!CALEClientStartScan())
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
+        oc_mutex_unlock(g_threadSendMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    if (g_clientErrorCallback)
+    {
+        g_clientErrorCallback(address, data, dataLen, CA_SEND_FAILED);
+    }
+    oc_mutex_unlock(g_threadSendMutex);
+    return CA_SEND_FAILED;
+}
+
+CAResult_t CALEClientSendMulticastMessageImpl(const uint8_t* data,
+                                              const uint32_t dataLen)
+{
+    OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %p, %u", data, dataLen);
+    VERIFY_NON_NULL(data, TAG, "data is null");
+
+    if (!g_deviceList)
+    {
+        OIC_LOG(ERROR, TAG, "g_deviceList is null");
+        return CA_STATUS_FAILED;
+    }
+
+    uint32_t length = 0;
+    oc_cond waitCond = NULL;
+
+    oc_mutex_lock(g_threadSendMutex);
+
+    CALEClientSetSendFinishFlag(false);
+
+    OIC_LOG(DEBUG, TAG, "set byteArray for data");
+
+    CAResult_t res = CALEClientIsThereScannedDevices(NULL);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(INFO, TAG, "there is no scanned device");
+        goto error_exit;
+    }
+
+    // connect to gatt server
+    OIC_LOG(DEBUG, TAG, "CALEClientSendMulticastMessageImpl --> stop scan");
+    res = CALEClientStopScan();
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
+        oc_mutex_unlock(g_threadSendMutex);
+        return res;
+    }
+    length = u_arraylist_length(g_deviceList);
+    g_targetCnt = length;
+
+    if ( g_sendBuffer != nil ){
+        g_sendBuffer = nil;
+    }
+
+    g_sendBuffer = [NSData dataWithBytes:(const uint8_t*)data length:dataLen];
+
+    OIC_LOG_V(DEBUG,TAG, "unicast send data size: %lu", [g_sendBuffer length]);
+    OIC_LOG_BUFFER(DEBUG,TAG,data,dataLen);
+
+    for (uint32_t index = 0; index < length; index++)
+    {
+        OIC_LOG_V(DEBUG, TAG, "target cnt: %d/%d", index+1,length);
+        CBPeripheral *peripheral = (CBPeripheral *)u_arraylist_get(g_deviceList, index);
+        if (!peripheral)
+        {
+            OIC_LOG(ERROR, TAG, "peripheral is not available");
+            continue;
+        }
+        else{
+            CALEClientSendData(peripheral);
+        }
+    }
+    OIC_LOG(DEBUG, TAG, "connection routine is finished for multicast");
+
+    // wait for finish to send data through "CALeGattServicesDiscoveredCallback"
+    oc_mutex_lock(g_threadMutex);
+    if (!g_isFinishedSendData)
+    {
+        OIC_LOG(DEBUG, TAG, "waiting send finish signal");
+        oc_cond_wait(g_threadCond, g_threadMutex);
+        OIC_LOG(DEBUG, TAG, "the data was sent");
+    }
+    oc_mutex_unlock(g_threadMutex);
+
+    // start LE Scan again
+    res = CALEClientStartScan();
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
+        oc_mutex_unlock(g_threadSendMutex);
+        return res;
+    }
+
+    oc_mutex_unlock(g_threadSendMutex);
+    OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
+    return CA_STATUS_OK;
+
+error_exit:
+    res = CALEClientStartScan();
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientStartScan has failed");
+        oc_mutex_unlock(g_threadSendMutex);
+        return res;
+    }
+
+    oc_mutex_unlock(g_threadSendMutex);
+    OIC_LOG(DEBUG, TAG, "OUT - CALEClientSendMulticastMessageImpl");
+    return CA_SEND_FAILED;
+}
+
+CAResult_t CALECheckSendState(const char* address)
+{
+    VERIFY_NON_NULL(address, TAG, "address is null");
+
+    oc_mutex_lock(g_deviceStateListMutex);
+    CALEState_t* state = CALEClientGetStateInfo(address);
+    if (NULL == state)
+    {
+        OIC_LOG(ERROR, TAG, "state is null");
+        oc_mutex_unlock(g_deviceStateListMutex);
+        return CA_SEND_FAILED;
+    }
+
+    if (STATE_SEND_SUCCESS != state->sendState)
+    {
+        OIC_LOG(ERROR, TAG, "sendstate is not STATE_SEND_SUCCESS");
+        oc_mutex_unlock(g_deviceStateListMutex);
+        return CA_SEND_FAILED;
+    }
+
+    OIC_LOG(INFO, TAG, "sendstate is STATE_SEND_SUCCESS");
+    oc_mutex_unlock(g_deviceStateListMutex);
+    return CA_STATUS_OK;
+}
+
+CAResult_t CALEClientSendData(CBPeripheral *peripheral)//, CBService *service)
+{
+    OIC_LOG(DEBUG, TAG, "IN - CALEClientSendData");
+
+    // get BLE address from bluetooth device object.
+    CALEState_t* state = NULL;
+    char *address = (char*)[[cbCentralIf CALEGetAddressFromBTDevice: peripheral] UTF8String];
+    if (!address)
+    {
+        OIC_LOG(ERROR, TAG, "address is not available");
+        return CA_STATUS_FAILED;
+    }
+    oc_mutex_lock(g_deviceStateListMutex);
+    state = CALEClientGetStateInfo(address);
+    oc_mutex_unlock(g_deviceStateListMutex);
+
+    if (!state)
+    {
+        OIC_LOG(DEBUG, TAG, "state is empty..start to connect LE");
+
+        // cancel previous connection request before connection
+        // if there is gatt object in g_gattObjectList.
+
+        // connection request
+        CAResult_t ret = CALEClientConnect(peripheral, false);
+        if (CA_STATUS_OK != ret){
+            OIC_LOG(ERROR, TAG, "CALEClientConnect failed");
+            return ret;
+        }
+    }
+    else
+    {
+        if (STATE_CONNECTED == state->connectedState)
+        {
+            OIC_LOG(INFO, TAG, "GATT has already connected");
+
+            CBPeripheral *tPeripheral = CALEClientGetGattObjInList(address);
+            if (!tPeripheral)
+            {
+                OIC_LOG(ERROR, TAG, "CALEClientGetGattObjInList has failed");
+                //return CA_STATUS_FAILED;
+                goto exit;
+            }
+
+            CAResult_t ret = CALEClientWriteCharacteristic(peripheral);
+            //CAResult_t ret = CALESetValueAndWriteCharacteristic(peripheral, service);
+            if (CA_STATUS_OK != ret)
+            {
+                OIC_LOG(ERROR, TAG, "WriteCharacteristic has failed");
+                return ret;
+            }
+        }
+        else
+        {
+            OIC_LOG(INFO, TAG, "STATE_DISCONNECTED - start to connect LE");
+
+            // cancel previous connection request before connection
+            // if there is gatt object in g_gattObjectList.
+
+            OIC_LOG(DEBUG, TAG, "start to connect LE");
+            CAResult_t ret = CALEClientConnect(peripheral, CALEClientGetAutoConnectFlag(address));
+            if (CA_STATUS_OK != ret){
+                OIC_LOG(ERROR, TAG, "CALEClientConnect failed");
+                return ret;
+            }
+        }
+    }
+
+    return CA_STATUS_OK;
+exit:
+    return CA_STATUS_OK;
+}
+
+NSString *CALEClientGetAddressFromGattObj(CBPeripheral *peripheral)
+{
+    VERIFY_NON_NULL_RET(peripheral, TAG, "peripheral is null", NULL);
+
+    return [cbPeripherals objectForKey: peripheral];
+}
+
+/**
+ * BLE layer
+ */
+CAResult_t CALEClientGattClose(CBPeripheral *peripheral)
+{
+    // GATT CLOSE
+    OIC_LOG(DEBUG, TAG, "Gatt Close");
+    [cbCentralIf CALEClientCancelPeripheralConnection:peripheral];
+    return CA_STATUS_OK;
+}
+
+CAResult_t CALEClientStartScan()
+{
+    if (!CALEClientIsEnableBTAdapter())
+    {
+        OIC_LOG(INFO, TAG, "BT adapter is not enabled");
+        return CA_ADAPTER_NOT_ENABLED;
+    }
+
+    if (!g_isStartedLEClient)
+    {
+        OIC_LOG(ERROR, TAG, "LE client is not started");
+        return CA_STATUS_FAILED;
+    }
+
+    if (g_isStartedScan)
+    {
+        OIC_LOG(INFO, TAG, "scanning is already started");
+        return CA_STATUS_OK;
+    }
+
+    OIC_LOG(DEBUG, TAG, "CALEClientStartScan");
+
+    CAResult_t ret = CA_STATUS_OK;
+
+#ifdef UUID_SCAN
+    ret = CA_ADAPTER_NOT_ENABLE;
+#else
+    ret = [cbCentralIf CALEClientStartScanImpl];
+#endif
+    if (CA_STATUS_OK != ret)
+    {
+        if (CA_ADAPTER_NOT_ENABLED == ret)
+        {
+            OIC_LOG(DEBUG, TAG, "Adapter is disabled");
+        }
+        else
+        {
+            OIC_LOG(ERROR, TAG, "start scan has failed");
+        }
+    }
+
+    return ret;
+}
+
+CAResult_t CALEClientStopScan()
+{
+    if (!g_isStartedScan)
+    {
+        OIC_LOG(INFO, TAG, "scanning is already stopped");
+        return CA_STATUS_OK;
+    }
+
+    CAResult_t ret = [cbCentralIf CALEClientStopScanImpl];
+    if (CA_STATUS_OK != ret)
+    {
+        if (CA_ADAPTER_NOT_ENABLED == ret)
+        {
+            OIC_LOG(DEBUG, TAG, "Adapter is disabled");
+        }
+        else
+        {
+            OIC_LOG(ERROR, TAG, "CALEClientStopScanImpl has failed");
+        }
+    }
+    else
+    {
+        CALEClientSetScanFlag(false);
+    }
+
+    return ret;
+}
+
+void CALEClientSetScanFlag(bool flag)
+{
+    oc_mutex_lock(g_scanMutex);
+    g_isStartedScan = flag;
+    oc_mutex_unlock(g_scanMutex);
+}
+
+CAResult_t CALEClientSetAutoConnectFlag(const char *address, bool flag)
+{
+    OIC_LOG(DEBUG, TAG, "IN - CALEClientSetAutoConnectFlag");
+
+    oc_mutex_lock(g_deviceStateListMutex);
+
+    if (!address)
+    {
+        OIC_LOG(ERROR, TAG, "address is not available");
+        return CA_STATUS_FAILED;
+    }
+
+    if (CALEClientIsDeviceInList(address))
+    {
+        CALEState_t* curState = CALEClientGetStateInfo(address);
+        if(!curState)
+        {
+            OIC_LOG(ERROR, TAG, "curState is null");
+            oc_mutex_unlock(g_deviceStateListMutex);
+            return CA_STATUS_FAILED;
+        }
+        OIC_LOG_V(INFO, TAG, "auto connect flag is set %d", flag);
+
+        curState->autoConnectFlag = flag;
+    }
+
+    oc_mutex_unlock(g_deviceStateListMutex);
+    OIC_LOG(DEBUG, TAG, "OUT - CALEClientSetAutoConnectFlag");
+    return CA_STATUS_OK;
+}
+
+bool CALEClientGetAutoConnectFlag(const char *address)
+{
+    OIC_LOG(DEBUG, TAG, "IN - CALEClientGetAutoConnectFlag");
+
+    oc_mutex_lock(g_deviceStateListMutex);
+
+    if (!address)
+    {
+        OIC_LOG(ERROR, TAG, "address is not available");
+        return false;
+    }
+
+    CALEState_t* curState = CALEClientGetStateInfo(address);
+    if(!curState)
+    {
+        OIC_LOG(INFO, TAG, "there is no information. auto connect flag is false");
+        oc_mutex_unlock(g_deviceStateListMutex);
+        return false;
+    }
+    OIC_LOG_V(INFO, TAG, "auto connect flag is %d", curState->autoConnectFlag);
+
+    oc_mutex_unlock(g_deviceStateListMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT - CALEClientGetAutoConnectFlag");
+    return curState->autoConnectFlag;
+}
+
+CAResult_t CALEClientConnect(CBPeripheral *peripheral, bool autoconnect)
+{
+    OIC_LOG(DEBUG, TAG, "CALEClientConnect");
+
+    return [cbCentralIf CALEClientConnectImpl:peripheral];
+}
+
+CAResult_t CALEClientDisconnect(CBPeripheral *peripheral)
+{
+    OIC_LOG(DEBUG, TAG, "GATT DISCONNECT");
+
+    [cbCentralIf CALEClientCancelPeripheralConnection: peripheral];
+    return CA_STATUS_OK;
+}
+
+CAResult_t CALEClientConnectCancel(CBPeripheral *peripheral)
+{
+    OIC_LOG(DEBUG, TAG, "GATT CONNECT CENCEL");
+
+    [cbCentralIf CALEClientCancelPeripheralConnection: peripheral];
+    return CA_STATUS_OK;
+}
+
+CAResult_t CALEClientDisconnectAll()
+{
+    OIC_LOG(DEBUG, TAG, "CALEClientDisconnectAll");
+
+    if (!g_gattObjectList)
+    {
+        OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
+        return CA_STATUS_OK;
+    }
+
+    uint32_t length = u_arraylist_length(g_gattObjectList);
+    OIC_LOG_V(DEBUG, TAG, "list length : %d", length);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        OIC_LOG(DEBUG, TAG, "start CALEClientDisconnectAll");
+        CBPeripheral *tPeripheral = (CBPeripheral *) u_arraylist_get(g_gattObjectList, index);
+
+        CAResult_t res = CALEClientDisconnect(tPeripheral);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "CALEClientDisconnect has failed");
+            continue;
+        }
+    }
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CALEClientDisconnectforAddress(const char *remote_address)
+{
+    OIC_LOG(DEBUG, TAG, "IN-CALEClientDisconnectforAddress");
+
+    if (!g_gattObjectList)
+    {
+        OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
+        return CA_STATUS_OK;
+    }
+
+    uint32_t length = u_arraylist_length(g_gattObjectList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        CBPeripheral *tPeripheral = (CBPeripheral *) u_arraylist_get(g_gattObjectList, index);
+
+        const char* setAddress = [[cbCentralIf CALEGetAddressFromBTDevice: tPeripheral] UTF8String];
+        if (!setAddress)
+        {
+            OIC_LOG(ERROR, TAG, "setAddress is null");
+            return CA_STATUS_FAILED;
+        }
+
+        if (!strcmp(remote_address, setAddress))
+        {
+            CAResult_t res = CALEClientDisconnect(tPeripheral);
+            if (CA_STATUS_OK != res)
+            {
+                OIC_LOG(ERROR, TAG, "CALEClientDisconnect failed");
+                return CA_STATUS_FAILED;
+            }
+        }
+    }
+    OIC_LOG(DEBUG, TAG, "OUT-CALEClientDisconnectforAddress");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CALEClientWriteCharacteristic(CBPeripheral *peripheral)
+{
+    OIC_LOG(DEBUG, TAG, "IN - CALEClientWriteCharacteristic");
+
+    CBService *service = [cbServices objectForKey:peripheral];
+    if (service == NULL){
+        OIC_LOG(ERROR, TAG, "can't find service obj");
+        return CA_STATUS_FAILED;
+    }else{
+        CBCharacteristic *requestCharacteristic = [requestCharacs objectForKey:peripheral];
+        if (requestCharacteristic == NULL){
+            OIC_LOG(ERROR, TAG, "can't find request characteristic obj");
+            return CA_STATUS_FAILED;
+        }else{
+            CAResult_t ret = CALEClientWriteCharacteristicImpl(peripheral, requestCharacteristic);
+            if (CA_STATUS_OK != ret){
+                CALEClientSendFinish(peripheral);
+                return CA_STATUS_FAILED;
+            }
+        }
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT - CALEClientWriteCharacteristic");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CALEClientWriteCharacteristicImpl(CBPeripheral *peripheral,
+                                             CBCharacteristic *requestCharc)
+{
+    OIC_LOG(DEBUG, TAG, "WRITE GATT CHARACTERISTIC");
+
+    if (!CALEClientIsEnableBTAdapter())
+    {
+        OIC_LOG(INFO, TAG, "BT adapter is not enabled");
+        return CA_STATUS_FAILED;
+    }
+
+    CAResult_t ret = [cbCentralIf CALEClientWriteValue: peripheral: requestCharc];
+
+    const char *address = [CALEClientGetAddressFromGattObj(peripheral) UTF8String];
+    if (CA_STATUS_OK != ret){
+        OIC_LOG(ERROR, TAG, "write characteristic failed");
+        CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
+                                    STATE_SEND_FAILED);
+
+        CALEClientSendFinish(peripheral);
+        return CA_STATUS_FAILED;
+    }else{
+        OIC_LOG(DEBUG, TAG, "writeCharacteristic is called successfully");
+        CALEClientUpdateDeviceState(address, STATE_CONNECTED, STATE_CHARACTER_SET,
+                                    STATE_SEND_SUCCESS);
+        CALEClientUpdateSendCnt();
+    }
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CALEClientSetCharacteristicNotification(CBPeripheral *peripheral,
+                                                   CBCharacteristic *responsCharc)
+{
+    if (!CALEClientIsEnableBTAdapter())
+    {
+        OIC_LOG(INFO, TAG, "BT adapter is not enabled");
+        return CA_ADAPTER_NOT_ENABLED;
+    }
+
+    [cbCentralIf CALEClientSetNotifyCharacteristic: peripheral: responsCharc];
+
+    return CA_STATUS_OK;
+}
+
+void CALEClientCreateScanDeviceList()
+{
+    OIC_LOG(DEBUG, TAG, "CALEClientCreateScanDeviceList");
+
+    oc_mutex_lock(g_deviceListMutex);
+    // create new object array
+    if (g_deviceList == NULL)
+    {
+        OIC_LOG(DEBUG, TAG, "Create device list");
+
+        g_deviceList = u_arraylist_create();
+    }
+    oc_mutex_unlock(g_deviceListMutex);
+}
+
+CAResult_t CALEClientAddScanDeviceToList(CBPeripheral *peripheral)
+{
+    oc_mutex_lock(g_deviceListMutex);
+
+    if (!g_deviceList)
+    {
+        OIC_LOG(ERROR, TAG, "gdevice_list is null");
+
+        CALEClientSetScanFlag(false);
+        OIC_LOG(DEBUG, TAG, "CALEClientAddScanDeviceToList --> stop scan");
+        if(CA_STATUS_OK != CALEClientStopScan())
+        {
+            OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
+        }
+
+        oc_mutex_unlock(g_deviceListMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    const char *remoteAddress = [[cbCentralIf CALEGetAddressFromBTDevice: peripheral] UTF8String];
+    if (!remoteAddress)
+    {
+        OIC_LOG(ERROR, TAG, "remoteAddress is null");
+        oc_mutex_unlock(g_deviceListMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    if (!CALEClientIsDeviceInScanDeviceList(remoteAddress))
+    {
+        u_arraylist_add(g_deviceList, peripheral);
+        oc_cond_signal(g_deviceDescCond);
+        OIC_LOG_V(DEBUG, TAG, "Added this BT Device[%s] in the List", remoteAddress);
+    }
+
+    oc_mutex_unlock(g_deviceListMutex);
+
+    return CA_STATUS_OK;
+}
+
+bool CALEClientIsDeviceInScanDeviceList(const char* remoteAddress)
+{
+    VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
+
+    if (!g_deviceList)
+    {
+        OIC_LOG(DEBUG, TAG, "g_deviceList is null");
+        return true;
+    }
+
+    uint32_t length = u_arraylist_length(g_deviceList);
+    int is_mac = isMAC(remoteAddress);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        CBPeripheral *tPeripheral = (CBPeripheral *) u_arraylist_get(g_deviceList, index);
+
+        if(is_mac == 1)
+        {
+            const char* setAddress = [[cbCentralIf CALEGetAddressFromBTDevice:
+                                       tPeripheral] UTF8String];
+
+            if (!strcmp(remoteAddress, setAddress))
+            {
+                return true;
+            }
+        }
+        else
+        {
+            OIC_LOG(DEBUG, TAG, "this is uuid unicast!");
+            const char* localUuid = [[[tPeripheral identifier] UUIDString] UTF8String];
+
+            if(localUuid == NULL)
+            {
+                continue;
+            }
+
+            if(!strcmp(remoteAddress, localUuid))
+            {
+                OIC_LOG(DEBUG, TAG, "find same one!!!!");
+                return true;
+            }
+        }
+    }
+
+    OIC_LOG(DEBUG, TAG, "there are no the device in list. we can add");
+
+    return false;
+}
+
+CAResult_t CALEClientRemoveAllScanDevices()
+{
+    OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllScanDevices");
+
+    oc_mutex_lock(g_deviceListMutex);
+
+    if (!g_deviceList)
+    {
+        OIC_LOG(ERROR, TAG, "g_deviceList is null");
+        oc_mutex_unlock(g_deviceListMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    uint32_t length = u_arraylist_length(g_deviceList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        CBPeripheral *tPeripheral = (CBPeripheral *) u_arraylist_get(g_deviceList, 0);
+        tPeripheral.delegate = nil;
+        [cbPeripherals removeObjectForKey: tPeripheral];
+        u_arraylist_remove(g_deviceList, 0);
+    }
+
+    OICFree(g_deviceList);
+    g_deviceList = NULL;
+
+    oc_mutex_unlock(g_deviceListMutex);
+    return CA_STATUS_OK;
+}
+
+CAResult_t CALEClientRemoveDeviceInScanDeviceList(NSString *address)
+{
+    OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceInScanDeviceList");
+    VERIFY_NON_NULL(address, TAG, "address is null");
+    if (nil == address){
+        OIC_LOG(INFO, TAG, "CALEClientRemoveDeviceInScanDeviceList address == nil");
+        return CA_STATUS_FAILED;
+    }
+
+    oc_mutex_lock(g_deviceListMutex);
+
+    if (!g_deviceList)
+    {
+        OIC_LOG(ERROR, TAG, "g_deviceList is null");
+        oc_mutex_unlock(g_deviceListMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    uint32_t length = u_arraylist_length(g_deviceList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        CBPeripheral *tPeripheral = (CBPeripheral *) u_arraylist_get(g_deviceList, index);
+
+        NSString *setAddress = [cbCentralIf CALEGetAddressFromBTDevice: tPeripheral];
+
+        OIC_LOG_V(DEBUG, TAG, "removedeviceinscandevicelist -address: %s-setaddr: %s",
+                  [address UTF8String], [setAddress UTF8String]);
+
+        if ([address isEqualToString:setAddress])
+        {
+            [cbPeripherals removeObjectForKey: tPeripheral];
+            if (NULL == u_arraylist_remove(g_deviceList, index))
+            {
+                OIC_LOG(ERROR, TAG, "List removal failed.");
+                oc_mutex_unlock(g_deviceListMutex);
+                return CA_STATUS_FAILED;
+            }
+            oc_mutex_unlock(g_deviceListMutex);
+            return CA_STATUS_OK;
+        }
+    }
+
+    oc_mutex_unlock(g_deviceListMutex);
+    OIC_LOG(DEBUG, TAG, "There are no object in the device list");
+
+    return CA_STATUS_OK;
+}
+
+/**
+ * Gatt Object List
+ */
+
+CAResult_t CALEClientAddGattobjToList(CBPeripheral *peripheral)
+{
+    OIC_LOG(INFO, TAG, "CALEClientAddGattobjToList");
+
+    oc_mutex_lock(g_gattObjectMutex);
+
+    if (!g_gattObjectList)
+    {
+        OIC_LOG(ERROR, TAG, "g_gattObjectList is not available");
+        oc_mutex_unlock(g_gattObjectMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    NSString *remoteAddress = CALEClientGetAddressFromGattObj(peripheral);
+    if (remoteAddress == nil || [remoteAddress isEqualToString:@"<null>"]
+        || [remoteAddress isEqualToString:@"null"] || remoteAddress == (id)[NSNull null]
+        || [[remoteAddress stringByTrimmingCharactersInSet:
+             [NSCharacterSet whitespaceAndNewlineCharacterSet]] isEqualToString:@""]){
+        OIC_LOG(ERROR, TAG, "remoteAddress is null");
+        oc_mutex_unlock(g_gattObjectMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    const char *remoteAddr = [remoteAddress UTF8String];
+    OIC_LOG_V(INFO, TAG, "remote address : %s", remoteAddr);
+    if (!CALEClientIsGattObjInList(remoteAddr))
+    {
+        u_arraylist_add(g_gattObjectList, peripheral);
+        OIC_LOG(INFO, TAG, "Set GATT Object to Array as Element");
+    }
+
+    oc_mutex_unlock(g_gattObjectMutex);
+    return CA_STATUS_OK;
+}
+
+bool CALEClientIsGattObjInList(const char* remoteAddress)
+{
+    OIC_LOG(DEBUG, TAG, "CALEClientIsGattObjInList");
+
+    VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", true);
+
+    uint32_t length = u_arraylist_length(g_gattObjectList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+
+        CBPeripheral *tPeripheral = (CBPeripheral *) u_arraylist_get(g_gattObjectList, index);
+        if (!tPeripheral)
+        {
+            OIC_LOG(ERROR, TAG, "jarrayObj is null");
+            return true;
+        }
+
+        NSString *setAddress = CALEClientGetAddressFromGattObj(tPeripheral);
+        if (setAddress == nil || [setAddress isEqualToString:@"<null>"]
+            || [setAddress isEqualToString:@"null"] || setAddress == (id)[NSNull null]
+            || [[setAddress stringByTrimmingCharactersInSet:
+                 [NSCharacterSet whitespaceAndNewlineCharacterSet]] isEqualToString:@""]){
+            OIC_LOG(ERROR, TAG, "setAddress is null");
+            return true;
+        }
+
+        const char* setAddr = [setAddress UTF8String];
+        if (!setAddress)
+        {
+            OIC_LOG(ERROR, TAG, "setAddress is null");
+            return true;
+        }
+
+        if (!strcmp(remoteAddress, setAddr))
+        {
+            OIC_LOG(DEBUG, TAG, "the device is already set");
+            return true;
+        }
+        else
+        {
+            continue;
+        }
+    }
+
+    OIC_LOG(DEBUG, TAG, "There are no GATT object in list. it can be added");
+    return false;
+}
+
+CBPeripheral *CALEClientGetGattObjInList(const char* remoteAddress)
+{
+    OIC_LOG(DEBUG, TAG, "CALEClientGetGattObjInList");
+    VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
+
+    oc_mutex_lock(g_gattObjectMutex);
+    uint32_t length = u_arraylist_length(g_gattObjectList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        CBPeripheral *tPeripheral = (CBPeripheral *) u_arraylist_get(g_gattObjectList, index);
+        if (!tPeripheral)
+        {
+            OIC_LOG(ERROR, TAG, "peripheral is null");
+            oc_mutex_unlock(g_gattObjectMutex);
+            return NULL;
+        }
+
+        NSString *setAddress = CALEClientGetAddressFromGattObj(tPeripheral);
+        if (setAddress == nil || [setAddress isEqualToString:@"<null>"]
+            || [setAddress isEqualToString:@"null"] || setAddress == (id)[NSNull null]
+            || [[setAddress stringByTrimmingCharactersInSet:
+                 [NSCharacterSet whitespaceAndNewlineCharacterSet]] isEqualToString:@""]){
+            OIC_LOG(ERROR, TAG, "setAddress is null");
+            oc_mutex_unlock(g_gattObjectMutex);
+            return NULL;
+        }
+
+        const char* setAddr = [setAddress UTF8String];
+        if (!setAddr)
+        {
+            OIC_LOG(ERROR, TAG, "setAddress is null");
+            oc_mutex_unlock(g_gattObjectMutex);
+            return NULL;
+        }
+
+        if (!strcmp(remoteAddress, setAddr))
+        {
+            OIC_LOG(DEBUG, TAG, "the device is already set");
+            oc_mutex_unlock(g_gattObjectMutex);
+            return tPeripheral;
+        }
+    }
+
+    oc_mutex_unlock(g_gattObjectMutex);
+    OIC_LOG(DEBUG, TAG, "There are no the gatt object in list");
+    return NULL;
+}
+
+CAResult_t CALEClientRemoveAllGattObjs()
+{
+    OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllGattObjs");
+
+    oc_mutex_lock(g_gattObjectMutex);
+    if (!g_gattObjectList)
+    {
+        OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
+        oc_mutex_unlock(g_gattObjectMutex);
+        return CA_STATUS_OK;
+    }
+
+    uint32_t length = u_arraylist_length(g_gattObjectList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        CBPeripheral *tPeripheral = (CBPeripheral *) u_arraylist_get(g_gattObjectList, index);
+        if (!tPeripheral)
+        {
+            OIC_LOG(ERROR, TAG, "tPeripheral is null");
+            continue;
+        }else{
+            if (NULL == u_arraylist_remove(g_gattObjectList, index))
+            {
+                OIC_LOG(ERROR, TAG, "List removal failed.");
+                oc_mutex_unlock(g_gattObjectMutex);
+                return CA_STATUS_FAILED;
+            }
+        }
+    }
+
+    OICFree(g_gattObjectList);
+    g_gattObjectList = NULL;
+    OIC_LOG(INFO, TAG, "g_gattObjectList is removed");
+    oc_mutex_unlock(g_gattObjectMutex);
+    return CA_STATUS_OK;
+}
+
+CAResult_t CALEClientRemoveGattObj(CBPeripheral *peripheral)
+{
+    OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObj");
+
+    oc_mutex_lock(g_gattObjectMutex);
+    if (!g_gattObjectList)
+    {
+        OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
+        oc_mutex_unlock(g_gattObjectMutex);
+        return CA_STATUS_OK;
+    }
+
+    uint32_t length = u_arraylist_length(g_gattObjectList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        CBPeripheral *tPeripheral = (CBPeripheral *) u_arraylist_get(g_gattObjectList, index);
+        if ([peripheral isEqual:tPeripheral]){
+            if (NULL == u_arraylist_remove(g_gattObjectList, index))
+            {
+                OIC_LOG(ERROR, TAG, "List removal failed.");
+                oc_mutex_unlock(g_gattObjectMutex);
+                return CA_STATUS_FAILED;
+            }
+        }
+    }
+
+    oc_mutex_unlock(g_gattObjectMutex);
+    OIC_LOG(DEBUG, TAG, "there are no target object");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CALEClientRemoveGattObjForAddr(const char* remoteAddr)
+{
+    OIC_LOG(DEBUG, TAG, "CALEClientRemoveGattObjForAddr");
+    VERIFY_NON_NULL(remoteAddr, TAG, "addr is null");
+
+    oc_mutex_lock(g_gattObjectMutex);
+    if (!g_gattObjectList)
+    {
+        OIC_LOG(DEBUG, TAG, "already removed for g_gattObjectList");
+        oc_mutex_unlock(g_gattObjectMutex);
+        return CA_STATUS_OK;
+    }
+
+    uint32_t length = u_arraylist_length(g_gattObjectList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        CBPeripheral *tPeripheral = (CBPeripheral *) u_arraylist_get(g_gattObjectList, index);
+        if (!tPeripheral)
+        {
+            OIC_LOG(ERROR, TAG, "tPeripheral is null");
+            oc_mutex_unlock(g_gattObjectMutex);
+            return CA_STATUS_FAILED;
+        }
+
+        NSString *setAddress = CALEClientGetAddressFromGattObj(tPeripheral);
+        if (setAddress == nil || [setAddress isEqualToString:@"<null>"]
+            || [setAddress isEqualToString:@"null"] || setAddress == (id)[NSNull null]
+            || [[setAddress stringByTrimmingCharactersInSet:
+                 [NSCharacterSet whitespaceAndNewlineCharacterSet]] isEqualToString:@""]){
+            OIC_LOG(ERROR, TAG, "setAddress is null");
+            oc_mutex_unlock(g_gattObjectMutex);
+            return CA_STATUS_FAILED;
+        }
+
+        const char* setAddr = [setAddress UTF8String];
+        if (!setAddr)
+        {
+            OIC_LOG(ERROR, TAG, "setAddress is null");
+            oc_mutex_unlock(g_gattObjectMutex);
+            return CA_STATUS_FAILED;
+        }
+
+        if (!strcmp(setAddr, remoteAddr))
+        {
+            OIC_LOG_V(DEBUG, TAG, "remove object : %s", remoteAddr);
+            if (NULL == u_arraylist_remove(g_gattObjectList, index))
+            {
+                OIC_LOG(ERROR, TAG, "List removal failed.");
+                oc_mutex_unlock(g_gattObjectMutex);
+                return CA_STATUS_FAILED;
+            }
+            oc_mutex_unlock(g_gattObjectMutex);
+            return CA_STATUS_OK;
+        }
+    }
+
+    oc_mutex_unlock(g_gattObjectMutex);
+    OIC_LOG(DEBUG, TAG, "there are no target object");
+    return CA_STATUS_FAILED;
+}
+
+/**
+ * BT State List
+ */
+
+CAResult_t CALEClientUpdateDeviceState(const char* address,
+                                       uint32_t connectedState,
+                                       uint16_t notificationState,
+                                       uint16_t sendState)
+{
+    VERIFY_NON_NULL(address, TAG, "address is null");
+
+    CALEState_t *newstate = (CALEState_t*) OICCalloc(1, sizeof(*newstate));
+    if (!newstate)
+    {
+        OIC_LOG(ERROR, TAG, "out of memory");
+        return CA_MEMORY_ALLOC_FAILED;
+    }
+
+    if (strlen(address) > CA_MACADDR_SIZE)
+    {
+        OIC_LOG(ERROR, TAG, "address is not proper");
+        OICFree(newstate);
+        return CA_STATUS_FAILED;
+    }
+
+    OICStrcpy(newstate->address, sizeof(newstate->address), address);
+    newstate->connectedState = connectedState;
+    newstate->notificationState = notificationState;
+    newstate->sendState = sendState;
+    return CALEClientAddDeviceStateToList(newstate);
+}
+
+CAResult_t CALEClientAddDeviceStateToList(CALEState_t* state)
+{
+    VERIFY_NON_NULL(state, TAG, "state is null");
+
+    oc_mutex_lock(g_deviceStateListMutex);
+
+    if (!g_deviceStateList)
+    {
+        OIC_LOG(ERROR, TAG, "gdevice_list is null");
+        oc_mutex_unlock(g_deviceStateListMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    if (CALEClientIsDeviceInList(state->address))
+    {
+        CALEState_t* curState = CALEClientGetStateInfo(state->address);
+        if(!curState)
+        {
+            OIC_LOG(ERROR, TAG, "curState is null");
+            oc_mutex_unlock(g_deviceStateListMutex);
+            return CA_STATUS_FAILED;
+        }
+
+        if (STATE_CHARACTER_NO_CHANGE == state->notificationState)
+        {
+            state->notificationState = curState->notificationState;
+        }
+        state->autoConnectFlag = curState->autoConnectFlag;
+
+        // delete previous state for update new state
+        CAResult_t res = CALEClientRemoveDeviceState(state->address);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "CALEClientRemoveDeviceState has failed");
+            oc_mutex_unlock(g_deviceStateListMutex);
+            return res;
+        }
+    }
+    u_arraylist_add(g_deviceStateList, state); // update new state
+    OIC_LOG_V(INFO, TAG, "Set State Info to List : %d, %d, %s, %d",
+              state->connectedState, state->notificationState,
+              state->address, state->autoConnectFlag);
+
+    oc_mutex_unlock(g_deviceStateListMutex);
+    return CA_STATUS_OK;
+}
+
+bool CALEClientIsDeviceInList(const char* remoteAddress)
+{
+    VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
+
+    if (!g_deviceStateList)
+    {
+        OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
+        return false;
+    }
+
+    uint32_t length = u_arraylist_length(g_deviceStateList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
+        if (!state)
+        {
+            OIC_LOG(ERROR, TAG, "CALEState_t object is null");
+            return false;
+        }
+
+        if (!strcmp(remoteAddress, state->address))
+        {
+            OIC_LOG(DEBUG, TAG, "the device is already set");
+            return true;
+        }
+    }
+
+    OIC_LOG(DEBUG, TAG, "there are no the device in list.");
+    return false;
+}
+
+CAResult_t CALEClientRemoveAllDeviceState()
+{
+    OIC_LOG(DEBUG, TAG, "CALEClientRemoveAllDeviceState");
+
+    oc_mutex_lock(g_deviceStateListMutex);
+    if (!g_deviceStateList)
+    {
+        OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
+        oc_mutex_unlock(g_deviceStateListMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    uint32_t length = u_arraylist_length(g_deviceStateList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
+        if (!state)
+        {
+            OIC_LOG(ERROR, TAG, "jarrayObj is null");
+            continue;
+        }else{
+            u_arraylist_remove(g_deviceStateList, index);
+        }
+        OICFree(state);
+    }
+
+    OICFree(g_deviceStateList);
+    g_deviceStateList = NULL;
+    oc_mutex_unlock(g_deviceStateListMutex);
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CALEClientResetDeviceStateForAll()
+{
+    OIC_LOG(DEBUG, TAG, "CALEClientResetDeviceStateForAll");
+
+    oc_mutex_lock(g_deviceStateListMutex);
+    if (!g_deviceStateList)
+    {
+        OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
+        oc_mutex_unlock(g_deviceStateListMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    size_t length = u_arraylist_length(g_deviceStateList);
+    for (size_t index = 0; index < length; index++)
+    {
+        CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
+        if (!state)
+        {
+            OIC_LOG(ERROR, TAG, "jarrayObj is null");
+            continue;
+        }
+
+        // autoConnectFlag value will be not changed,
+        // since it has reset only termination case.
+        state->connectedState = STATE_DISCONNECTED;
+        state->notificationState = STATE_CHARACTER_UNSET;
+        state->sendState = STATE_SEND_NONE;
+    }
+    oc_mutex_unlock(g_deviceStateListMutex);
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CALEClientRemoveDeviceState(const char* remoteAddress)
+{
+    OIC_LOG(DEBUG, TAG, "CALEClientRemoveDeviceState");
+    VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
+
+    if (!g_deviceStateList)
+    {
+        OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
+        return CA_STATUS_FAILED;
+    }
+
+    uint32_t length = u_arraylist_length(g_deviceStateList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
+        if (!state)
+        {
+            OIC_LOG(ERROR, TAG, "CALEState_t object is null");
+            continue;
+        }
+
+        if (!strcmp(state->address, remoteAddress))
+        {
+            OIC_LOG_V(DEBUG, TAG, "remove state : %s", state->address);
+
+            CALEState_t* targetState  = (CALEState_t*)u_arraylist_remove(g_deviceStateList,
+                                                                         index);
+            if (NULL == targetState)
+            {
+                OIC_LOG(ERROR, TAG, "List removal failed.");
+                return CA_STATUS_FAILED;
+            }
+
+            OICFree(targetState);
+            return CA_STATUS_OK;
+        }
+    }
+
+    return CA_STATUS_OK;
+}
+
+CALEState_t* CALEClientGetStateInfo(const char* remoteAddress)
+{
+    OIC_LOG(DEBUG, TAG, "CALEClientGetStateInfo");
+    VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", NULL);
+
+    if (!g_deviceStateList)
+    {
+        OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
+        return NULL;
+    }
+
+    uint32_t length = u_arraylist_length(g_deviceStateList);
+    OIC_LOG_V(DEBUG, TAG, "CALEClientGetStateInfo : %d", length);
+
+    for (uint32_t index = 0; index < length; index++)
+    {
+        CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
+        if (!state)
+        {
+            OIC_LOG(ERROR, TAG, "CALEState_t object is null");
+            continue;
+        }
+
+        OIC_LOG_V(DEBUG, TAG, "target address : %s", remoteAddress);
+        OIC_LOG_V(DEBUG, TAG, "state address : %s", state->address);
+
+        if (!strcmp(state->address, remoteAddress))
+        {
+            OIC_LOG_V(DEBUG, TAG, "get state : %s", remoteAddress);
+            return state;
+        }
+    }
+    return NULL;
+}
+
+bool CALEClientIsConnectedDevice(const char* remoteAddress)
+{
+    OIC_LOG(DEBUG, TAG, "CALEClientIsConnectedDevice");
+    VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
+
+    oc_mutex_lock(g_deviceStateListMutex);
+    if (!g_deviceStateList)
+    {
+        OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
+        oc_mutex_unlock(g_deviceStateListMutex);
+        return false;
+    }
+
+    uint32_t length = u_arraylist_length(g_deviceStateList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
+        if (!state)
+        {
+            OIC_LOG(ERROR, TAG, "CALEState_t object is null");
+            continue;
+        }
+
+        if (!strcmp(state->address, remoteAddress))
+        {
+            OIC_LOG(DEBUG, TAG, "check whether it is connected or not");
+
+            if (STATE_CONNECTED == state->connectedState)
+            {
+                oc_mutex_unlock(g_deviceStateListMutex);
+                return true;
+            }
+            else
+            {
+                oc_mutex_unlock(g_deviceStateListMutex);
+                return false;
+            }
+        }
+    }
+    oc_mutex_unlock(g_deviceStateListMutex);
+    return false;
+}
+
+bool CALEClientIsSetCharacteristic(const char* remoteAddress)//, const char* serviceId)
+{
+    OIC_LOG(DEBUG, TAG, "CALEClientIsSetCharacteristic");
+    VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
+
+    oc_mutex_lock(g_deviceStateListMutex);
+    if (!g_deviceStateList)
+    {
+        OIC_LOG(ERROR, TAG, "g_deviceStateList is null");
+        oc_mutex_unlock(g_deviceStateListMutex);
+        return false;
+    }
+
+    uint32_t length = u_arraylist_length(g_deviceStateList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        CALEState_t* state = (CALEState_t*) u_arraylist_get(g_deviceStateList, index);
+        if (!state)
+        {
+            OIC_LOG(ERROR, TAG, "CALEState_t object is null");
+            continue;
+        }
+
+        if (!strcmp(state->address, remoteAddress))
+        {
+            OIC_LOG_V(DEBUG, TAG, "check whether it was set or not:%d", state->notificationState);
+
+            if (STATE_CHARACTER_SET == state->notificationState)
+            {
+                oc_mutex_unlock(g_deviceStateListMutex);
+                OIC_LOG(DEBUG, TAG, "state->notificationState was set");
+                return true;
+            }
+            else
+            {
+                oc_mutex_unlock(g_deviceStateListMutex);
+                OIC_LOG(DEBUG, TAG, "state->notificationState was not set");
+                return false;
+            }
+        }
+    }
+
+    oc_mutex_unlock(g_deviceStateListMutex);
+    return false;
+}
+
+void CALEClientCreateDeviceList()
+{
+    OIC_LOG(DEBUG, TAG, "CALEClientCreateDeviceList");
+
+    // create new object array
+    if (!g_gattObjectList)
+    {
+        OIC_LOG(DEBUG, TAG, "Create g_gattObjectList");
+
+        g_gattObjectList = u_arraylist_create();
+    }
+
+    if (!g_deviceStateList)
+    {
+        OIC_LOG(DEBUG, TAG, "Create g_deviceStateList");
+
+        g_deviceStateList = u_arraylist_create();
+    }
+
+    if (!g_deviceList)
+    {
+        OIC_LOG(DEBUG, TAG, "Create g_deviceList");
+
+        g_deviceList = u_arraylist_create();
+    }
+}
+
+/**
+ * Check Sent Count for remove g_sendBuffer
+ */
+void CALEClientUpdateSendCnt()
+{
+    OIC_LOG(DEBUG, TAG, "CALEClientUpdateSendCnt");
+
+    // mutex lock
+    oc_mutex_lock(g_threadMutex);
+
+    g_currentSentCnt++;
+
+    if (g_targetCnt <= g_currentSentCnt)
+    {
+        g_targetCnt = 0;
+        g_currentSentCnt = 0;
+
+        //init g_sendbuffer
+        if (g_sendBuffer != nil ){//|| g_sendBuffer != NULL || [g_sendBuffer length] > 0){
+            //[g_sendBuffer release];
+            g_sendBuffer = nil;
+        }
+
+        // notity the thread
+        oc_cond_signal(g_threadCond);
+
+        CALEClientSetSendFinishFlag(true);
+
+        OIC_LOG(DEBUG, TAG, "set signal for send data");
+    }
+    // mutex unlock
+    oc_mutex_unlock(g_threadMutex);
+}
+
+CAResult_t CALEClientInitGattMutexVaraibles()
+{
+    if (NULL == g_bleReqRespClientCbMutex)
+    {
+        g_bleReqRespClientCbMutex = oc_mutex_new();
+        if (NULL == g_bleReqRespClientCbMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_bleServerBDAddressMutex)
+    {
+        g_bleServerBDAddressMutex = oc_mutex_new();
+        if (NULL == g_bleServerBDAddressMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_threadMutex)
+    {
+        g_threadMutex = oc_mutex_new();
+        if (NULL == g_threadMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_threadSendMutex)
+    {
+        g_threadSendMutex = oc_mutex_new();
+        if (NULL == g_threadSendMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_deviceListMutex)
+    {
+        g_deviceListMutex = oc_mutex_new();
+        if (NULL == g_deviceListMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_gattObjectMutex)
+    {
+        g_gattObjectMutex = oc_mutex_new();
+        if (NULL == g_gattObjectMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_deviceStateListMutex)
+    {
+        g_deviceStateListMutex = oc_mutex_new();
+        if (NULL == g_deviceStateListMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_SendFinishMutex)
+    {
+        g_SendFinishMutex = oc_mutex_new();
+        if (NULL == g_SendFinishMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_scanMutex)
+    {
+        g_scanMutex = oc_mutex_new();
+        if (NULL == g_scanMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == waitMutex){
+        waitMutex = oc_mutex_new();
+    }
+
+    if (NULL == g_threadWriteCharacteristicMutex)
+    {
+        g_threadWriteCharacteristicMutex = oc_mutex_new();
+        if (NULL == g_threadWriteCharacteristicMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_deviceScanRetryDelayMutex)
+    {
+        g_deviceScanRetryDelayMutex = oc_mutex_new();
+        if (NULL == g_deviceScanRetryDelayMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_initializeMutex)
+    {
+        g_initializeMutex = oc_mutex_new();
+        if (NULL == g_initializeMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    return CA_STATUS_OK;
+}
+
+void CALEClientTerminateGattMutexVariables()
+{
+    oc_mutex_free(g_bleReqRespClientCbMutex);
+    g_bleReqRespClientCbMutex = NULL;
+
+    oc_mutex_free(g_bleServerBDAddressMutex);
+    g_bleServerBDAddressMutex = NULL;
+
+    oc_mutex_free(g_threadMutex);
+    g_threadMutex = NULL;
+
+    oc_mutex_free(g_threadSendMutex);
+    g_threadSendMutex = NULL;
+
+    oc_mutex_free(g_deviceListMutex);
+    g_deviceListMutex = NULL;
+
+    oc_mutex_free(g_SendFinishMutex);
+    g_SendFinishMutex = NULL;
+
+    oc_mutex_free(g_scanMutex);
+    g_scanMutex = NULL;
+
+    oc_mutex_free(waitMutex);
+    waitMutex = NULL;
+
+    oc_mutex_free(g_threadWriteCharacteristicMutex);
+    g_threadWriteCharacteristicMutex = NULL;
+
+    oc_mutex_free(g_deviceScanRetryDelayMutex);
+    g_deviceScanRetryDelayMutex = NULL;
+
+    oc_mutex_free(g_initializeMutex);
+    g_initializeMutex = NULL;
+}
+
+void CALEClientSetSendFinishFlag(bool flag)
+{
+    OIC_LOG_V(DEBUG, TAG, "g_isFinishedSendData is %d", flag);
+
+    oc_mutex_lock(g_SendFinishMutex);
+    g_isFinishedSendData = flag;
+    oc_mutex_unlock(g_SendFinishMutex);
+}
+
+/**
+ * adapter common
+ */
+
+CAResult_t CAStartLEGattClient()
+{
+    // init mutex for send logic
+    if (!g_deviceDescCond)
+    {
+        g_deviceDescCond = oc_cond_new();
+    }
+
+    if (!g_threadCond)
+    {
+        g_threadCond = oc_cond_new();
+    }
+
+    if (!g_threadWriteCharacteristicCond)
+    {
+        g_threadWriteCharacteristicCond = oc_cond_new();
+    }
+
+    g_isStartedLEClient = true;
+    return CA_STATUS_OK;
+}
+
+void CAStopLEGattClient()
+{
+    OIC_LOG(DEBUG, TAG, "CAStopBLEGattClient");
+
+    g_isStartedLEClient = false;
+
+    CAResult_t ret = CALEClientDisconnectAll();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
+    }
+
+    ret = CALEClientStopScan();
+    if(CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientStopScan has failed");
+    }
+
+    oc_mutex_lock(g_threadMutex);
+    OIC_LOG(DEBUG, TAG, "signal - connection cond");
+    oc_cond_signal(g_threadCond);
+    CALEClientSetSendFinishFlag(true);
+    oc_mutex_unlock(g_threadMutex);
+
+    oc_mutex_lock(g_threadWriteCharacteristicMutex);
+    OIC_LOG(DEBUG, TAG, "signal - WriteCharacteristic cond");
+    oc_cond_signal(g_threadWriteCharacteristicCond);
+    oc_mutex_unlock(g_threadWriteCharacteristicMutex);
+
+    oc_mutex_lock(g_deviceScanRetryDelayMutex);
+    OIC_LOG(DEBUG, TAG, "signal - delay cond");
+    oc_cond_signal(g_deviceScanRetryDelayCond);
+    oc_mutex_unlock(g_deviceScanRetryDelayMutex);
+
+    oc_cond_signal(g_deviceDescCond);   //change
+
+    oc_cond_free(g_deviceDescCond);
+    oc_cond_free(g_threadCond);
+    oc_cond_free(g_threadWriteCharacteristicCond);
+    oc_cond_free(g_deviceScanRetryDelayCond);
+
+    g_deviceDescCond = NULL;
+    g_threadCond = NULL;
+    g_threadWriteCharacteristicCond = NULL;
+    g_deviceScanRetryDelayCond = NULL;
+}
+
+CAResult_t CAInitializeLEGattClient()
+{
+    OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
+    CALEClientInitialize();
+    return CA_STATUS_OK;
+}
+
+void CATerminateLEGattClient()
+{
+    OIC_LOG(DEBUG, TAG, "Terminate GATT Client");
+    CAStopLEGattClient();
+    CALEClientTerminate();
+}
+
+CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress,
+                                               const uint8_t  *data,
+                                               uint32_t dataLen,
+                                               CALETransferType_t type,
+                                               int32_t position)
+{
+    OIC_LOG(DEBUG, TAG, "call CALEClientSendUnicastMessage");
+    VERIFY_NON_NULL(data, TAG, "data is null");
+    VERIFY_NON_NULL(remoteAddress, TAG, "remoteAddress is null");
+
+    if (LE_UNICAST != type || position < 0)
+    {
+        OIC_LOG(ERROR, TAG, "this request is not unicast");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    return CALEClientSendUnicastMessage(remoteAddress, data, dataLen);
+}
+
+CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
+{
+    OIC_LOG(DEBUG, TAG, "call CALEClientSendMulticastMessage");
+    VERIFY_NON_NULL(data, TAG, "data is null");
+
+    return CALEClientSendMulticastMessage(data, dataLen);
+}
+
+void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
+{
+    oc_mutex_lock(g_bleReqRespClientCbMutex);
+    g_CABLEClientDataReceivedCallback = callback;
+    oc_mutex_unlock(g_bleReqRespClientCbMutex);
+}
+
+void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
+{
+    g_threadPoolHandle = handle;
+}
+
+CAResult_t CAGetLEAddress(char **local_address){
+    return CA_NOT_SUPPORTED;
+}
+
+void CALEClientSetFlagBTAdapter(bool state){
+    isEnableBtAdapter = state;
+}
+
+bool CALEClientIsEnableBTAdapter(){
+    return isEnableBtAdapter;
+}
\ No newline at end of file
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/ios/calenwmonitor.h b/resource/csdk/connectivity/src/bt_le_adapter/ios/calenwmonitor.h
new file mode 100644 (file)
index 0000000..c382e90
--- /dev/null
@@ -0,0 +1,51 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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 BT LE communications.
+*/
+#ifndef CA_LENWMONITOR_H_
+#define CA_LENWMONITOR_H_
+
+#include "cacommon.h"
+#include "cathreadpool.h"
+#include "uarraylist.h"
+#include "caleinterface.h"
+#include "caleutils.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+void CALESetAdapterStateCallback(CALEDeviceStateChangedCallback callback);
+
+void CALEClientNWStateChangeCallback(CALE_STATE_t status);
+
+void CALEServerDisconnectCallback(const char *address);
+void CALEClientDisconnectCallback(const char *address);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* CA_LENWMONITOR_H_ */
+
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/ios/calenwmonitor.m b/resource/csdk/connectivity/src/bt_le_adapter/ios/calenwmonitor.m
new file mode 100644 (file)
index 0000000..1951c03
--- /dev/null
@@ -0,0 +1,305 @@
+/******************************************************************
+ *
+ * Copyright 2017 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 <stdio.h>
+#include "logger.h"
+#include "calenwmonitor.h"
+#include "caleclient.h"
+#include "caleserver.h"
+#include "caleutils.h"
+#include "caleinterface.h"
+#include "caadapterutils.h"
+
+#include "octhread.h"
+
+#define TAG PCF("OIC_CA_LE_MONITOR")
+
+static oc_cond g_deviceStateCbCond = NULL;
+static oc_mutex g_deviceStateCbMutex = NULL;
+
+/**
+ * @var g_bleDeviceStateChangedCallback
+ * @brief Maintains the callback to be notified on device state changed.
+ */
+static CALEDeviceStateChangedCallback g_bleDeviceStateChangedCallback = NULL;
+
+/**
+ * @var g_bleConnectionStateChangedCallback
+ * @brief Maintains the callback to be notified on device state changed.
+ */
+static CALEConnectionStateChangedCallback g_bleConnectionStateChangedCallback = NULL;
+
+/**
+ * @var g_bleDeviceStateChangedCbMutex
+ * @brief Mutex to synchronize access to the deviceStateChanged Callback when the state
+ *           of the LE adapter gets change.
+ */
+static oc_mutex g_bleDeviceStateChangedCbMutex = NULL;
+
+/**
+ * @var g_bleConnectionStateChangedCbMutex
+ * @brief Mutex to synchronize access to the LE ConnectionStateChanged Callback when the state
+ *           of the LE adapter gets change.
+ */
+static oc_mutex g_bleConnectionStateChangedCbMutex = NULL;
+
+void CALESetAdapterStateCallback(CALEDeviceStateChangedCallback callback)
+{
+    OIC_LOG(DEBUG, TAG, "CALESetAdapterStateCallback");
+    g_bleDeviceStateChangedCallback = callback;
+
+    oc_cond_signal(g_deviceStateCbCond);
+}
+
+CAResult_t CAInitializeLEAdapter(const ca_thread_pool_t threadPool)
+{
+    OIC_LOG(DEBUG, TAG, "IN - CAInitializeLEAdapter");
+    (void)threadPool;
+    OIC_LOG(DEBUG, TAG, "OUT - CAInitializeLEAdapter");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAStartLEAdapter()
+{
+    // Nothing to do.
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAStopLEAdapter()
+{
+    // Nothing to do.
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAInitLENwkMonitorMutexVaraibles()
+{
+    OIC_LOG(DEBUG, TAG, "IN - CAInitLENwkMonitorMutexVaraibles");
+    if (NULL == g_deviceStateCbMutex)
+    {
+        g_deviceStateCbMutex = oc_mutex_new();
+        if (NULL == g_deviceStateCbMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_bleDeviceStateChangedCbMutex)
+    {
+        g_bleDeviceStateChangedCbMutex = oc_mutex_new();
+        if (NULL == g_bleDeviceStateChangedCbMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_bleConnectionStateChangedCbMutex)
+    {
+        g_bleConnectionStateChangedCbMutex = oc_mutex_new();
+        if (NULL == g_bleConnectionStateChangedCbMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            oc_mutex_free(g_bleConnectionStateChangedCbMutex);
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT - CAInitLENwkMonitorMutexVaraibles");
+    return CA_STATUS_OK;
+}
+
+void CATerminateLENwkMonitorMutexVaraibles()
+{
+    OIC_LOG(DEBUG, TAG, "IN - CATerminateLENwkMonitorMutexVaraibles");
+
+    oc_mutex_free(g_deviceStateCbMutex);
+    g_deviceStateCbMutex = NULL;
+
+    oc_mutex_free(g_bleDeviceStateChangedCbMutex);
+    g_bleDeviceStateChangedCbMutex = NULL;
+
+    oc_mutex_free(g_bleConnectionStateChangedCbMutex);
+    g_bleConnectionStateChangedCbMutex = NULL;
+
+    OIC_LOG(DEBUG, TAG, "OUT - CATerminateLENwkMonitorMutexVaraibles");
+}
+
+CAResult_t CAGetLEAdapterState()
+{
+    OIC_LOG(DEBUG, TAG, "IN - CAGetLEAdapterState");
+
+    if (!CALEClientIsEnableBTAdapter() || !CALEServerIsEnableBTAdapter())
+    {
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT - CAGetLEAdapterState");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAInitializeLENetworkMonitor()
+{
+    OIC_LOG(DEBUG, TAG, "IN - CAInitializeLENetworkMonitor");
+
+    if (NULL == g_deviceStateCbCond){
+        g_deviceStateCbCond = oc_cond_new();
+    }
+
+    CAResult_t res = CAInitLENwkMonitorMutexVaraibles();
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "CAInitLENwkMonitorMutexVaraibles has failed");
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT- CAInitializeLENetworkMonitor");
+
+    return CA_STATUS_OK;
+
+}
+
+void CATerminateLENetworkMonitor()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    oc_cond_free(g_deviceStateCbCond);
+    g_deviceStateCbCond = NULL;
+
+    CATerminateLENwkMonitorMutexVaraibles();
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+CAResult_t CASetLEAdapterStateChangedCb(CALEDeviceStateChangedCallback callback)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    OIC_LOG(DEBUG, TAG, "Setting CALEDeviceStateChangedCallback");
+
+    oc_mutex_lock(g_bleDeviceStateChangedCbMutex);
+    CALESetAdapterStateCallback(callback);
+    oc_mutex_unlock(g_bleDeviceStateChangedCbMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAUnSetLEAdapterStateChangedCb()
+{
+    OIC_LOG(DEBUG, TAG, "it is not required in this platform");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CASetLENWConnectionStateChangedCb(CALEConnectionStateChangedCallback callback)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    oc_mutex_lock(g_bleConnectionStateChangedCbMutex);
+    g_bleConnectionStateChangedCallback = callback;
+    oc_mutex_unlock(g_bleConnectionStateChangedCbMutex);
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAUnSetLENWConnectionStateChangedCb()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    oc_mutex_lock(g_bleConnectionStateChangedCbMutex);
+    g_bleConnectionStateChangedCallback = NULL;
+    oc_mutex_unlock(g_bleConnectionStateChangedCbMutex);
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CALEClientNWStateChangeCallback(CALE_STATE_t state){
+    OIC_LOG_V(DEBUG, TAG, "[Network State Changed]: state(%s)",
+            state == 1 ? "STATE_ON": (state == 0 ? "STATE_OFF" : "TURN_OFF"));
+
+    if (!g_bleDeviceStateChangedCallback)
+    {
+        OIC_LOG(ERROR, TAG, "gNetworkChangeCb is null --> wait~");
+        if (NULL == g_deviceStateCbMutex){
+            g_deviceStateCbMutex = oc_mutex_new();
+        }
+        if (NULL == g_deviceStateCbCond){
+            g_deviceStateCbCond = oc_cond_new();
+        }
+        oc_mutex_lock(g_deviceStateCbMutex);
+        oc_cond_wait(g_deviceStateCbCond, g_deviceStateCbMutex);
+        oc_mutex_unlock(g_deviceStateCbMutex);
+    }
+
+    CAAdapterState_t newStatus = CA_ADAPTER_ENABLED;
+    CAResult_t res = CA_STATUS_OK;
+    switch(state){
+        case CALE_STATE_ON:
+            newStatus = CA_ADAPTER_ENABLED;
+            CALEClientCreateDeviceList();
+            CALEServerCreateCachedDeviceList();
+
+            g_bleDeviceStateChangedCallback(newStatus);
+            break;
+        case CALE_STATE_TURNING_OFF:
+            CAStopLEGattClient();
+            break;
+        default:
+        case CALE_STATE_OFF:
+            res = CALEClientRemoveAllGattObjs();
+            if (CA_STATUS_OK != res)
+            {
+                OIC_LOG(ERROR, TAG, "CALEClientRemoveAllGattObjs has failed");
+            }
+
+            res = CALEClientResetDeviceStateForAll();
+            if (CA_STATUS_OK != res)
+            {
+                OIC_LOG(ERROR, TAG, "CALEClientResetDeviceStateForAll has failed");
+            }
+            res = CALEServerRemoveAllDevices();
+            if (CA_STATUS_OK != res)
+            {
+                OIC_LOG(ERROR, TAG, "CALEServerRemoveAllDevices has failed");
+            }
+            CALEClientSetScanFlag(false);
+
+            newStatus = CA_ADAPTER_DISABLED;
+            g_bleDeviceStateChangedCallback(newStatus);
+            break;
+    }
+}
+
+void CALEClientDisconnectCallabck(const char *address){
+    OIC_LOG(DEBUG, TAG, "[CALEClientDisconnectCallabck] Central: disconnect");
+    if (g_bleConnectionStateChangedCallback)
+    {
+        g_bleConnectionStateChangedCallback(CA_ADAPTER_GATT_BTLE, address, false);
+    }
+}
+
+void CALEServerDisconnectCallback(const char *address){
+    OIC_LOG(DEBUG, TAG, "[CALEServerDisconnectCallback] Peripheral: disconnect");
+    if (g_bleConnectionStateChangedCallback)
+    {
+        g_bleConnectionStateChangedCallback(CA_ADAPTER_GATT_BTLE, address, false);
+    }
+}
+
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/ios/caleserver.h b/resource/csdk/connectivity/src/bt_le_adapter/ios/caleserver.h
new file mode 100644 (file)
index 0000000..8555bd4
--- /dev/null
@@ -0,0 +1,240 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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 BT LE communications.
+ */
+#ifndef CA_LESERVER_H_
+#define CA_LESERVER_H_
+
+#include "cacommon.h"
+#include "cathreadpool.h"
+#include "uarraylist.h"
+
+#include "caleutils.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * Callback to be notified on reception of any data from remote devices.
+ * @param[in]  address           MAC address of remote device.
+ * @param[in]  data              Data received from remote device.
+ * @pre  Callback must be registered using CALEServerSetCallback(CAPacketReceiveCallback callback).
+ */
+typedef void (*CAPacketReceiveCallback)(const char *address, const uint8_t *data);
+
+/**
+ * initialize server for BLE.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEServerInitialize();
+
+/**
+ * terminate client for BLE.
+ */
+void CALEServerTerminate();
+
+/**
+ * send data for unicast (interface).
+ * @param[in]   address          remote address.
+ * @param[in]   data             data for transmission.
+ * @param[in]   dataLen          data length.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEServerSendUnicastMessage(const char *address,
+                                        const uint8_t *data,
+                                        uint32_t dataLen);
+
+/**
+ * send data for multicast (interface).
+ * @param[in]   data             data for transmission.
+ * @param[in]   dataLen          data length.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEServerSendMulticastMessage(const uint8_t *data, uint32_t dataLen);
+
+/**
+ * start multicast server (start advertise).
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEServerStartMulticastServer();
+
+/**
+ * stop multicast server (stop discovery).
+ * @return  None
+ */
+CAResult_t CALEServerStopMulticastServer();
+
+/**
+ * set this callback for receiving data packets from peer devices.
+ * @param[in]   callback         callback to be notified on reception of
+ *                               unicast/multicast data packets.
+ */
+void CALEServerSetCallback(CAPacketReceiveCallback callback);
+
+/**
+ * send data for unicast (implement).
+ * @param[in]   env              JNI interface pointer.
+ * @param[in]   address          remote address.
+ * @param[in]   data             data for transmission.
+ * @param[in]   dataLen          data length.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEServerSendUnicastMessageImpl(const char *address,
+                                            const uint8_t *data,
+                                            uint32_t dataLen);
+
+/**
+ * send data for multicast (implement)
+ * @param[in]   env              JNI interface pointer
+ * @param[in]   data             data for transmission
+ * @param[in]   dataLen          data length
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEServerSendMulticastMessageImpl(const uint8_t *data,
+                                              uint32_t dataLen);
+
+/**
+ * start advertise in gatt server.
+ */
+CAResult_t CALEStartAdvertise();
+
+/**
+ * start advertise in gatt server.
+ * @param[in]   env                JNI interface pointer.
+ * @param[in]   advertiseCallback  callback to be notified on reception of
+ *                                 advertisement result.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEServerStartAdvertise();
+
+/**
+ * stop advertise in gatt server.
+ * @param[in]   env                JNI interface pointer.
+ * @param[in]   advertiseCallback  callback to be notified on reception of
+ *                                 advertisement result.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEServerStopAdvertise();
+
+/**
+ * start gatt server.
+ * @param[in]   env                  JNI interface pointer.
+ * @param[in]   gattServerCallback   callback to be notified on reception of
+ *                                   state change of gatt server.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEServerStartGattServer();
+
+/**
+ * close gatt server.
+ * @param[in]   env                  JNI interface pointer.
+ * @param[in]   bluetoothGattServer  Gatt Server object.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+//CAResult_t CALEServerGattClose();
+/**
+ * send data.
+ * @param[in]   env                  JNI interface pointer.
+ * @param[in]   bluetoothDevice      bluetooth device object.
+ * @param[in]   data                 data which send.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEServerSend(CBCentral *central, const uint8_t *data, const uint32_t dataLen);
+
+/**
+ * disconnect LE for all devices.
+ * @param[in]   env                  JNI interface pointer.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+//CAResult_t CALEServerDisconnectAllDevices();
+
+/**
+ * create connected device list.
+ */
+void CALEServerCreateCachedDeviceList();
+
+/**
+ * check whether the device exist in the list or not.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   remoteAddress         remote address.
+ * @return  true or false.
+ */
+bool CALEServerIsDeviceInList(const char* remoteAddress);//, const char* serviceUUID);
+
+/**
+ * add device object to the list (connected device list).
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   device                bluetooth device object.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEServerAddDeviceToList(CBCentral *central);
+
+/**
+ * remove all devices objects in the list (connected device list).
+ * @param[in]   env                   JNI interface pointer.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEServerRemoveAllDevices();
+
+/**
+ * remove target device in the list (connected device list).
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   address               target address to remove.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEServerRemoveDevice(const char *remoteAddr);
+
+/**
+ * initialize mutex.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEServerInitMutexVaraibles();
+
+/**
+ * terminate mutex.
+ */
+void CALEServerTerminateMutexVaraibles();
+
+/**
+ * initialize condition.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEServerInitConditionVaraibles();
+
+/**
+ * terminate condition.
+ */
+void CALEServerTerminateConditionVaraibles();
+
+NSString *CALEServerGetAddressFromGattObj(CBCentral *central);
+
+bool CALEServerIsEnableBTAdapter();
+void CALEServerSetFlagBTAdapter(bool state);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* CA_LESERVER_H_ */
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/ios/caleserver.m b/resource/csdk/connectivity/src/bt_le_adapter/ios/caleserver.m
new file mode 100644 (file)
index 0000000..562729a
--- /dev/null
@@ -0,0 +1,982 @@
+/******************************************************************
+ *
+ * Copyright 2017 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 <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include "caleserver.h"
+#include "caleutils.h"
+#include "caleinterface.h"
+#include "caadapterutils.h"
+
+#include "logger.h"
+#include "oic_malloc.h"
+#include "cathreadpool.h"
+#include "octhread.h"
+#include "uarraylist.h"
+
+#define TAG PCF("OIC_CA_LE_SERVER")
+
+#define WAIT_TIME_WRITE_CHARACTERISTIC 10000000
+
+static CAPacketReceiveCallback g_packetReceiveCallback = NULL;
+static CABLEErrorHandleCallback g_serverErrorCallback;
+
+static u_arraylist_t *g_connectedDeviceList = NULL;
+
+static bool g_isStartServer = false;
+static bool g_isInitializedServer = false;
+
+static CABLEDataReceivedCallback g_CABLEServerDataReceivedCallback = NULL;
+static oc_mutex g_bleReqRespCbMutex = NULL;
+static oc_mutex g_bleClientBDAddressMutex = NULL;
+static oc_mutex g_connectedDeviceListMutex = NULL;
+
+static oc_cond g_transmitQueueCond = NULL;
+static oc_mutex g_transmitQueueMutex = NULL;
+
+static bool g_isStartAdvertising = false;
+static bool isEnableGattServer = true;
+
+static id cbPeripheralIf;
+
+@interface CBPeripheralIfClass:NSObject <CBPeripheralManagerDelegate>
+@end
+
+NSMutableArray *peripheralMgrs;
+static CBMutableCharacteristic *readCharacteristic = nil;
+static CBMutableCharacteristic *writeCharacteristic = nil;
+NSMutableDictionary *cbCentrals;
+NSMutableDictionary *cbCentralsConnInfo;
+
+@implementation CBPeripheralIfClass
+static CBPeripheralManager *peripheralMgr = nil;
+
+- (void) createPeripheralManager{
+    OIC_LOG(DEBUG, TAG, "[CBPrl] create peripheral manager");
+    peripheralMgr = [[CBPeripheralManager alloc] initWithDelegate:self
+                    queue:nil options:nil];
+    peripheralMgrs = [NSMutableArray new];
+    cbCentrals = [[NSMutableDictionary alloc] init];
+    cbCentralsConnInfo = [[NSMutableDictionary alloc] init];
+}
+
+- (void) setCharacteristic{
+    OIC_LOG(DEBUG, TAG, "[CBPrl] set Characteristic");
+    readCharacteristic = [[CBMutableCharacteristic alloc]
+            initWithType:[CBUUID UUIDWithString:
+                          [NSString stringWithUTF8String:OIC_GATT_CHARACTERISTIC_RESPONSE_UUID]]
+            properties:CBCharacteristicPropertyNotify | CBCharacteristicPropertyRead
+            value: nil
+            permissions:CBAttributePermissionsReadable];
+    writeCharacteristic = [[CBMutableCharacteristic alloc]
+            initWithType:[CBUUID UUIDWithString:
+                          [NSString stringWithUTF8String:OIC_GATT_CHARACTERISTIC_REQUEST_UUID]]
+            properties: CBCharacteristicPropertyWrite | CBCharacteristicPropertyWriteWithoutResponse
+            value:nil
+            permissions:CBAttributePermissionsWriteable];
+}
+
+- (CBMutableService *) setService{
+    OIC_LOG(DEBUG, TAG, "PeripheralInterface: set Service");
+    CBMutableService *leService = [[CBMutableService alloc]
+            initWithType:[CBUUID UUIDWithString:
+                          [NSString stringWithUTF8String:OIC_GATT_SERVICE_UUID]]
+            primary:YES];
+
+    return leService;
+}
+
+- (void) addService:(CBMutableService *) leService :(CBPeripheralManager *)peripheral{
+    OIC_LOG(DEBUG, TAG, "PeripheralInterface: add Service");
+    leService.characteristics = @[readCharacteristic, writeCharacteristic];
+    [peripheral addService:leService];
+}
+
+- (void) startAdvertising: (CBPeripheralManager *)peripheral{
+    [self setCharacteristic];
+    [self addService:[self setService]:peripheral];
+
+    NSString *beaconName = @"IoTivity Service";
+
+    if (!g_isStartAdvertising){
+        OIC_LOG(DEBUG, TAG, "PeripheralInterface: startAdvertising 1");
+        [peripheral startAdvertising:@{
+            CBAdvertisementDataLocalNameKey: beaconName,
+            CBAdvertisementDataServiceUUIDsKey:
+            @[[CBUUID UUIDWithString:[NSString stringWithUTF8String:OIC_GATT_SERVICE_UUID]]]}
+        ];
+        g_isStartAdvertising = true;
+    }
+}
+
+- (void) stopAdvertising{
+    OIC_LOG(DEBUG, TAG, "PeripheralInterface: stopAdvertising");
+    [peripheralMgr stopAdvertising];
+}
+
+- (CAResult_t) sendData:(CBCentral *) connCentral :(NSData *)data{
+    if (peripheralMgr != nil){
+        if (connCentral != nil){
+            OIC_LOG_V(DEBUG, TAG, "central: %s, senddata updateValue",
+                      [[connCentral.identifier UUIDString] UTF8String]);
+            NSUInteger tLen = [data length];
+            uint8_t *tData = (uint8_t *)malloc(tLen);
+            memcpy(tData, [data bytes], tLen);
+            OIC_LOG_BUFFER(DEBUG, TAG, tData, tLen);
+            free(tData);
+            bool result = [peripheralMgr updateValue: data
+                    forCharacteristic:readCharacteristic
+                    onSubscribedCentrals:@[connCentral]];
+            if (result){
+                OIC_LOG(DEBUG, TAG, "CBCI: sending success");
+                return CA_STATUS_OK;
+            }else{
+                OIC_LOG(ERROR, TAG, "CBCI: transmit queue is full! --> wait");
+
+                oc_mutex_lock(g_transmitQueueMutex);
+                oc_cond_wait(g_transmitQueueCond, g_transmitQueueMutex);
+                oc_mutex_unlock(g_transmitQueueMutex);
+
+                [peripheralMgr updateValue: data
+                        forCharacteristic:readCharacteristic
+                        onSubscribedCentrals:@[connCentral]];
+                return CA_STATUS_OK;
+            }
+        }else{
+            OIC_LOG(ERROR, TAG, "CBCI: connectedCentral ERROR");
+            return CA_STATUS_FAILED;
+        }
+    }
+    return CA_STATUS_FAILED;
+}
+
+- (NSString *) createCentralUUID{
+    CFUUIDRef theUUID = CFUUIDCreate(NULL);
+    CFStringRef uuidString = CFUUIDCreateString(NULL, theUUID);
+    NSString *uuid = (NSString *)CFStringCreateCopy(NULL, uuidString);
+    CFRelease(theUUID);
+    CFRelease(uuidString);
+    return [uuid autorelease];
+}
+
+#pragma mark - CBPeripheralManagerDelegate
+
+- (void) peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral{
+    if (peripheral.state == CBPeripheralManagerStatePoweredOn){
+        OIC_LOG(DEBUG, TAG, "PeripheralInterface: update state --> POWERED ON");
+        peripheralMgr = peripheral;
+        [peripheralMgrs addObject:peripheralMgr];
+
+        CALEServerSetFlagBTAdapter(true);
+
+        if (!g_isStartAdvertising){
+            CALEServerStartAdvertise();
+        }
+    }else {
+        OIC_LOG(DEBUG, TAG, "PeripheralInterface: update state --> ! powered on");
+        [peripheralMgrs removeObject: peripheral];
+        CALEServerSetFlagBTAdapter(false);
+
+        return;
+    }
+}
+
+- (void)peripheralManager:(CBPeripheralManager *)peripheral
+        didAddService:(CBService *)service error:(NSError *)error{
+    OIC_LOG_V(INFO, TAG, "didAddService:%s", [[service.UUID UUIDString] UTF8String]);
+    if (error){
+        OIC_LOG_V(ERROR, TAG, "didAddService:%s,  error:%s",
+                [[service.UUID UUIDString] UTF8String], [[error localizedDescription] UTF8String]);
+    }
+}
+
+- (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral
+        error:(NSError *)error{
+    if ([[error localizedDescription] isEqualToString:@"null"]
+            || [[error localizedDescription] isEqualToString:@"<null>"]
+            || [[error localizedDescription] isEqualToString:@"(null)"]
+            || [[error localizedDescription] length] != 0){
+
+        OIC_LOG_V(ERROR, TAG, "peripheralManagerDidStartAdvertising : error:%s",
+                [[error localizedDescription] UTF8String]);
+    }
+}
+
+- (void)peripheralManager: (CBPeripheralManager *)peripheral
+        didReceiveReadRequest:(CBATTRequest *)request{
+    OIC_LOG(DEBUG, TAG, "didReceiveReadRequest");
+}
+
+- (void)peripheralManager:(CBPeripheralManager *)peripheral
+        central:(CBCentral *)central
+        didSubscribeToCharacteristic:(CBCharacteristic *)characteristic{
+    OIC_LOG(DEBUG, TAG, "PeripheralInterface: connected");
+    OIC_LOG_V(DEBUG, TAG, "connected characteristic %s",
+                [[characteristic.UUID UUIDString] UTF8String]);
+
+    bool hasCentral = false;
+    for (CBCentral *key in cbCentrals){
+        if ([key isEqual:central]){
+            hasCentral = true;
+            OIC_LOG_V(DEBUG, TAG, "tuuid %s", [[cbCentrals objectForKey:key] UTF8String]);
+        }
+    }
+
+    if (!hasCentral){
+        OIC_LOG(DEBUG, TAG, "set Central Object");
+        [cbCentrals setObject:[cbPeripheralIf createCentralUUID] forKey:central];
+    }
+
+    const char *address = [CALEServerGetAddressFromGattObj(central) UTF8String];
+    if (false == CALEServerIsDeviceInList(address)){
+        OIC_LOG_V(DEBUG, TAG, "add connected Central obj to cache: %s", address);
+        CALEServerAddDeviceToList(central);
+    }
+
+    [cbCentralsConnInfo setObject:[NSNumber numberWithInteger:(int)STATE_CONNECTED] forKey:central];
+}
+
+- (void)peripheralManager:(CBPeripheralManager *)peripheral
+        central:(CBCentral *)central
+        didUnsubscribeFromCharacteristic:(CBCharacteristic *)characteristic{
+    OIC_LOG(DEBUG, TAG, "PeripheralInterface: disconnected");
+
+    const char *address = [CALEServerGetAddressFromGattObj(central) UTF8String];
+    if (true == CALEServerIsDeviceInList(address)){
+        OIC_LOG_V(DEBUG, TAG, "remove connected Central obj to cache: %s", address);
+        CALEServerRemoveDevice(address);
+    }
+
+    [cbCentralsConnInfo setObject:[NSNumber numberWithInteger:
+                                   (int)STATE_DISCONNECTED] forKey:central];
+}
+
+- (void)peripheralManager:(CBPeripheralManager *)peripheral
+        didReceiveWriteRequests: (NSArray *)requests{
+    NSMutableData *nsData = [[NSMutableData alloc] init];
+    for (CBATTRequest *request in requests){
+        if ([request.characteristic.UUID isEqual:
+                [CBUUID UUIDWithString:
+                 [NSString stringWithUTF8String:OIC_GATT_CHARACTERISTIC_REQUEST_UUID]]]){
+            OIC_LOG_V(DEBUG, TAG, "Received data from central %s",
+                      [[request.central.identifier UUIDString] UTF8String]);
+
+            const char* address = [CALEServerGetAddressFromGattObj(request.central) UTF8String];
+            if (!address){
+                OIC_LOG(ERROR, TAG, "address is not available");
+                return;
+            }
+
+            OIC_LOG_V(DEBUG, TAG, "------------- received data (size:%lu)----------------",
+                    request.value.length);
+            [nsData appendData:request.value];
+            uint32_t len = [nsData length];
+            uint8_t *data = (uint8_t*)OICMalloc(len);
+            uint32_t sentLength = 0;
+
+            memcpy(data, (const uint8_t*)[nsData bytes], len);
+
+            OIC_LOG_BUFFER(DEBUG, TAG, data, len);
+
+            oc_mutex_lock(g_bleClientBDAddressMutex);
+            g_CABLEServerDataReceivedCallback(address, data, len, &sentLength);
+            oc_mutex_unlock(g_bleClientBDAddressMutex);
+        }
+    }
+}
+
+- (void)peripheralManagerIsReadyToUpdateSubscribers:(CBPeripheralManager *) peripheral{
+    oc_mutex_lock(g_transmitQueueMutex);
+    OIC_LOG(DEBUG, TAG, "transmit queue is ready to update subscribers");
+    oc_cond_signal(g_transmitQueueCond);
+    oc_mutex_unlock(g_transmitQueueMutex);
+}
+
+@end
+
+
+/**
+ * get the current connection state of the gatt profile to the remote device.
+ * @param[in]   device           bluetooth device object
+ * @return  state of the profile connection.
+ */
+static int CALEServerGetConnectionState(CBCentral *central)
+{
+    OIC_LOG(DEBUG, TAG, "CALEServerGetConnectionState");
+
+    int connState = [[cbCentralsConnInfo objectForKey:central] intValue];
+    OIC_LOG_V(INFO, TAG, "connection state is %d", connState);
+    return connState;
+}
+
+CAResult_t CALEStartAdvertise()
+{
+    CAResult_t ret = CALEServerStartAdvertise();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
+    }
+
+    return ret;
+}
+
+CAResult_t CALEServerStartAdvertise()
+{
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerStartAdvertise");
+
+    if (!CALEServerIsEnableBTAdapter())
+    {
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
+        return CA_ADAPTER_NOT_ENABLED;
+    }
+
+    if ([peripheralMgrs count] != 0 && caglobals.serverFlags){
+        [cbPeripheralIf startAdvertising: peripheralMgrs[0]];
+    }else{
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, TAG, "Advertising started!!");
+
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerStartAdvertise");
+    return CA_STATUS_OK;
+
+}
+
+CAResult_t CALEServerStopAdvertise()
+{
+    OIC_LOG(DEBUG, TAG, "LEServerStopAdvertise");
+
+    if (!CALEServerIsEnableBTAdapter())
+    {
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
+        return CA_ADAPTER_NOT_ENABLED;
+    }
+
+    [cbPeripheralIf stopAdvertising];
+
+    OIC_LOG(DEBUG, TAG, "Advertising stopped!!");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CALEServerStartGattServer()
+{
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerStartGattServer");
+
+    if (!CALEServerIsEnableBTAdapter())
+    {
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
+        return CA_ADAPTER_NOT_ENABLED;
+    }
+
+    if (g_isStartServer)
+    {
+        OIC_LOG(DEBUG, TAG, "Gatt server already started");
+    }
+
+    OIC_LOG(DEBUG,TAG, "OUT - CALEServerStartGattServer");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CALEServerSend(CBCentral *central, const uint8_t *data, const uint32_t dataLen)
+{
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerSend");
+
+    if (!CALEServerIsEnableBTAdapter())
+    {
+        OIC_LOG(ERROR, TAG, "BT adapter is not enabled");
+        return CA_ADAPTER_NOT_ENABLED;
+    }
+
+    NSData *nsData = [NSData dataWithBytes:(const uint8_t*)data length:dataLen];
+    OIC_LOG(DEBUG, TAG, "send data");
+    OIC_LOG_BUFFER(DEBUG, TAG, data, dataLen);
+
+    CAResult_t result = [cbPeripheralIf sendData: central: nsData];
+
+    if (CA_STATUS_OK != result)
+    {
+        OIC_LOG(ERROR, TAG, "Fail to send response data");
+        return result;
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerSend");
+    return result;
+}
+
+CAResult_t CALEServerInitialize()
+{
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerInitialize");
+
+    cbPeripheralIf = [[CBPeripheralIfClass alloc] init];
+    [cbPeripheralIf createPeripheralManager];
+
+    CAResult_t ret = CA_STATUS_FAILED;
+    g_transmitQueueCond = oc_cond_new();
+
+    ret = CALEServerInitMutexVaraibles();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEServerInitMutexVaraibles has failed");
+
+        return CA_STATUS_FAILED;
+    }
+    CALEServerCreateCachedDeviceList();
+
+    g_isInitializedServer = true;
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerInitialize");
+    return CA_STATUS_OK;
+}
+
+void CALEServerTerminate()
+{
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerTerminate");
+
+    CALEServerTerminateMutexVaraibles();
+    CALEServerTerminateConditionVaraibles();
+
+    g_isInitializedServer = false;
+
+    oc_cond_free(g_transmitQueueCond);
+    g_transmitQueueCond = NULL;
+
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerTerminate");
+}
+
+CAResult_t CALEServerSendUnicastMessage(const char* address, const uint8_t* data, uint32_t dataLen)
+{
+    OIC_LOG_V(DEBUG, TAG, "CALEServerSendUnicastMessage(%s, %p)", address, data);
+    VERIFY_NON_NULL(address, TAG, "address is null");
+    VERIFY_NON_NULL(data, TAG, "data is null");
+
+    CAResult_t ret = CALEServerSendUnicastMessageImpl(address, data, dataLen);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEServerSendUnicastMessageImpl has failed");
+    }
+
+    return ret;
+}
+
+CAResult_t CALEServerSendMulticastMessage(const uint8_t* data, uint32_t dataLen)
+{
+    OIC_LOG_V(DEBUG, TAG, "CALEServerSendMulticastMessage(%p)", data);
+    VERIFY_NON_NULL(data, TAG, "data is null");
+
+    CAResult_t ret = CALEServerSendMulticastMessageImpl(data, dataLen);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEServerSendMulticastMessageImpl has failed");
+    }
+
+    return ret;
+}
+
+CAResult_t CALEServerStartMulticastServer()
+{
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerStartMulticastServer");
+
+    if (!g_isInitializedServer)
+    {
+        OIC_LOG(INFO, TAG, "server is not initialized");
+        return CA_STATUS_FAILED;
+    }
+
+    if (g_isStartServer)
+    {
+        OIC_LOG(INFO, TAG, "server is already started..it will be skipped");
+        return CA_STATUS_FAILED;
+    }
+
+    g_isStartServer = true;
+
+    CAResult_t ret = CALEServerStartGattServer();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "Fail to start gatt server");
+        return ret;
+    }
+
+    if(!CALEServerIsEnableBTAdapter())
+    {
+        OIC_LOG(DEBUG, TAG, "Cannot start advertise. Not powered on yet.");
+        return ret;
+    }
+    if(!g_isStartAdvertising)
+        ret = CALEServerStartAdvertise();
+    else
+    {
+        OIC_LOG(DEBUG, TAG, "skipped cause already advertising.");
+    }
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerStartMulticastServer");
+    return ret;
+}
+
+CAResult_t CALEServerStopMulticastServer()
+{
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerStopMulticastServer");
+
+    if (false == g_isStartServer)
+    {
+        OIC_LOG(INFO, TAG, "server is already stopped..it will be skipped");
+        return CA_STATUS_FAILED;
+    }
+
+    CAResult_t ret = CALEServerStopAdvertise();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEServerStopAdvertise has failed");
+    }
+
+    g_isStartServer = false;
+
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerStopMulticastServer");
+    return ret;
+}
+
+void CALEServerSetCallback(CAPacketReceiveCallback callback)
+{
+    OIC_LOG(DEBUG, TAG, "CALEServerSetCallback");
+    g_packetReceiveCallback = callback;
+}
+
+CAResult_t CALEServerSendUnicastMessageImpl(const char* address, const uint8_t* data,
+                                            uint32_t dataLen)
+{
+    OIC_LOG_V(DEBUG, TAG, "CALEServerSendUnicastMessageImpl, address: %s, data: %p, size: %u",
+            address, data, dataLen);
+    OIC_LOG_BUFFER(DEBUG, TAG, data, dataLen);
+    VERIFY_NON_NULL(address, TAG, "address is null");
+    VERIFY_NON_NULL(data, TAG, "data is null");
+
+    if (!g_connectedDeviceList)
+    {
+        OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
+        return CA_STATUS_FAILED;
+    }
+
+
+    uint32_t length = u_arraylist_length(g_connectedDeviceList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        OIC_LOG(DEBUG, TAG, "check device address");
+        CBCentral *tCentral = (CBCentral *) u_arraylist_get(g_connectedDeviceList, index);
+        if (!tCentral)
+        {
+            OIC_LOG(ERROR, TAG, "tCentral is null");
+            return CA_SEND_FAILED;
+        }
+
+        const char *setAddress = [CALEServerGetAddressFromGattObj(tCentral) UTF8String];
+        if (!setAddress)
+        {
+            OIC_LOG(ERROR, TAG, "setAddress is null");
+            return CA_SEND_FAILED;
+        }
+
+        OIC_LOG_V(DEBUG, TAG, "setAddress : %s", setAddress);
+        OIC_LOG_V(DEBUG, TAG, "address : %s", address);
+
+        if (!strcmp(setAddress, address))
+        {
+            OIC_LOG_V(DEBUG, TAG, "found the device: %s", setAddress);
+
+            CAResult_t res = CALEServerSend(tCentral, data, dataLen);
+            if (CA_STATUS_OK != res)
+            {
+                OIC_LOG(ERROR, TAG, "send has failed");
+                return CA_SEND_FAILED;
+            }
+            break;
+        }
+    }
+
+    OIC_LOG(INFO, TAG, "unicast - send request is successful");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CALEServerSendMulticastMessageImpl(const uint8_t *data, uint32_t dataLen)
+{
+    OIC_LOG_V(DEBUG, TAG, "CALEServerSendMulticastMessageImpl, send to, data: %s", data);
+    VERIFY_NON_NULL(data, TAG, "data is null");
+
+    if (!g_connectedDeviceList)
+    {
+        OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
+        return CA_STATUS_FAILED;
+    }
+
+    uint32_t length = u_arraylist_length(g_connectedDeviceList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        CBCentral *tCentral = (CBCentral *) u_arraylist_get(g_connectedDeviceList, index);
+        if (!tCentral)
+        {
+            OIC_LOG(ERROR, TAG, "central is null");
+            continue;
+        }
+
+        const char *addr = [CALEServerGetAddressFromGattObj(tCentral) UTF8String];
+        CAResult_t res = CALEServerSend(tCentral, data, dataLen);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG_V(ERROR, TAG, "Send failed: %s", addr);
+        }
+
+        OIC_LOG_V(INFO, TAG, "unicast - send request is successful for a device[%s]", addr);
+    }
+
+    return CA_STATUS_OK;
+}
+
+void CALEServerCreateCachedDeviceList()
+{
+    oc_mutex_lock(g_connectedDeviceListMutex);
+    if (!g_connectedDeviceList)
+    {
+        OIC_LOG(DEBUG, TAG, "Create device list");
+        g_connectedDeviceList = u_arraylist_create();
+    }
+    oc_mutex_unlock(g_connectedDeviceListMutex);
+}
+
+bool CALEServerIsDeviceInList(const char* remoteAddress)
+{
+    VERIFY_NON_NULL_RET(remoteAddress, TAG, "remoteAddress is null", false);
+
+    if (!g_connectedDeviceList)
+    {
+        OIC_LOG(ERROR, TAG, "list is null");
+        return false;
+    }
+
+    uint32_t length = u_arraylist_length(g_connectedDeviceList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        CBCentral *central = (CBCentral *) u_arraylist_get(g_connectedDeviceList, index);
+
+        if (!central)
+        {
+            OIC_LOG(ERROR, TAG, "connectedDevice is not available");
+            return false;
+        }
+
+        const char* setAddress = [CALEServerGetAddressFromGattObj(central) UTF8String];
+        if (!setAddress)
+        {
+            OIC_LOG(ERROR, TAG, "setAddress is null");
+            return false;
+        }
+
+        if (!strcmp(remoteAddress, setAddress))
+        {
+            OIC_LOG(ERROR, TAG, "the device is already set");
+            return true;
+        }
+    }
+
+    OIC_LOG(DEBUG, TAG, "there are no device in the list");
+    return false;
+}
+
+CAResult_t CALEServerAddDeviceToList(CBCentral *central)
+{
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerAddDeviceToList");
+    VERIFY_NON_NULL(central, TAG, "central is null");
+
+    oc_mutex_lock(g_connectedDeviceListMutex);
+
+    if (!g_connectedDeviceList)
+    {
+        OIC_LOG(ERROR, TAG, "list is null");
+        oc_mutex_unlock(g_connectedDeviceListMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    const char *remoteAddress = [CALEServerGetAddressFromGattObj(central) UTF8String];
+    if (!remoteAddress)
+    {
+        OIC_LOG(ERROR, TAG, "remoteAddress is null");
+        oc_mutex_unlock(g_connectedDeviceListMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    if (false == CALEServerIsDeviceInList(remoteAddress))
+    {
+        u_arraylist_add(g_connectedDeviceList, central);
+        OIC_LOG_V(DEBUG, TAG, "Set the object to ArrayList as Element : %s", remoteAddress);
+    }
+
+    oc_mutex_unlock(g_connectedDeviceListMutex);
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerAddDeviceToList");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CALEServerRemoveAllDevices()
+{
+    OIC_LOG(DEBUG, TAG, "IN - CALEServerRemoveAllDevices");
+
+    oc_mutex_lock(g_connectedDeviceListMutex);
+    if (!g_connectedDeviceList)
+    {
+        OIC_LOG(ERROR, TAG, "g_connectedDeviceList is null");
+        oc_mutex_unlock(g_connectedDeviceListMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    uint32_t length = u_arraylist_length(g_connectedDeviceList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        CBCentral *central = (CBCentral *)u_arraylist_get(g_connectedDeviceList, index);
+        [cbCentrals removeObjectForKey: central];
+        if (NULL == u_arraylist_remove(g_connectedDeviceList, index)){
+            oc_mutex_unlock(g_connectedDeviceListMutex);
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    OICFree(g_connectedDeviceList);
+    g_connectedDeviceList = NULL;
+    oc_mutex_unlock(g_connectedDeviceListMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT - CALEServerRemoveAllDevices");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CALEServerRemoveDevice(const char *remoteAddress)
+{
+    OIC_LOG(DEBUG, TAG, "IN CALEServerRemoveDevice");
+
+    oc_mutex_lock(g_connectedDeviceListMutex);
+    if (!g_connectedDeviceList)
+    {
+        OIC_LOG(ERROR, TAG, "no deviceList");
+        oc_mutex_unlock(g_connectedDeviceListMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    uint32_t length = u_arraylist_length(g_connectedDeviceList);
+    for (uint32_t index = 0; index < length; index++)
+    {
+        CBCentral *central = (CBCentral *)u_arraylist_get(g_connectedDeviceList, index);
+
+        if (central)
+        {
+            const char* setAddress = [CALEServerGetAddressFromGattObj(central) UTF8String];
+            if (!setAddress)
+            {
+                OIC_LOG(ERROR, TAG, "setAddress is null");
+                continue;
+            }
+
+            if (!strcmp(setAddress, remoteAddress))
+            {
+                OIC_LOG_V(DEBUG, TAG, "device address : %s", remoteAddress);
+
+                if (NULL == u_arraylist_remove(g_connectedDeviceList, index))
+                {
+                    OIC_LOG(ERROR, TAG, "List removal failed.");
+                    oc_mutex_unlock(g_connectedDeviceListMutex);
+                    return CA_STATUS_FAILED;
+                }
+                [cbCentrals removeObjectForKey: central];
+                oc_mutex_unlock(g_connectedDeviceListMutex);
+                return CA_STATUS_OK;
+            }
+        }
+    }
+
+    oc_mutex_unlock(g_connectedDeviceListMutex);
+
+    OIC_LOG(DEBUG, TAG, "there are no device in the device list");
+
+    OIC_LOG(DEBUG, TAG, "IN CALEServerRemoveDevice");
+    return CA_STATUS_FAILED;
+}
+
+
+/**
+ * adapter common
+ */
+
+CAResult_t CAStartLEGattServer()
+{
+    CALEServerStartMulticastServer();
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAStopLEGattServer()
+{
+    OIC_LOG(DEBUG, TAG, "CAStopLEGattServer");
+
+    CAResult_t ret = CALEServerRemoveAllDevices();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEServerRemoveAllDevices has failed");
+        return CA_STATUS_FAILED;
+    }
+
+    g_isStartServer = false;
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAInitializeLEGattServer()
+{
+    OIC_LOG(DEBUG, TAG, "Initialize Gatt Server");
+    return CALEServerInitialize();
+}
+
+void CATerminateLEGattServer()
+{
+    OIC_LOG(DEBUG, TAG, "Terminate Gatt Server");
+    CALEServerTerminate();
+}
+
+void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
+{
+    oc_mutex_lock(g_bleReqRespCbMutex);
+    g_CABLEServerDataReceivedCallback = callback;
+    oc_mutex_unlock(g_bleReqRespCbMutex);
+}
+
+void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
+{
+    g_serverErrorCallback = callback;
+}
+
+CAResult_t CAUpdateCharacteristicsToGattClient(const char *address,
+                                               const uint8_t *charValue,
+                                               uint32_t charValueLen)
+{
+    CAResult_t result = CA_SEND_FAILED;
+    VERIFY_NON_NULL(charValue, TAG, "charValue is null");
+
+    if (address)
+    {
+        result = CALEServerSendUnicastMessage(address, charValue, charValueLen);
+    }
+
+    return result;
+}
+
+CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue,
+                                                   uint32_t charValueLen)
+{
+    VERIFY_NON_NULL(charValue, TAG, "device is null");
+
+    CAResult_t result = CALEServerSendMulticastMessage(charValue, charValueLen);
+
+    return result;
+}
+
+void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
+{
+    OIC_LOG(INFO, TAG, "CASetLEServerThreadPoolHandle is not support");
+    (void)handle;
+}
+
+CAResult_t CALEServerInitMutexVaraibles()
+{
+    if (NULL == g_bleReqRespCbMutex)
+    {
+        g_bleReqRespCbMutex = oc_mutex_new();
+        if (NULL == g_bleReqRespCbMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_bleClientBDAddressMutex)
+    {
+        g_bleClientBDAddressMutex = oc_mutex_new();
+        if (NULL == g_bleClientBDAddressMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_connectedDeviceListMutex)
+    {
+        g_connectedDeviceListMutex = oc_mutex_new();
+        if (NULL == g_connectedDeviceListMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_transmitQueueMutex){
+        g_transmitQueueMutex = oc_mutex_new();
+        if (NULL == g_transmitQueueMutex){
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    return CA_STATUS_OK;
+}
+
+void CALEServerTerminateMutexVaraibles()
+{
+    oc_mutex_free(g_bleReqRespCbMutex);
+    g_bleReqRespCbMutex = NULL;
+
+    oc_mutex_free(g_bleClientBDAddressMutex);
+    g_bleClientBDAddressMutex = NULL;
+
+    oc_mutex_free(g_connectedDeviceListMutex);
+    g_connectedDeviceListMutex = NULL;
+
+    oc_mutex_free(g_transmitQueueMutex);
+    g_transmitQueueMutex = NULL;
+}
+
+void CALEServerTerminateConditionVaraibles()
+{
+    OIC_LOG(DEBUG, TAG, "this method is not supported");
+}
+
+NSString *CALEServerGetAddressFromGattObj(CBCentral *central){
+    VERIFY_NON_NULL_RET(central, TAG, "central is null", NULL);
+    NSString *address = [cbCentrals objectForKey: central];
+    if (!address){
+        OIC_LOG(ERROR, TAG, "address isn't available");
+        return NULL;
+    }
+    return address;
+}
+
+void CALEServerSetFlagBTAdapter(bool state){
+    isEnableGattServer = state;
+}
+
+bool CALEServerIsEnableBTAdapter(){
+    return isEnableGattServer;
+}
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/ios/caleutils.h b/resource/csdk/connectivity/src/bt_le_adapter/ios/caleutils.h
new file mode 100644 (file)
index 0000000..e57c704
--- /dev/null
@@ -0,0 +1,66 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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 BT LE communications.
+ */
+#ifndef CA_LE_UTILS_H_
+#define CA_LE_UTILS_H_
+
+#import <Foundation/Foundation.h>
+#import <CoreBluetooth/CoreBluetooth.h>
+
+#include "cacommon.h"
+#include "cathreadpool.h"
+#include "cagattservice.h"
+#include "uarraylist.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+static const char OIC_GATT_SERVICE_UUID[] = CA_GATT_SERVICE_UUID;
+static const char OIC_GATT_CHARACTERISTIC_REQUEST_UUID[] = CA_GATT_REQUEST_CHRC_UUID;
+static const char OIC_GATT_CHARACTERISTIC_RESPONSE_UUID[] = CA_GATT_RESPONSE_CHRC_UUID;
+static const char OIC_GATT_CHARACTERISTIC_CONFIG_UUID[] = "00002902-0000-1000-8000-00805f9b34fb";
+
+static const int GATT_PROFILE = 7;
+static const int GATT_SUCCESS = 0;
+
+static const int BOND_BONDED = 12;
+static const int BOND_BONDING = 11;
+static const int BOND_NONE = 10;
+
+static const int STATE_CONNECTED = 2;
+static const int STATE_DISCONNECTED = 0;
+
+typedef enum{
+    CALE_STATE_OFF = 0,
+    CALE_STATE_ON = 1,
+    CALE_STATE_TURNING_OFF = 2
+} CALE_STATE_t;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* CA_LE_UTILS_H_ */
index 57aa4eb..3647378 100644 (file)
@@ -55,13 +55,13 @@ static bool CALESetUpBlueZObjects(CALEContext * context);
 
 static bool CALECheckStarted()
 {
-    ca_mutex_lock(g_context.lock);
+    oc_mutex_lock(g_context.lock);
 
     bool const started =
         (g_context.event_loop != NULL
          && g_main_loop_is_running(g_context.event_loop));
 
-    ca_mutex_unlock(g_context.lock);
+    oc_mutex_unlock(g_context.lock);
 
     /**
      * @todo Fix potential TOCTOU race condition.  A LE transport
@@ -206,7 +206,7 @@ static void CALEHandleInterfaceAdded(GList ** proxy_list,
         return;
     }
 
-    ca_mutex_lock(g_context.lock);
+    oc_mutex_lock(g_context.lock);
 
     /*
       Add the object information to the list.
@@ -217,7 +217,7 @@ static void CALEHandleInterfaceAdded(GList ** proxy_list,
     */
     *proxy_list = g_list_prepend(*proxy_list, proxy);
 
-    ca_mutex_unlock(g_context.lock);
+    oc_mutex_unlock(g_context.lock);
 
     /**
      * Let the thread that may be blocked waiting for Devices to be
@@ -230,7 +230,7 @@ static void CALEHandleInterfaceAdded(GList ** proxy_list,
      */
     if (strcmp(interface, BLUEZ_DEVICE_INTERFACE) == 0)
     {
-        ca_cond_signal(g_context.condition);
+        oc_cond_signal(g_context.condition);
     }
 }
 
@@ -329,7 +329,7 @@ static void CALEOnInterfacesRemoved(GDBusConnection * connection,
         gchar const * path = NULL;
         g_variant_get_child(parameters, 0, "&o", &path);
 
-        ca_mutex_lock(g_context.lock);
+        oc_mutex_lock(g_context.lock);
 
         for (GList * l = *list; l != NULL; l = g_list_next(l))
         {
@@ -352,7 +352,7 @@ static void CALEOnInterfacesRemoved(GDBusConnection * connection,
             }
         }
 
-        ca_mutex_unlock(g_context.lock);
+        oc_mutex_unlock(g_context.lock);
 
         g_variant_unref(child);
     }
@@ -405,12 +405,12 @@ static void CALESubscribeToSignals(CALEContext * context,
                      G_CALLBACK(CALEOnInterfaceProxyPropertiesChanged),
                      context);
 
-    ca_mutex_lock(context->lock);
+    oc_mutex_lock(context->lock);
 
     context->interfaces_added_sub_id   = interfaces_added_sub_id;
     context->interfaces_removed_sub_id = interfaces_removed_sub_id;
 
-    ca_mutex_unlock(context->lock);
+    oc_mutex_unlock(context->lock);
 }
 
 static bool CALESetUpDBus(CALEContext * context)
@@ -471,10 +471,10 @@ static bool CALESetUpDBus(CALEContext * context)
 
     CALESubscribeToSignals(context, connection, object_manager);
 
-    ca_mutex_lock(context->lock);
+    oc_mutex_lock(context->lock);
     context->connection     = connection;
     context->object_manager = object_manager;
-    ca_mutex_unlock(context->lock);
+    oc_mutex_unlock(context->lock);
 
     success = CALESetUpBlueZObjects(context);
 
@@ -490,7 +490,7 @@ static void CALETearDownDBus(CALEContext * context)
       global state, and pushing resource finalization outside the global
       lock.
     */
-    ca_mutex_lock(context->lock);
+    oc_mutex_lock(context->lock);
 
     GDBusConnection * const connection = context->connection;
     context->connection = NULL;
@@ -513,7 +513,7 @@ static void CALETearDownDBus(CALEContext * context)
     context->interfaces_added_sub_id   = 0;
     context->interfaces_removed_sub_id = 0;
 
-    ca_mutex_unlock(context->lock);
+    oc_mutex_unlock(context->lock);
 
     // Destroy the device proxies list.
     g_list_free_full(devices, g_object_unref);
@@ -599,9 +599,9 @@ static bool CALESetUpBlueZObjects(CALEContext * context)
         return success;
     }
 
-    ca_mutex_lock(context->lock);
+    oc_mutex_lock(context->lock);
     context->objects = objects;
-    ca_mutex_unlock(context->lock);
+    oc_mutex_unlock(context->lock);
 
     /*
       Create a proxies to the org.bluez.Adapter1 D-Bus objects that
@@ -617,9 +617,9 @@ static bool CALESetUpBlueZObjects(CALEContext * context)
     // An empty adapters list is NULL.
     if (success && adapters != NULL)
     {
-        ca_mutex_lock(context->lock);
+        oc_mutex_lock(context->lock);
         context->adapters = adapters;
-        ca_mutex_unlock(context->lock);
+        oc_mutex_unlock(context->lock);
     }
 
     /*
@@ -635,9 +635,9 @@ static bool CALESetUpBlueZObjects(CALEContext * context)
     // An empty device list is NULL.
     if (success && devices != NULL)
     {
-        ca_mutex_lock(context->lock);
+        oc_mutex_lock(context->lock);
         context->devices = devices;
-        ca_mutex_unlock(context->lock);
+        oc_mutex_unlock(context->lock);
     }
 
     return success;
@@ -677,12 +677,12 @@ static void CALEStartEventLoop(void * data)
     */
     if (CALESetUpDBus(&g_context))
     {
-        ca_mutex_lock(context->lock);
+        oc_mutex_lock(context->lock);
 
         assert(context->event_loop == NULL);
         context->event_loop = event_loop;
 
-        ca_mutex_unlock(context->lock);
+        oc_mutex_unlock(context->lock);
 
         /*
           Add an idle handler that notifies a thread waiting for the
@@ -714,12 +714,12 @@ static void CALEStartEventLoop(void * data)
 
 static void CALEStopEventLoop(CALEContext * context)
 {
-    ca_mutex_lock(context->lock);
+    oc_mutex_lock(context->lock);
 
     GMainLoop * const event_loop = context->event_loop;
     context->event_loop = NULL;
 
-    ca_mutex_unlock(context->lock);
+    oc_mutex_unlock(context->lock);
 
     if (event_loop != NULL)
     {
@@ -749,13 +749,13 @@ static bool CALEWaitForNonEmptyList(GList * const * list,
 {
     bool success = false;
 
-    ca_mutex_lock(g_context.lock);
+    oc_mutex_lock(g_context.lock);
 
     for (int i = 0; *list == NULL && i < retries; ++i)
     {
-        if (ca_cond_wait_for(g_context.condition,
+        if (oc_cond_wait_for(g_context.condition,
                              g_context.lock,
-                             timeout) == CA_WAIT_SUCCESS)
+                             timeout) == OC_WAIT_SUCCESS)
         {
             /*
               Condition variable was signaled before the timeout was
@@ -765,7 +765,7 @@ static bool CALEWaitForNonEmptyList(GList * const * list,
         }
     }
 
-    ca_mutex_unlock(g_context.lock);
+    oc_mutex_unlock(g_context.lock);
 
     return success;
 }
@@ -822,7 +822,7 @@ CAResult_t CAStartLEAdapter()
      */
     result = ca_thread_pool_add_task(g_context.client_thread_pool,
                                      CALEStartEventLoop,
-                                     &g_context);
+                                     &g_context, NULL);
 
     /*
       Wait for the GLib event loop to actually run before returning.
@@ -882,7 +882,7 @@ CAResult_t CAGetLEAdapterState()
 {
     CAResult_t result = CA_ADAPTER_NOT_ENABLED;
 
-    ca_mutex_lock(g_context.lock);
+    oc_mutex_lock(g_context.lock);
 
     for (GList * l = g_context.adapters; l != NULL; l = l->next)
     {
@@ -912,7 +912,7 @@ CAResult_t CAGetLEAdapterState()
         }
     }
 
-    ca_mutex_unlock(g_context.lock);
+    oc_mutex_unlock(g_context.lock);
 
     return result;
 }
@@ -928,8 +928,8 @@ CAResult_t CAInitializeLENetworkMonitor()
      * @see @c CAStartLEAdapter() for further details.
      */
 
-    g_context.lock      = ca_mutex_new();
-    g_context.condition = ca_cond_new();
+    g_context.lock      = oc_mutex_new();
+    g_context.condition = oc_cond_new();
 
     static int const PSHARED        = 0;  // shared between threads
     static unsigned int const VALUE = 0;  // force sem_wait() to block
@@ -968,7 +968,7 @@ void CATerminateLENetworkMonitor()
 
     (void) sem_destroy(&g_context.le_started);
 
-    ca_mutex_lock(g_context.lock);
+    oc_mutex_lock(g_context.lock);
 
     g_context.on_device_state_changed = NULL;
     g_context.on_server_received_data = NULL;
@@ -978,21 +978,21 @@ void CATerminateLENetworkMonitor()
     g_context.on_client_error         = NULL;
     g_context.on_server_error         = NULL;
 
-    ca_cond_free(g_context.condition);
+    oc_cond_free(g_context.condition);
     g_context.condition = NULL;
 
-    ca_mutex_unlock(g_context.lock);
+    oc_mutex_unlock(g_context.lock);
 
-    ca_mutex_free(g_context.lock);
+    oc_mutex_free(g_context.lock);
     g_context.lock = NULL;
 }
 
 CAResult_t CASetLEAdapterStateChangedCb(
     CALEDeviceStateChangedCallback callback)
 {
-    ca_mutex_lock(g_context.lock);
+    oc_mutex_lock(g_context.lock);
     g_context.on_device_state_changed = callback;
-    ca_mutex_unlock(g_context.lock);
+    oc_mutex_unlock(g_context.lock);
 
     return CA_STATUS_OK;
 }
@@ -1003,6 +1003,11 @@ CAResult_t CASetLENWConnectionStateChangedCb(CALEConnectionStateChangedCallback
     return CA_NOT_SUPPORTED;
 }
 
+CAResult_t CAUnSetLENWConnectionStateChangedCb()
+{
+    return CA_NOT_SUPPORTED;
+}
+
 CAResult_t CAGetLEAddress(char **local_address)
 {
     OIC_LOG(DEBUG, TAG, "Get Linux BLE local device information.");
@@ -1054,7 +1059,7 @@ CAResult_t CAGetLEAddress(char **local_address)
 
     *local_address = NULL;
 
-    ca_mutex_lock(g_context.lock);
+    oc_mutex_lock(g_context.lock);
 
     for (GList * l = g_context.adapters; l != NULL; l = l->next)
     {
@@ -1098,7 +1103,7 @@ CAResult_t CAGetLEAddress(char **local_address)
         break;
     }
 
-    ca_mutex_unlock(g_context.lock);
+    oc_mutex_unlock(g_context.lock);
 
     return *local_address != NULL ? CA_STATUS_OK : CA_STATUS_FAILED;
 }
@@ -1128,9 +1133,9 @@ void CATerminateLEGattServer()
 
 void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
 {
-    ca_mutex_lock(g_context.lock);
+    oc_mutex_lock(g_context.lock);
     g_context.on_server_received_data = callback;
-    ca_mutex_unlock(g_context.lock);
+    oc_mutex_unlock(g_context.lock);
 }
 
 CAResult_t CAUpdateCharacteristicsToGattClient(char const * address,
@@ -1157,9 +1162,9 @@ CAResult_t CAStartLEGattClient()
         return result;
     }
 
-    ca_mutex_lock(g_context.lock);
+    oc_mutex_lock(g_context.lock);
     bool found_peripherals = (g_context.devices != NULL);
-    ca_mutex_unlock(g_context.lock);
+    oc_mutex_unlock(g_context.lock);
 
     if (!found_peripherals)
     {
@@ -1265,44 +1270,44 @@ CAResult_t CAUpdateCharacteristicsToAllGattServers(uint8_t const * data,
 
 void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
 {
-    ca_mutex_lock(g_context.lock);
+    oc_mutex_lock(g_context.lock);
     g_context.on_client_received_data = callback;
-    ca_mutex_unlock(g_context.lock);
+    oc_mutex_unlock(g_context.lock);
 }
 
 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
 {
-    ca_mutex_lock(g_context.lock);
+    oc_mutex_lock(g_context.lock);
     g_context.server_thread_pool = handle;
-    ca_mutex_unlock(g_context.lock);
+    oc_mutex_unlock(g_context.lock);
 }
 
 void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
 {
-    ca_mutex_lock(g_context.lock);
+    oc_mutex_lock(g_context.lock);
     g_context.client_thread_pool = handle;
-    ca_mutex_unlock(g_context.lock);
+    oc_mutex_unlock(g_context.lock);
 }
 
 CAResult_t CAUnSetLEAdapterStateChangedCb()
 {
-    ca_mutex_lock(g_context.lock);
+    oc_mutex_lock(g_context.lock);
     g_context.on_device_state_changed = NULL;
-    ca_mutex_unlock(g_context.lock);
+    oc_mutex_unlock(g_context.lock);
 
     return CA_STATUS_OK;
 }
 
 void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
 {
-    ca_mutex_lock(g_context.lock);
+    oc_mutex_lock(g_context.lock);
     g_context.on_client_error = callback;
-    ca_mutex_unlock(g_context.lock);
+    oc_mutex_unlock(g_context.lock);
 }
 
 void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
 {
-    ca_mutex_lock(g_context.lock);
+    oc_mutex_lock(g_context.lock);
     g_context.on_server_error = callback;
-    ca_mutex_unlock(g_context.lock);
+    oc_mutex_unlock(g_context.lock);
 }
index 874e3a2..39daf5e 100644 (file)
@@ -254,7 +254,7 @@ static void CACentralDisconnect(CALEContext * context)
 {
     assert(context != NULL);
 
-    ca_mutex_lock(context->lock);
+    oc_mutex_lock(context->lock);
 
     for (GList * l = context->devices; l != NULL; l = l->next)
     {
@@ -280,7 +280,7 @@ static void CACentralDisconnect(CALEContext * context)
         }
     }
 
-    ca_mutex_unlock(context->lock);
+    oc_mutex_unlock(context->lock);
 }
 
 // -----------------------------------------------------------------------
@@ -295,7 +295,7 @@ CAResult_t CACentralStart(CALEContext * context)
       Synchronize access to the adapter information using the base
       context lock since we don't own the adapters.
      */
-    ca_mutex_lock(context->lock);
+    oc_mutex_lock(context->lock);
 
     /**
      * Start discovery on all detected adapters.
@@ -309,7 +309,7 @@ CAResult_t CACentralStart(CALEContext * context)
                    CACentralStartDiscoveryImpl,
                    &result);
 
-    ca_mutex_unlock(context->lock);
+    oc_mutex_unlock(context->lock);
 
     return result;
 }
@@ -343,14 +343,14 @@ CAResult_t CACentralStartDiscovery(CALEContext * context)
       Synchronize access to the adapter information using the base
       context lock since we don't own the adapters.
      */
-    ca_mutex_lock(context->lock);
+    oc_mutex_lock(context->lock);
 
     // Start discovery on all detected adapters.
     g_list_foreach(context->adapters,
                    CACentralStartDiscoveryImpl,
                    &result);
 
-    ca_mutex_unlock(context->lock);
+    oc_mutex_unlock(context->lock);
 
     return result;
 }
@@ -365,7 +365,7 @@ CAResult_t CACentralStopDiscovery(CALEContext * context)
       Synchronize access to the adapter information using the base
       context lock since we don't own the adapters.
      */
-    ca_mutex_lock(context->lock);
+    oc_mutex_lock(context->lock);
 
     // Stop discovery on all detected adapters.
     g_list_foreach(context->adapters,
@@ -376,7 +376,7 @@ CAResult_t CACentralStopDiscovery(CALEContext * context)
      * @todo Stop notifications on all response characteristics.
      */
 
-    ca_mutex_unlock(context->lock);
+    oc_mutex_unlock(context->lock);
 
     return result;
 }
@@ -431,14 +431,14 @@ bool CACentralConnectToAll(CALEContext * context)
 {
     bool connected = true;
 
-    ca_mutex_lock(context->lock);
+    oc_mutex_lock(context->lock);
 
     // Connect to the LE peripherals, if we're not already connected.
     g_list_foreach(context->devices,
                    CACentralConnectToDevice,
                    &connected);
 
-    ca_mutex_unlock(context->lock);
+    oc_mutex_unlock(context->lock);
 
     return connected;
 }
index 5972837..ea30505 100644 (file)
@@ -336,9 +336,9 @@ bool CAGattRequestCharacteristicInitialize(struct CAGattService * s,
         return false;
     }
 
-    ca_mutex_lock(context->lock);
+    oc_mutex_lock(context->lock);
     c->recv_info.on_packet_received = context->on_server_received_data;
-    ca_mutex_unlock(context->lock);
+    oc_mutex_unlock(context->lock);
 
     c->recv_info.peer    = peer;
     c->recv_info.context = context;
index 2888c7b..299f54e 100644 (file)
@@ -70,7 +70,7 @@ typedef struct _CAGattClientContext
     GHashTable * address_map;
 
     /// Mutex used to synchronize access to context fields.
-    ca_mutex lock;
+    oc_mutex lock;
 
 } CAGattClientContext;
 
@@ -108,7 +108,7 @@ static void CAGattClientOnCharacteristicPropertiesChanged(
     char const * const object_path =
         g_dbus_proxy_get_object_path(characteristic);
 
-    ca_mutex_lock(g_context.lock);
+    oc_mutex_lock(g_context.lock);
 
     char * const address =
         g_hash_table_lookup(g_context.address_map, object_path);
@@ -145,7 +145,7 @@ static void CAGattClientOnCharacteristicPropertiesChanged(
         }
     }
 
-    ca_mutex_unlock(g_context.lock);
+    oc_mutex_unlock(g_context.lock);
 }
 
 // ---------------------------------------------------------------------
@@ -483,7 +483,7 @@ static void CAGattClientOnDevicePropertiesChanged(
     {
         CALEContext * const context = user_data;
 
-        ca_mutex_lock(g_context.lock);
+        oc_mutex_lock(g_context.lock);
 
         CAGattClientSetupService(device,
                                  g_context.characteristic_map,
@@ -491,7 +491,7 @@ static void CAGattClientOnDevicePropertiesChanged(
                                  services_prop,
                                  context);
 
-        ca_mutex_unlock(g_context.lock);
+        oc_mutex_unlock(g_context.lock);
 
         g_variant_unref(services_prop);
     }
@@ -499,7 +499,7 @@ static void CAGattClientOnDevicePropertiesChanged(
 
 CAResult_t CAGattClientInitialize(CALEContext * context)
 {
-    g_context.lock = ca_mutex_new();
+    g_context.lock = oc_mutex_new();
 
     /*
       Map Bluetooth MAC address to OIC Transport Profile
@@ -521,7 +521,7 @@ CAResult_t CAGattClientInitialize(CALEContext * context)
                               OICFree,
                               OICFree);
 
-    ca_mutex_lock(context->lock);
+    oc_mutex_lock(context->lock);
 
     for (GList * l = context->devices; l != NULL; l = l->next)
     {
@@ -545,14 +545,14 @@ CAResult_t CAGattClientInitialize(CALEContext * context)
                                  context);
     }
 
-    ca_mutex_unlock(context->lock);
+    oc_mutex_unlock(context->lock);
 
-    ca_mutex_lock(g_context.lock);
+    oc_mutex_lock(g_context.lock);
 
     g_context.characteristic_map = characteristic_map;
     g_context.address_map = address_map;
 
-    ca_mutex_unlock(g_context.lock);
+    oc_mutex_unlock(g_context.lock);
 
     return CA_STATUS_OK;
 }
@@ -564,7 +564,7 @@ void CAGattClientDestroy()
         return;  // Initialization did not complete.
     }
 
-    ca_mutex_lock(g_context.lock);
+    oc_mutex_lock(g_context.lock);
 
     if (g_context.characteristic_map != NULL)
     {
@@ -578,9 +578,9 @@ void CAGattClientDestroy()
         g_context.address_map = NULL;
     }
 
-    ca_mutex_unlock(g_context.lock);
+    oc_mutex_unlock(g_context.lock);
 
-    ca_mutex_free(g_context.lock);
+    oc_mutex_free(g_context.lock);
     g_context.lock = NULL;
 
     /*
@@ -636,7 +636,7 @@ static CAResult_t CAGattClientSendDataImpl(GDBusProxy * characteristic,
 
         g_error_free(error);
 
-        ca_mutex_lock(context->lock);
+        oc_mutex_lock(context->lock);
 
         if (context->on_client_error != NULL)
         {
@@ -650,7 +650,7 @@ static CAResult_t CAGattClientSendDataImpl(GDBusProxy * characteristic,
                                      CA_STATUS_FAILED);
         }
 
-        ca_mutex_unlock(context->lock);
+        oc_mutex_unlock(context->lock);
 
         return CA_STATUS_FAILED;
     }
@@ -669,7 +669,7 @@ CAResult_t CAGattClientSendData(char const * address,
 
     CAResult_t result = CA_STATUS_FAILED;
 
-    ca_mutex_lock(g_context.lock);
+    oc_mutex_lock(g_context.lock);
 
     GDBusProxy * const characteristic =
         G_DBUS_PROXY(
@@ -691,7 +691,7 @@ CAResult_t CAGattClientSendData(char const * address,
                                       length,
                                       context);
 
-    ca_mutex_unlock(g_context.lock);
+    oc_mutex_unlock(g_context.lock);
 
     return result;
 }
@@ -704,12 +704,12 @@ CAResult_t CAGattClientSendDataToAll(uint8_t const * data,
 
     CAResult_t result = CA_STATUS_FAILED;
 
-    ca_mutex_lock(g_context.lock);
+    oc_mutex_lock(g_context.lock);
 
     if (g_context.characteristic_map == NULL)
     {
         // Remote OIC GATT service was not found prior to getting here.
-        ca_mutex_unlock(g_context.lock);
+        oc_mutex_unlock(g_context.lock);
         return result;
     }
 
@@ -737,7 +737,7 @@ CAResult_t CAGattClientSendDataToAll(uint8_t const * data,
         }
     }
 
-    ca_mutex_unlock(g_context.lock);
+    oc_mutex_unlock(g_context.lock);
 
     return result;
 }
index e0db333..2e734af 100644 (file)
@@ -20,7 +20,7 @@
 #define CA_BLE_LINUX_CONTEXT_H
 
 #include "caadapterinterface.h"
-#include "camutex.h"
+#include "octhread.h"
 #include "cathreadpool.h"
 #include "caleinterface.h"
 
@@ -149,7 +149,7 @@ typedef struct _CALEContext
     CABLEErrorHandleCallback on_server_error;
 
     /// Mutex used to synchronize access to context fields.
-    ca_mutex lock;
+    oc_mutex lock;
 
     /**
      * BlueZ adapter list initialization condition variable.
@@ -163,7 +163,7 @@ typedef struct _CALEContext
      *
      * @see @c GMainLoop documentation for further details.
      */
-    ca_cond condition;
+    oc_cond condition;
 
     /**
      * Semaphore that indicates completed start of the LE transport.
index 9966198..6cd91ac 100644 (file)
@@ -39,13 +39,13 @@ static CAPeripheralContext g_context = {
 
 static bool CAPeripheralCheckStarted()
 {
-    ca_mutex_lock(g_context.lock);
+    oc_mutex_lock(g_context.lock);
 
     bool const started =
         (g_context.event_loop != NULL
          && g_main_loop_is_running(g_context.event_loop));
 
-    ca_mutex_unlock(g_context.lock);
+    oc_mutex_unlock(g_context.lock);
 
     /**
      * @todo Fix potential TOCTOU race condition.  A peripheral could
@@ -59,11 +59,11 @@ static bool CAPeripheralCheckStarted()
 static bool CAPeripheralAdaptersFound(CALEContext * context)
 {
     // Check if BlueZ detected bluetooth hardware adapters.
-    ca_mutex_lock(context->lock);
+    oc_mutex_lock(context->lock);
 
     bool const found = (context->adapters != NULL);
 
-    ca_mutex_unlock(context->lock);
+    oc_mutex_unlock(context->lock);
 
     if (!found)
     {
@@ -162,7 +162,7 @@ static bool CAPeripheralRegisterGattServices(
 
     bool success = true;
 
-    ca_mutex_lock(context->lock);
+    oc_mutex_lock(context->lock);
 
     for (GList * l = context->gatt_services; l != NULL; l = l->next)
     {
@@ -209,7 +209,7 @@ static bool CAPeripheralRegisterGattServices(
         g_variant_unref(ret);
     }
 
-    ca_mutex_unlock(context->lock);
+    oc_mutex_unlock(context->lock);
 
     return success;
 }
@@ -224,7 +224,7 @@ static bool CAPeripheralRegisterAdvertisements(
       LE Advertisement Manager.
     */
 
-    ca_mutex_lock(context->lock);
+    oc_mutex_lock(context->lock);
 
     char const * const advertisement_path =
         g_dbus_interface_skeleton_get_object_path(
@@ -310,7 +310,7 @@ static bool CAPeripheralRegisterAdvertisements(
         success = true;
     }
 
-    ca_mutex_unlock(context->lock);
+    oc_mutex_unlock(context->lock);
 
     return success;
 }
@@ -383,14 +383,14 @@ static CAResult_t CAPeripheralSetDiscoverability(
       Synchronize access to the adapter information using the base
       context lock since we don't own the adapter_infos.
      */
-    ca_mutex_lock(context->lock);
+    oc_mutex_lock(context->lock);
 
     // Make all detected adapters discoverable.
     g_list_foreach(context->adapters,
                    discoverability_func,
                    &result);
 
-    ca_mutex_unlock(context->lock);
+    oc_mutex_unlock(context->lock);
 
     return result;
 }
@@ -447,9 +447,9 @@ static void CAPeripheralOnNameLost(GDBusConnection * connection,
  */
 static gboolean CAPeripheralEventLoopStarted(gpointer user_data)
 {
-    ca_cond const condition = user_data;
+    oc_cond const condition = user_data;
 
-    ca_cond_signal(condition);  // For service registration
+    oc_cond_signal(condition);  // For service registration
 
     return G_SOURCE_REMOVE;
 }
@@ -515,7 +515,7 @@ static void CAPeripheralStartEventLoop(void * data)
                 "manager interface.");
     }
 
-    ca_mutex_lock(g_context.lock);
+    oc_mutex_lock(g_context.lock);
 
     assert(g_context.event_loop == NULL);
     g_context.event_loop = event_loop;
@@ -542,7 +542,7 @@ static void CAPeripheralStartEventLoop(void * data)
                                 context->connection,
                                 advertising_managers);
 
-    ca_mutex_unlock(g_context.lock);
+    oc_mutex_unlock(g_context.lock);
 
     /*
       Add an idle handler that notifies a thread waiting for the
@@ -571,12 +571,12 @@ static void CAPeripheralStartEventLoop(void * data)
 
 static void CAPeripheralStopEventLoop(CAPeripheralContext * context)
 {
-    ca_mutex_lock(context->lock);
+    oc_mutex_lock(context->lock);
 
     GMainLoop * const event_loop = context->event_loop;
     context->event_loop = NULL;
 
-    ca_mutex_unlock(context->lock);
+    oc_mutex_unlock(context->lock);
 
     if (event_loop != NULL)
     {
@@ -596,14 +596,14 @@ static void CAPeripheralStopEventLoop(CAPeripheralContext * context)
 
 void CAPeripheralInitialize()
 {
-    g_context.lock      = ca_mutex_new();
-    g_context.condition = ca_cond_new();
+    g_context.lock      = oc_mutex_new();
+    g_context.condition = oc_cond_new();
 }
 
 void CAPeripheralFinalize()
 {
-    ca_cond_free(g_context.condition);
-    ca_mutex_free(g_context.lock);
+    oc_cond_free(g_context.condition);
+    oc_mutex_free(g_context.lock);
 }
 
 CAResult_t CAPeripheralStart(CALEContext * context)
@@ -634,7 +634,7 @@ CAResult_t CAPeripheralStart(CALEContext * context)
      */
     result = ca_thread_pool_add_task(context->server_thread_pool,
                                      CAPeripheralStartEventLoop,
-                                     context);
+                                     context, NULL);
 
     if (result != CA_STATUS_OK)
     {
@@ -653,21 +653,21 @@ CAResult_t CAPeripheralStart(CALEContext * context)
     static uint64_t const timeout =
         2 * MICROSECS_PER_SEC;  // Microseconds
 
-    ca_mutex_lock(g_context.lock);
+    oc_mutex_lock(g_context.lock);
 
     for (int i = 0;
          g_context.gatt_services == NULL && i < max_retries;
          ++i)
     {
-        if (ca_cond_wait_for(g_context.condition,
+        if (oc_cond_wait_for(g_context.condition,
                              g_context.lock,
-                             timeout) == CA_WAIT_SUCCESS)
+                             timeout) == OC_WAIT_SUCCESS)
         {
             result = CA_STATUS_OK;
         }
     }
 
-    ca_mutex_unlock(g_context.lock);
+    oc_mutex_unlock(g_context.lock);
 
     if (result != CA_STATUS_OK)
     {
@@ -718,7 +718,7 @@ CAResult_t CAPeripheralStop()
 
     CAPeripheralStopEventLoop(&g_context);
 
-    ca_mutex_lock(g_context.lock);
+    oc_mutex_lock(g_context.lock);
 
     guint const owner_id = g_context.owner_id;
     g_context.owner_id = 0;
@@ -728,7 +728,7 @@ CAResult_t CAPeripheralStop()
 
     g_context.base = NULL;
 
-    ca_mutex_unlock(g_context.lock);
+    oc_mutex_unlock(g_context.lock);
 
     CALEAdvertisementDestroy(&g_context.advertisement);
 
@@ -741,9 +741,9 @@ CAResult_t CAPeripheralStop()
 
 void CAPeripheralForEachService(GFunc func, void * user_data)
 {
-    ca_mutex_lock(g_context.lock);
+    oc_mutex_lock(g_context.lock);
 
     g_list_foreach(g_context.gatt_services, func, user_data);
 
-    ca_mutex_unlock(g_context.lock);
+    oc_mutex_unlock(g_context.lock);
 }
index 419edb4..2333cb9 100644 (file)
@@ -78,7 +78,7 @@ typedef struct _CAPeripheralContext
     GMainLoop * event_loop;
 
     /// Mutex used to synchronize access to context fields.
-    ca_mutex lock;
+    oc_mutex lock;
 
     /**
      * Service registration condition variable.
@@ -90,7 +90,7 @@ typedef struct _CAPeripheralContext
      *
      * @see @c GMainLoop documentation for further details.
      */
-    ca_cond condition;
+    oc_cond condition;
 
 } CAPeripheralContext;
 
index c50ba1b..921fbd6 100644 (file)
@@ -51,7 +51,7 @@ bool CAGattRecv(CAGattRecvInfo * info,
 {
     uint32_t sent_length = 0;
 
-    ca_mutex_lock(info->context->lock);
+    oc_mutex_lock(info->context->lock);
 
     bool const success =
         info->on_packet_received(info->peer,
@@ -59,7 +59,7 @@ bool CAGattRecv(CAGattRecvInfo * info,
                                  length,
                                  &sent_length) == CA_STATUS_OK;
 
-    ca_mutex_unlock(info->context->lock);
+    oc_mutex_unlock(info->context->lock);
 
     return success && length == sent_length;
 }
index ac0f8f3..50148bd 100644 (file)
@@ -44,11 +44,11 @@ bool CAGetBlueZManagedObjectProxies(GList ** proxies,
     */
     bool success = true;
 
-    ca_mutex_lock(context->lock);
+    oc_mutex_lock(context->lock);
 
     if (context->objects == NULL)
     {
-        ca_mutex_unlock(context->lock);
+        oc_mutex_unlock(context->lock);
         return success;
     }
 
@@ -84,7 +84,7 @@ bool CAGetBlueZManagedObjectProxies(GList ** proxies,
         }
     }
 
-    ca_mutex_unlock(context->lock);
+    oc_mutex_unlock(context->lock);
 
     return success;
 }
index 4a2cb7a..01c8248 100644 (file)
@@ -6,13 +6,35 @@ Import('env', 'src_dir')
 import os.path
 
 root_dir = os.pardir
+division = env.get('BLE_DIVISION')
+tizen30 = env.get('BLE_TIZEN_30')
+
 env.PrependUnique(CPPPATH = [ os.path.join(src_dir, 'tizen')])
 
 env.ParseConfig("pkg-config --cflags --libs capi-network-bluetooth")
 
-src_files = [ 'caleclient.c',
-              'caleserver.c',
-              'caleutil.c',
-              'calenwmonitor.c']
+if 'MCD' in division:
+    env.AppendUnique(CPPDEFINES = ['BLE_MCD'])
+    print "BLE for MCD"
+
+if tizen30 == 'True':
+    env.AppendUnique(CPPDEFINES = ['BLE_TIZEN_30'])
+    print "Build using Tizen 3.0 BLE API"
+
+if 'MCD' in division:
+    src_files = [ 'caleclient.c',
+               'caleserver_mcd.c',
+               'caleutil.c',
+               'calenwmonitor.c']
+elif 'VD' in division:
+    src_files = [ 'caleclient.c',
+               'caleserver_vd.c',
+               'caleutil.c',
+               'calenwmonitor_vd.c']
+else:
+    src_files = [ 'caleclient.c',
+               'caleserver.c',
+               'caleutil.c',
+               'calenwmonitor.c']
 
 Return('src_files')
index f402124..16282b3 100644 (file)
@@ -30,7 +30,7 @@
 #include <pthread.h>
 #include <gio/gio.h>
 
-#include "camutex.h"
+#include "octhread.h"
 #include "uarraylist.h"
 #include "caqueueingthread.h"
 #include "caadapterutils.h"
@@ -61,7 +61,7 @@ static u_arraylist_t *g_multicastDataList = NULL;
 /**
  * Mutex to synchronize the access to Pending multicast data list.
  */
-static ca_mutex g_multicastDataListMutex = NULL;
+static oc_mutex g_multicastDataListMutex = NULL;
 
 /**
  * List of devices discovered.
@@ -71,17 +71,17 @@ static u_arraylist_t *g_deviceDiscoveredList = NULL;
 /**
  * Mutex to synchronize the access to discovered devices list.
  */
-static ca_mutex g_deviceDiscoveredListMutex = NULL;
+static oc_mutex g_deviceDiscoveredListMutex = NULL;
 
 /**
  * Condition to start the timer for scanning.
  */
-static ca_cond g_startTimerCond = NULL;
+static oc_cond g_startTimerCond = NULL;
 
 /**
  * Condition for scanning Time interval.
  */
-static ca_cond g_scanningTimeCond = NULL;
+static oc_cond g_scanningTimeCond = NULL;
 
 /**
  * This contains the list of OIC services a client connect tot.
@@ -91,7 +91,7 @@ static LEServerInfoList *g_LEServerList = NULL;
 /**
  * Mutex to synchronize access to BleServiceList.
  */
-static ca_mutex g_LEServerListMutex = NULL;
+static oc_mutex g_LEServerListMutex = NULL;
 
 /**
  * Boolean variable to keep the state of the GATT Client.
@@ -102,34 +102,34 @@ static bool g_isLEGattClientStarted = false;
  * Mutex to synchronize access to the requestResponse callback to be called
  * when the data needs to be sent from GATTClient.
  */
-static ca_mutex g_LEReqRespClientCbMutex = NULL;
+static oc_mutex g_LEReqRespClientCbMutex = NULL;
 
 /**
  * Mutex to synchronize access to the requestResponse callback to be called
  * when the data needs to be sent from GATTClient.
  */
-static ca_mutex g_LEClientConnectMutex = NULL;
+static oc_mutex g_LEClientConnectMutex = NULL;
 
 /**
  * Mutex to synchronize the calls to be done to the platform from GATTClient
  * interfaces from different threads.
  */
-static ca_mutex g_LEClientStateMutex = NULL;
+static oc_mutex g_LEClientStateMutex = NULL;
 
 /**
  * Mutex to synchronize the task to be pushed to thread pool.
  */
-static ca_mutex g_LEClientThreadPoolMutex = NULL;
+static oc_mutex g_LEClientThreadPoolMutex = NULL;
 
 /**
  * Mutex to synchronize the task to write characteristic one packet after another.
  */
-static ca_mutex g_threadWriteCharacteristicMutex = NULL;
+static oc_mutex g_threadWriteCharacteristicMutex = NULL;
 
 /**
  * Condition for Writing characteristic.
  */
-static ca_cond g_threadWriteCharacteristicCond = NULL;
+static oc_cond g_threadWriteCharacteristicCond = NULL;
 
 /**
  * Flag to check status of write characteristic.
@@ -157,29 +157,74 @@ static GMainLoop *g_eventLoop = NULL;
  */
 static ca_thread_pool_t g_LEClientThreadPool = NULL;
 
-bt_scan_filter_h g_scanFilter = NULL;
+bool CALEIsHaveService(bt_adapter_le_device_scan_result_info_s* scanInfo, char* service_uuid)
+{
+    bool ret = false;
+    char **uuids = NULL;
+    int count = 0;
+    int result = 0;
+
+    // For arduino servers, scan response will give the UUIDs advertised.
+    result = bt_adapter_le_get_scan_result_service_uuids(scanInfo,
+                                                         BT_ADAPTER_LE_PACKET_SCAN_RESPONSE,
+                                                         &uuids, &count);
+    if (result == BT_ERROR_NONE && NULL != uuids)
+    {
+        int i;
+        for (i = 0; i < count; i++)
+        {
+            if (0 == strcasecmp(uuids[i], service_uuid))
+            {
+                OIC_LOG_V(DEBUG, TAG, "Service[%s] Found in %s",
+                          uuids[i], scanInfo->remote_address);
+                ret = true;
+            }
+            OICFree(uuids[i]);
+        }
+        OICFree(uuids);
+    }
+
+    // For android/tizen servers, advertising packet will give the UUIDs.
+    result = bt_adapter_le_get_scan_result_service_uuids(scanInfo,
+                                                         BT_ADAPTER_LE_PACKET_ADVERTISING,
+                                                         &uuids, &count);
+    if (result == BT_ERROR_NONE && NULL != uuids)
+    {
+        int i;
+        for (i = 0; i < count; i++)
+        {
+            if (0 == strcasecmp(uuids[i], service_uuid))
+            {
+                OIC_LOG_V(DEBUG, TAG, "Service[%s] Found in %s",
+                          uuids[i], scanInfo->remote_address);
+                ret = true;
+            }
+            OICFree(uuids[i]);
+        }
+        OICFree(uuids);
+    }
+
+    return ret;
+}
 
 bool CALEIsDeviceDiscovered(const char * address)
 {
-    OIC_LOG(DEBUG, TAG, "IN");
     if (g_deviceDiscoveredList)
     {
-        ca_mutex_lock(g_deviceDiscoveredListMutex);
+        oc_mutex_lock(g_deviceDiscoveredListMutex);
         uint32_t arrayLength = u_arraylist_length(g_deviceDiscoveredList);
-        for (int i = 0; i < arrayLength; i++)
+        for (uint32_t i = 0; i < arrayLength; i++)
         {
             char *deviceAddr = u_arraylist_get(g_deviceDiscoveredList, i);
             if (0 == strcasecmp(deviceAddr, address))
             {
-                OIC_LOG(DEBUG, TAG, "Device Found");
-                ca_mutex_unlock(g_deviceDiscoveredListMutex);
+                oc_mutex_unlock(g_deviceDiscoveredListMutex);
                 return true;
             }
 
         }
-        ca_mutex_unlock(g_deviceDiscoveredListMutex);
+        oc_mutex_unlock(g_deviceDiscoveredListMutex);
     }
-    OIC_LOG(DEBUG, TAG, "OUT");
     return false;
 }
 
@@ -190,20 +235,20 @@ void CALEGattCharacteristicChangedCb(bt_gatt_h characteristic,
     OIC_LOG(DEBUG, TAG, "IN");
     OIC_LOG_V(DEBUG, TAG, "Changed characteristic value length [%d]", valueLen);
 
-    ca_mutex_lock(g_LEReqRespClientCbMutex);
+    oc_mutex_lock(g_LEReqRespClientCbMutex);
     if (NULL == g_LEClientDataReceivedCallback)
     {
         OIC_LOG(ERROR, TAG, "Request response callback is not set");
-        ca_mutex_unlock(g_LEReqRespClientCbMutex);
+        oc_mutex_unlock(g_LEReqRespClientCbMutex);
         return;
     }
 
     uint32_t sentLength = 0;
     g_LEClientDataReceivedCallback(userData, (uint8_t *)value, valueLen, &sentLength);
 
-    OIC_LOG_V(DEBUG, TAG, "Sent data Length is %d", sentLength);
+    OIC_LOG_V(DEBUG, TAG, "Recv data Length is %d", sentLength);
 
-    ca_mutex_unlock(g_LEReqRespClientCbMutex);
+    oc_mutex_unlock(g_LEReqRespClientCbMutex);
 
     OIC_LOG(DEBUG, TAG, "OUT");
 }
@@ -214,16 +259,22 @@ void CALEGattCharacteristicWriteCb(int result, bt_gatt_h reqHandle, void *userDa
 
     if (BT_ERROR_NONE != result)
     {
+        CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
+                           false, "writeChar failure");
+
         OIC_LOG(ERROR, TAG, "Write failed Need Retry ");
         //Need to Implement retry mechanism
     }
     else
     {
-        ca_mutex_lock(g_threadWriteCharacteristicMutex);
+        oc_mutex_lock(g_threadWriteCharacteristicMutex);
         OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
         g_isSignalSetFlag = true;
-        ca_cond_signal(g_threadWriteCharacteristicCond);
-        ca_mutex_unlock(g_threadWriteCharacteristicMutex);
+        oc_cond_signal(g_threadWriteCharacteristicCond);
+        oc_mutex_unlock(g_threadWriteCharacteristicMutex);
+
+        CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
+                           true, "writeChar success");
     }
 
     OIC_LOG(DEBUG, TAG, "OUT ");
@@ -242,14 +293,14 @@ void CALEGattConnectionStateChanged(bool connected, const char *remoteAddress)
         OIC_LOG(ERROR, TAG, "CALEGattStartDeviceDiscovery Failed");
     }
     // Signal the start timer.
-    ca_cond_signal(g_scanningTimeCond);
+    oc_cond_signal(g_scanningTimeCond);
 
     if (!connected)
     {
         OIC_LOG_V(DEBUG, TAG, "DisConnected from [%s] ", remoteAddress);
-        ca_mutex_lock(g_LEServerListMutex);
+        oc_mutex_lock(g_LEServerListMutex);
         CARemoveLEServerInfoFromList(&g_LEServerList, remoteAddress);
-        ca_mutex_unlock(g_LEServerListMutex);
+        oc_mutex_unlock(g_LEServerListMutex);
     }
     else
     {
@@ -262,23 +313,23 @@ void CALEGattConnectionStateChanged(bool connected, const char *remoteAddress)
             return;
         }
 
-        ca_mutex_lock(g_LEClientThreadPoolMutex);
+        oc_mutex_lock(g_LEClientThreadPoolMutex);
         if (NULL == g_LEClientThreadPool)
         {
             OIC_LOG(ERROR, TAG, "g_LEClientThreadPool is NULL");
             OICFree(addr);
-            ca_mutex_unlock(g_LEClientThreadPoolMutex);
+            oc_mutex_unlock(g_LEClientThreadPoolMutex);
             return;
         }
 
         ret = ca_thread_pool_add_task(g_LEClientThreadPool, CADiscoverLEServicesThread,
-                                      addr);
+                                      addr, NULL);
         if (CA_STATUS_OK != ret)
         {
             OIC_LOG_V(ERROR, TAG, "ca_thread_pool_add_task failed with ret [%d]", ret);
             OICFree(addr);
         }
-        ca_mutex_unlock(g_LEClientThreadPoolMutex);
+        oc_mutex_unlock(g_LEClientThreadPoolMutex);
     }
     OIC_LOG(DEBUG, TAG, "OUT");
 }
@@ -305,26 +356,30 @@ void CALEAdapterScanResultCb(int result, bt_adapter_le_device_scan_result_info_s
         return;
     }
 
-    // Stop the scan before invoking bt_gatt_connect().
-    CALEGattStopDeviceScanning();
-
-    ca_mutex_lock(g_deviceDiscoveredListMutex);
-    // Add the the device Discovered list.
-    if (NULL == g_deviceDiscoveredList)
+    if (!CALEIsHaveService(scanInfo, CA_GATT_SERVICE_UUID))
     {
-        g_deviceDiscoveredList = u_arraylist_create();
-    }
+        oc_mutex_lock(g_deviceDiscoveredListMutex);
+        // Add the the device Discovered list.
+        if (NULL == g_deviceDiscoveredList)
+        {
+            g_deviceDiscoveredList = u_arraylist_create();
+        }
+        char *deviceAddr = OICStrdup(scanInfo->remote_address);
+        if (NULL == deviceAddr)
+        {
+            OIC_LOG_V(ERROR, TAG, "Device address is NULL");
+            oc_mutex_unlock(g_deviceDiscoveredListMutex);
+            return;
+        }
 
-    char *deviceAddr = OICStrdup(scanInfo->remote_address);
-    if (NULL == deviceAddr)
-    {
-        OIC_LOG_V(ERROR, TAG, "Device address is NULL");
-        ca_mutex_unlock(g_deviceDiscoveredListMutex);
+        u_arraylist_add(g_deviceDiscoveredList, (void *) deviceAddr);
+        oc_mutex_unlock(g_deviceDiscoveredListMutex);
+        OIC_LOG_V(INFO, TAG, "Device[%s] is don't have service", scanInfo->remote_address);
         return;
     }
 
-    u_arraylist_add(g_deviceDiscoveredList, (void *) deviceAddr);
-    ca_mutex_unlock(g_deviceDiscoveredListMutex);
+    // Stop the scan before invoking bt_gatt_connect().
+    CALEGattStopDeviceScanning();
 
     size_t len = strlen(scanInfo->remote_address);
 
@@ -336,23 +391,23 @@ void CALEAdapterScanResultCb(int result, bt_adapter_le_device_scan_result_info_s
     OIC_LOG_V(DEBUG, TAG,
               "Trying to do Gatt connection to [%s]", addr);
 
-    ca_mutex_lock(g_LEClientThreadPoolMutex);
+    oc_mutex_lock(g_LEClientThreadPoolMutex);
     if (NULL == g_LEClientThreadPool)
     {
         OIC_LOG(ERROR, TAG, "g_LEClientThreadPool is NULL");
         OICFree(addr);
-        ca_mutex_unlock(g_LEClientThreadPoolMutex);
+        oc_mutex_unlock(g_LEClientThreadPoolMutex);
         return;
     }
 
-    CAResult_t res = ca_thread_pool_add_task(g_LEClientThreadPool, CAGattConnectThread, addr);
+    CAResult_t res = ca_thread_pool_add_task(g_LEClientThreadPool, CAGattConnectThread, addr, NULL);
     if (CA_STATUS_OK != res)
     {
         OIC_LOG_V(ERROR, TAG,
                   "ca_thread_pool_add_task failed with ret [%d]", res);
         OICFree(addr);
     }
-    ca_mutex_unlock(g_LEClientThreadPoolMutex);
+    oc_mutex_unlock(g_LEClientThreadPoolMutex);
     OIC_LOG(DEBUG, TAG, "OUT");
 }
 
@@ -360,9 +415,9 @@ void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
-    ca_mutex_lock(g_LEClientThreadPoolMutex);
+    oc_mutex_lock(g_LEClientThreadPoolMutex);
     g_LEClientThreadPool = handle;
-    ca_mutex_unlock(g_LEClientThreadPoolMutex);
+    oc_mutex_unlock(g_LEClientThreadPoolMutex);
 
     OIC_LOG(DEBUG, TAG, "OUT");
 }
@@ -371,11 +426,11 @@ void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
-    ca_mutex_lock(g_LEReqRespClientCbMutex);
+    oc_mutex_lock(g_LEReqRespClientCbMutex);
 
     g_LEClientDataReceivedCallback = callback;
 
-    ca_mutex_unlock(g_LEReqRespClientCbMutex);
+    oc_mutex_unlock(g_LEReqRespClientCbMutex);
 
     OIC_LOG(DEBUG, TAG, "OUT");
 }
@@ -389,11 +444,11 @@ CAResult_t CAStartLEGattClient()
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
-    ca_mutex_lock(g_LEClientStateMutex);
+    oc_mutex_lock(g_LEClientStateMutex);
     if (true  == g_isLEGattClientStarted)
     {
         OIC_LOG(ERROR, TAG, "Gatt Client is already running!!");
-        ca_mutex_unlock(g_LEClientStateMutex);
+        oc_mutex_unlock(g_LEClientStateMutex);
         return CA_STATUS_FAILED;
     }
 
@@ -401,33 +456,33 @@ CAResult_t CAStartLEGattClient()
     if (CA_STATUS_OK != result)
     {
         OIC_LOG(ERROR, TAG, "CABleGattSetCallbacks Failed");
-        ca_mutex_unlock(g_LEClientStateMutex);
+        oc_mutex_unlock(g_LEClientStateMutex);
         CATerminateLEGattClient();
         return CA_STATUS_FAILED;
     }
 
     g_isLEGattClientStarted = true;
-    ca_mutex_unlock(g_LEClientStateMutex);
+    oc_mutex_unlock(g_LEClientStateMutex);
 
-    ca_mutex_lock(g_LEClientThreadPoolMutex);
+    oc_mutex_lock(g_LEClientThreadPoolMutex);
     if (NULL == g_LEClientThreadPool)
     {
         OIC_LOG(ERROR, TAG, "gBleServerThreadPool is NULL");
         CATerminateGattClientMutexVariables();
-        ca_mutex_unlock(g_LEClientThreadPoolMutex);
+        oc_mutex_unlock(g_LEClientThreadPoolMutex);
         return CA_STATUS_FAILED;
     }
 
     result = ca_thread_pool_add_task(g_LEClientThreadPool, CAStartTimerThread,
-                                     NULL);
+                                     NULL, NULL);
     if (CA_STATUS_OK != result)
     {
         OIC_LOG(ERROR, TAG, "ca_thread_pool_add_task failed");
         CATerminateGattClientMutexVariables();
-        ca_mutex_unlock(g_LEClientThreadPoolMutex);
+        oc_mutex_unlock(g_LEClientThreadPoolMutex);
         return CA_STATUS_FAILED;
     }
-    ca_mutex_unlock(g_LEClientThreadPoolMutex);
+    oc_mutex_unlock(g_LEClientThreadPoolMutex);
 
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
@@ -438,19 +493,24 @@ void CAStartTimerThread(void *data)
     OIC_LOG(DEBUG, TAG, "IN");
     while (g_isLEGattClientStarted)
     {
-        ca_mutex_lock(g_multicastDataListMutex);
+        oc_mutex_lock(g_multicastDataListMutex);
         if (!g_isMulticastInProgress)
         {
             OIC_LOG(DEBUG, TAG, "waiting....");
-            ca_cond_wait(g_startTimerCond, g_multicastDataListMutex);
+            oc_cond_wait(g_startTimerCond, g_multicastDataListMutex);
             OIC_LOG(DEBUG, TAG, "Wake up");
             g_isMulticastInProgress = true;
+
+            if (!g_isLEGattClientStarted)
+            {
+               break;
+            }
         }
 
         // Timed conditional wait for stopping the scan.
-        CAWaitResult_t ret = ca_cond_wait_for(g_scanningTimeCond, g_multicastDataListMutex,
+        OCWaitResult_t ret = oc_cond_wait_for(g_scanningTimeCond, g_multicastDataListMutex,
                                               TIMEOUT);
-        if (CA_WAIT_TIMEDOUT == ret)
+        if (OC_WAIT_TIMEDOUT == ret)
         {
             OIC_LOG(DEBUG, TAG, "Scan is timed Out");
             // Call stop scan.
@@ -460,14 +520,14 @@ void CAStartTimerThread(void *data)
             u_arraylist_destroy(g_multicastDataList);
             g_multicastDataList = NULL;
 
-            ca_mutex_lock(g_deviceDiscoveredListMutex);
+            oc_mutex_lock(g_deviceDiscoveredListMutex);
             u_arraylist_destroy(g_deviceDiscoveredList);
             g_deviceDiscoveredList = NULL;
-            ca_mutex_unlock(g_deviceDiscoveredListMutex);
+            oc_mutex_unlock(g_deviceDiscoveredListMutex);
 
             g_isMulticastInProgress = false;
         }
-        ca_mutex_unlock(g_multicastDataListMutex);
+        oc_mutex_unlock(g_multicastDataListMutex);
     }
 
     OIC_LOG(DEBUG, TAG, "OUT");
@@ -477,12 +537,12 @@ void CAStopLEGattClient()
 {
     OIC_LOG(DEBUG,  TAG, "IN");
 
-    ca_mutex_lock(g_LEClientStateMutex);
+    oc_mutex_lock(g_LEClientStateMutex);
 
     if (false == g_isLEGattClientStarted)
     {
         OIC_LOG(ERROR, TAG, "Gatt Client is not running to stop");
-        ca_mutex_unlock(g_LEClientStateMutex);
+        oc_mutex_unlock(g_LEClientStateMutex);
         return;
     }
 
@@ -490,37 +550,39 @@ void CAStopLEGattClient()
 
     CALEGattStopDeviceScanning();
 
+    // this flag should be set before signal g_startTimerCond.
+    // since scan thread can be stopped through this flag.
     g_isLEGattClientStarted = false;
 
     // Signal the conditions waiting in Start timer.
-    ca_cond_signal(g_startTimerCond);
-    ca_cond_signal(g_scanningTimeCond);
+    oc_cond_signal(g_startTimerCond);
+    oc_cond_signal(g_scanningTimeCond);
 
     // Destroy the multicast data list and device list if not empty.
     if (NULL != g_multicastDataList)
     {
-        ca_mutex_lock(g_multicastDataListMutex);
+        oc_mutex_lock(g_multicastDataListMutex);
         u_arraylist_destroy(g_multicastDataList);
         g_multicastDataList = NULL;
-        ca_mutex_unlock(g_multicastDataListMutex);
+        oc_mutex_unlock(g_multicastDataListMutex);
     }
 
     if (NULL != g_deviceDiscoveredList)
     {
-        ca_mutex_lock(g_deviceDiscoveredListMutex);
+        oc_mutex_lock(g_deviceDiscoveredListMutex);
         u_arraylist_destroy(g_deviceDiscoveredList);
         g_deviceDiscoveredList = NULL;
-        ca_mutex_unlock(g_deviceDiscoveredListMutex);
+        oc_mutex_unlock(g_deviceDiscoveredListMutex);
     }
 
-    ca_mutex_lock(g_LEServerListMutex);
+    oc_mutex_lock(g_LEServerListMutex);
     CAFreeLEServerList(g_LEServerList);
     g_LEServerList = NULL;
-    ca_mutex_unlock(g_LEServerListMutex);
+    oc_mutex_unlock(g_LEServerListMutex);
 
-    ca_mutex_lock(g_threadWriteCharacteristicMutex);
-    ca_cond_signal(g_threadWriteCharacteristicCond);
-    ca_mutex_unlock(g_threadWriteCharacteristicMutex);
+    oc_mutex_lock(g_threadWriteCharacteristicMutex);
+    oc_cond_signal(g_threadWriteCharacteristicCond);
+    oc_mutex_unlock(g_threadWriteCharacteristicMutex);
 
     CAResetRegisteredServiceCount();
 
@@ -543,7 +605,7 @@ void CAStopLEGattClient()
         OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
     }
 
-    ca_mutex_unlock(g_LEClientStateMutex);
+    oc_mutex_unlock(g_LEClientStateMutex);
 
     OIC_LOG(DEBUG,  TAG, "OUT");
 }
@@ -575,110 +637,110 @@ CAResult_t CAInitGattClientMutexVariables()
     OIC_LOG(DEBUG,  TAG, "IN");
     if (NULL == g_LEClientStateMutex)
     {
-        g_LEClientStateMutex = ca_mutex_new();
+        g_LEClientStateMutex = oc_mutex_new();
         if (NULL == g_LEClientStateMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_LEServerListMutex)
     {
-        g_LEServerListMutex = ca_mutex_new();
+        g_LEServerListMutex = oc_mutex_new();
         if (NULL == g_LEServerListMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_LEReqRespClientCbMutex)
     {
-        g_LEReqRespClientCbMutex = ca_mutex_new();
+        g_LEReqRespClientCbMutex = oc_mutex_new();
         if (NULL == g_LEReqRespClientCbMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_LEClientThreadPoolMutex)
     {
-        g_LEClientThreadPoolMutex = ca_mutex_new();
+        g_LEClientThreadPoolMutex = oc_mutex_new();
         if (NULL == g_LEClientThreadPoolMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_LEClientConnectMutex)
     {
-        g_LEClientConnectMutex = ca_mutex_new();
+        g_LEClientConnectMutex = oc_mutex_new();
         if (NULL == g_LEClientConnectMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_multicastDataListMutex)
     {
-        g_multicastDataListMutex = ca_mutex_new();
+        g_multicastDataListMutex = oc_mutex_new();
         if (NULL == g_multicastDataListMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_deviceDiscoveredListMutex)
     {
-        g_deviceDiscoveredListMutex = ca_mutex_new();
+        g_deviceDiscoveredListMutex = oc_mutex_new();
         if (NULL == g_deviceDiscoveredListMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_threadWriteCharacteristicMutex)
     {
-        g_threadWriteCharacteristicMutex = ca_mutex_new();
+        g_threadWriteCharacteristicMutex = oc_mutex_new();
         if (NULL == g_threadWriteCharacteristicMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_startTimerCond)
     {
-        g_startTimerCond = ca_cond_new();
+        g_startTimerCond = oc_cond_new();
         if (NULL == g_startTimerCond)
         {
-            OIC_LOG(ERROR, TAG, "ca_cond_new failed");
+            OIC_LOG(ERROR, TAG, "oc_cond_new failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_scanningTimeCond)
     {
-        g_scanningTimeCond = ca_cond_new();
+        g_scanningTimeCond = oc_cond_new();
         if (NULL == g_scanningTimeCond)
         {
-            OIC_LOG(ERROR, TAG, "ca_cond_new failed");
+            OIC_LOG(ERROR, TAG, "oc_cond_new failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_threadWriteCharacteristicCond)
     {
-        g_threadWriteCharacteristicCond = ca_cond_new();
+        g_threadWriteCharacteristicCond = oc_cond_new();
         if (NULL == g_threadWriteCharacteristicCond)
         {
-            OIC_LOG(ERROR, TAG, "ca_cond_new failed");
+            OIC_LOG(ERROR, TAG, "oc_cond_new failed");
             return CA_STATUS_FAILED;
         }
     }
@@ -691,37 +753,37 @@ void CATerminateGattClientMutexVariables()
 {
     OIC_LOG(DEBUG,  TAG, "IN");
 
-    ca_mutex_free(g_LEClientStateMutex);
+    oc_mutex_free(g_LEClientStateMutex);
     g_LEClientStateMutex = NULL;
 
-    ca_mutex_free(g_LEServerListMutex);
+    oc_mutex_free(g_LEServerListMutex);
     g_LEServerListMutex = NULL;
 
-    ca_mutex_free(g_LEReqRespClientCbMutex);
+    oc_mutex_free(g_LEReqRespClientCbMutex);
     g_LEReqRespClientCbMutex = NULL;
 
-    ca_mutex_free(g_LEClientConnectMutex);
+    oc_mutex_free(g_LEClientConnectMutex);
     g_LEClientConnectMutex = NULL;
 
-    ca_mutex_free(g_LEClientThreadPoolMutex);
+    oc_mutex_free(g_LEClientThreadPoolMutex);
     g_LEClientThreadPoolMutex = NULL;
 
-    ca_mutex_free(g_multicastDataListMutex);
+    oc_mutex_free(g_multicastDataListMutex);
     g_multicastDataListMutex = NULL;
 
-    ca_mutex_free(g_deviceDiscoveredListMutex);
+    oc_mutex_free(g_deviceDiscoveredListMutex);
     g_deviceDiscoveredListMutex = NULL;
 
-    ca_mutex_free(g_threadWriteCharacteristicMutex);
+    oc_mutex_free(g_threadWriteCharacteristicMutex);
     g_threadWriteCharacteristicMutex = NULL;
 
-    ca_cond_free(g_startTimerCond);
+    oc_cond_free(g_startTimerCond);
     g_startTimerCond = NULL;
 
-    ca_cond_free(g_scanningTimeCond);
+    oc_cond_free(g_scanningTimeCond);
     g_scanningTimeCond = NULL;
 
-    ca_cond_free(g_threadWriteCharacteristicCond);
+    oc_cond_free(g_threadWriteCharacteristicCond);
     g_threadWriteCharacteristicCond = NULL;
     g_isSignalSetFlag = false;
 
@@ -812,14 +874,14 @@ CAResult_t CALEGattConnect(const char *remoteAddress)
     VERIFY_NON_NULL_RET(remoteAddress, TAG,
                         "remote address is NULL", CA_STATUS_FAILED);
 
-    ca_mutex_lock(g_LEClientConnectMutex);
+    oc_mutex_lock(g_LEClientConnectMutex);
     bool isConnected = false;
     int ret = bt_device_is_profile_connected(remoteAddress, BT_PROFILE_GATT, &isConnected);
     if (BT_ERROR_NONE != ret)
     {
         OIC_LOG_V(ERROR, TAG, "bt_device_is_profile_connected Failed with ret value [%s] ",
                   CALEGetErrorMsg(ret));
-        ca_mutex_unlock(g_LEClientConnectMutex);
+        oc_mutex_unlock(g_LEClientConnectMutex);
         return CA_STATUS_FAILED;
     }
 
@@ -832,7 +894,7 @@ CAResult_t CALEGattConnect(const char *remoteAddress)
         {
             OIC_LOG_V(ERROR, TAG, "bt_gatt_connect Failed with ret value [%s] ",
                       CALEGetErrorMsg(ret));
-            ca_mutex_unlock(g_LEClientConnectMutex);
+            oc_mutex_unlock(g_LEClientConnectMutex);
             return CA_STATUS_FAILED;
         }
     }
@@ -844,30 +906,30 @@ CAResult_t CALEGattConnect(const char *remoteAddress)
         if (NULL == addr)
         {
             OIC_LOG(ERROR, TAG, "addr is NULL");
-            ca_mutex_unlock(g_LEClientConnectMutex);
+            oc_mutex_unlock(g_LEClientConnectMutex);
             return CA_STATUS_FAILED;
         }
 
-        ca_mutex_lock(g_LEClientThreadPoolMutex);
+        oc_mutex_lock(g_LEClientThreadPoolMutex);
         if (NULL == g_LEClientThreadPool)
         {
             OIC_LOG(ERROR, TAG, "g_LEClientThreadPool is NULL");
             OICFree(addr);
-            ca_mutex_unlock(g_LEClientThreadPoolMutex);
-            ca_mutex_unlock(g_LEClientConnectMutex);
+            oc_mutex_unlock(g_LEClientThreadPoolMutex);
+            oc_mutex_unlock(g_LEClientConnectMutex);
             return CA_STATUS_FAILED;
         }
 
         result = ca_thread_pool_add_task(g_LEClientThreadPool, CADiscoverLEServicesThread,
-                                      addr);
+                                         addr, NULL);
         if (CA_STATUS_OK != result)
         {
             OIC_LOG_V(ERROR, TAG, "ca_thread_pool_add_task failed with ret [%d]", result);
             OICFree(addr);
         }
-        ca_mutex_unlock(g_LEClientThreadPoolMutex);
+        oc_mutex_unlock(g_LEClientThreadPoolMutex);
     }
-    ca_mutex_unlock(g_LEClientConnectMutex);
+    oc_mutex_unlock(g_LEClientConnectMutex);
 
     OIC_LOG(DEBUG, TAG, "OUT");
     return result;
@@ -918,13 +980,50 @@ CAResult_t CALEGattDiscoverServices(const char *remoteAddress)
     VERIFY_NON_NULL_RET(remoteAddress, TAG,
                         "remote address is NULL", CA_STATUS_FAILED);
 
+    LEServerInfo *leServerInfo = NULL;
+    CAResult_t result =  CA_STATUS_FAILED;
+
+    oc_mutex_lock(g_LEServerListMutex);
+    result = CAGetLEServerInfo(g_LEServerList, remoteAddress, &leServerInfo);
+    oc_mutex_unlock(g_LEServerListMutex);
+
+    if (CA_STATUS_OK == result)
+    {
+        OIC_LOG_V(INFO, TAG, "Device[%s] is already discovered", leServerInfo->remoteAddress);
+
+        // Send the data of pending multicast data list if any.
+        if (g_multicastDataList)
+        {
+            oc_mutex_lock(g_multicastDataListMutex);
+            uint32_t arrayLength = u_arraylist_length(g_multicastDataList);
+            for (uint32_t i = 0; i < arrayLength; i++)
+            {
+                CALEData_t *multicastData = u_arraylist_get(g_multicastDataList, i);
+                if (NULL == multicastData)
+                {
+                    OIC_LOG(DEBUG, TAG, "multicastData is NULL");
+                    continue;
+                }
+                CAUpdateCharacteristicsToGattServer(remoteAddress, multicastData->data,
+                                                    multicastData->dataLen, LE_UNICAST, 0);
+            }
+            oc_mutex_unlock(g_multicastDataListMutex);
+        }
+
+        OIC_LOG(DEBUG, TAG, "OUT");
+        return CA_STATUS_OK;
+    }
+    else
+    {
+        OIC_LOG_V(INFO, TAG, "CAGetLEServerInfo [%s] is failed, %d", remoteAddress, result);
+    }
+
     bt_gatt_client_h clientHandle = NULL;
     int32_t ret = bt_gatt_client_create(remoteAddress, &clientHandle);
     if (BT_ERROR_NONE != ret || NULL == clientHandle)
     {
         OIC_LOG_V(ERROR, TAG,
                   "bt_gatt_client_create Failed with ret value [%s] ", CALEGetErrorMsg(ret));
-        CALEGattDisConnect(remoteAddress);
         return CA_STATUS_FAILED;
     }
 
@@ -935,7 +1034,6 @@ CAResult_t CALEGattDiscoverServices(const char *remoteAddress)
         OIC_LOG_V(ERROR, TAG,
                   "bt_gatt_client_get_service Failed with ret value [%s] ", CALEGetErrorMsg(ret));
         bt_gatt_client_destroy(clientHandle);
-        CALEGattDisConnect(remoteAddress);
         return CA_STATUS_FAILED;
     }
 
@@ -1004,8 +1102,8 @@ CAResult_t CALEGattDiscoverServices(const char *remoteAddress)
     serverInfo->writeChar = writeChrHandle;
     serverInfo->remoteAddress = OICStrdup(remoteAddress);
 
-    ca_mutex_lock(g_LEServerListMutex);
-    CAResult_t result = CAAddLEServerInfoToList(&g_LEServerList, serverInfo);
+    oc_mutex_lock(g_LEServerListMutex);
+    result = CAAddLEServerInfoToList(&g_LEServerList, serverInfo);
     if (CA_STATUS_OK != result)
     {
         OIC_LOG(ERROR, TAG, "CAAddLEServerInfoToList failed");
@@ -1013,14 +1111,30 @@ CAResult_t CALEGattDiscoverServices(const char *remoteAddress)
         CALEGattDisConnect(remoteAddress);
         return CA_STATUS_FAILED;
     }
-    ca_mutex_unlock(g_LEServerListMutex);
+    oc_mutex_unlock(g_LEServerListMutex);
+
+    oc_mutex_lock(g_deviceDiscoveredListMutex);
+    // Add the the device Discovered list.
+    if (NULL == g_deviceDiscoveredList)
+    {
+        g_deviceDiscoveredList = u_arraylist_create();
+    }
+    char *deviceAddr = OICStrdup(remoteAddress);
+    if (NULL == deviceAddr)
+    {
+        OIC_LOG_V(ERROR, TAG, "Device address is NULL");
+        oc_mutex_unlock(g_deviceDiscoveredListMutex);
+        return CA_STATUS_FAILED;
+    }
+    u_arraylist_add(g_deviceDiscoveredList, (void *) deviceAddr);
+    oc_mutex_unlock(g_deviceDiscoveredListMutex);
 
     // Send the data of pending multicast data list if any.
     if (g_multicastDataList)
     {
-        ca_mutex_lock(g_multicastDataListMutex);
+        oc_mutex_lock(g_multicastDataListMutex);
         uint32_t arrayLength = u_arraylist_length(g_multicastDataList);
-        for (int i = 0; i < arrayLength; i++)
+        for (uint32_t i = 0; i < arrayLength; i++)
         {
             CALEData_t *multicastData = u_arraylist_get(g_multicastDataList, i);
             if (NULL == multicastData)
@@ -1031,7 +1145,7 @@ CAResult_t CALEGattDiscoverServices(const char *remoteAddress)
             CAUpdateCharacteristicsToGattServer(remoteAddress, multicastData->data,
                                                 multicastData->dataLen, LE_UNICAST, 0);
         }
-        ca_mutex_unlock(g_multicastDataListMutex);
+        oc_mutex_unlock(g_multicastDataListMutex);
     }
 
     OIC_LOG(DEBUG, TAG, "OUT");
@@ -1055,7 +1169,7 @@ CAResult_t  CAUpdateCharacteristicsToGattServer(const char *remoteAddress,
     LEServerInfo *leServerInfo = NULL;
     CAResult_t ret =  CA_STATUS_FAILED;
 
-    ca_mutex_lock(g_LEServerListMutex);
+    oc_mutex_lock(g_LEServerListMutex);
     if (LE_UNICAST == type)
     {
         ret = CAGetLEServerInfo(g_LEServerList, remoteAddress, &leServerInfo);
@@ -1064,7 +1178,7 @@ CAResult_t  CAUpdateCharacteristicsToGattServer(const char *remoteAddress,
     {
         ret = CAGetLEServerInfoByPosition(g_LEServerList, position, &leServerInfo);
     }
-    ca_mutex_unlock(g_LEServerListMutex);
+    oc_mutex_unlock(g_LEServerListMutex);
 
     if (CA_STATUS_OK != ret)
     {
@@ -1099,23 +1213,23 @@ CAResult_t  CAUpdateCharacteristicsToGattServer(const char *remoteAddress,
 
     // wait for callback for write Characteristic with success to sent data
     OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
-    ca_mutex_lock(g_threadWriteCharacteristicMutex);
+    oc_mutex_lock(g_threadWriteCharacteristicMutex);
     if (!g_isSignalSetFlag)
     {
         OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
-        if (CA_WAIT_SUCCESS != ca_cond_wait_for(g_threadWriteCharacteristicCond,
+        if (OC_WAIT_SUCCESS != oc_cond_wait_for(g_threadWriteCharacteristicCond,
                                   g_threadWriteCharacteristicMutex,
                                   WAIT_TIME_WRITE_CHARACTERISTIC))
         {
             OIC_LOG(ERROR, TAG, "there is no response. write has failed");
             g_isSignalSetFlag = false;
-            ca_mutex_unlock(g_threadWriteCharacteristicMutex);
+            oc_mutex_unlock(g_threadWriteCharacteristicMutex);
             return CA_SEND_FAILED;
         }
     }
     // reset flag set by writeCharacteristic Callback
     g_isSignalSetFlag = false;
-    ca_mutex_unlock(g_threadWriteCharacteristicMutex);
+    oc_mutex_unlock(g_threadWriteCharacteristicMutex);
 
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
@@ -1167,13 +1281,13 @@ CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t
     memcpy(multicastData->data, data, dataLen);
     multicastData->dataLen = dataLen;
 
-    ca_mutex_lock(g_multicastDataListMutex);
+    oc_mutex_lock(g_multicastDataListMutex);
     if (NULL == g_multicastDataList)
     {
         g_multicastDataList = u_arraylist_create();
     }
     u_arraylist_add(g_multicastDataList, (void *)multicastData);
-    ca_mutex_unlock(g_multicastDataListMutex);
+    oc_mutex_unlock(g_multicastDataListMutex);
 
     // Start the scanning.
     CAResult_t result = CALEGattStartDeviceScanning();
@@ -1184,11 +1298,39 @@ CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t
     }
 
     // Start the timer by signalling it.
-    ca_cond_signal(g_startTimerCond);
+    oc_cond_signal(g_startTimerCond);
 
 exit:
     OIC_LOG(DEBUG, TAG, "OUT ");
     return CA_STATUS_OK;
 }
 
+bool CALEClientIsConnected(const char* address)
+{
+    //@Todo
+    return true;
+}
 
+uint16_t CALEClientGetMtuSize(const char* address)
+{
+    VERIFY_NON_NULL_RET(address, TAG, "address is null", CA_DEFAULT_BLE_MTU_SIZE);
+    //@Todo
+    //it should be implemented after update Tizen 3.0
+    return CA_DEFAULT_BLE_MTU_SIZE;
+}
+
+CAResult_t CALEClientSetMtuSize(const char* address, uint16_t mtuSize)
+{
+    VERIFY_NON_NULL(address, TAG, "address is null");
+    //@Todo
+    //it should be implemented after update Tizen 3.0
+    return CA_NOT_SUPPORTED;
+}
+
+CAResult_t CALEClientSendNegotiationMessage(const char* address)
+{
+    OIC_LOG_V(DEBUG, TAG, "CALEClientSendNegotiationMessage(%s)", address);
+    //@Todo
+    //it will be implemented when tizen public 3.0 is released.
+    return CA_NOT_SUPPORTED;
+}
index c55e025..6372429 100644 (file)
@@ -178,4 +178,34 @@ void CADiscoverLEServicesThread (void *remoteAddress);
  * @retval ::CA_STATUS_FAILED Operation failed.
  */
 CAResult_t CALEGattDiscoverServices(const char *remoteAddress);
+
+/**
+ * check connection status.
+ * @param[in] address      the address of the remote device.
+ * @return  true or false.
+ */
+bool CALEClientIsConnected(const char* address);
+
+/**
+ * get MTU size.
+ * @param[in] address      the address of the remote device.
+ * @return  mtu size negotiated from remote device.
+ */
+uint16_t CALEClientGetMtuSize(const char* address);
+
+/**
+ * This function is used to set MTU size
+ * which negotiated between client and server device.
+ * @param[in]   address       remote address.
+ * @param[in]   mtuSize       MTU size.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientSetMtuSize(const char* address, uint16_t mtuSize);
+
+/**
+ * Send negotiation message after gatt connection is done.
+ * @param[in]   address               remote address.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CALEClientSendNegotiationMessage(const char* address);
 #endif /* TZ_BLE_CLIENT_H_ */
index 2e2156b..5775877 100644 (file)
@@ -23,6 +23,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <glib.h>
 #include <arpa/inet.h>
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -32,7 +33,7 @@
 #include <bluetooth_internal.h>
 #include <bluetooth_type.h>
 
-#include "camutex.h"
+#include "octhread.h"
 #include "caleadapter.h"
 #include "caadapterutils.h"
 #include "oic_string.h"
@@ -43,6 +44,9 @@
  */
 #define TAG "OIC_CA_LE_MONITOR"
 
+static GMainLoop *g_mainloop = NULL;
+static ca_thread_pool_t g_threadPoolHandle = NULL;
+
 /**
  * Maintains the callback to be notified on device state changed.
  */
@@ -57,13 +61,13 @@ static CALEConnectionStateChangedCallback g_bleConnectionStateChangedCallback =
  * Mutex to synchronize access to the deviceStateChanged Callback when the state
  *           of the LE adapter gets change.
  */
-static ca_mutex g_bleDeviceStateChangedCbMutex = NULL;
+static oc_mutex g_bleDeviceStateChangedCbMutex = NULL;
 
 /**
  * Mutex to synchronize access to the ConnectionStateChanged Callback when the state
  * of the LE adapter gets change.
  */
-static ca_mutex g_bleConnectionStateChangedCbMutex = NULL;
+static oc_mutex g_bleConnectionStateChangedCbMutex = NULL;
 
 /**
 * This is the callback which will be called when the adapter state gets changed.
@@ -77,6 +81,11 @@ static ca_mutex g_bleConnectionStateChangedCbMutex = NULL;
 void CALEAdapterStateChangedCb(int result, bt_adapter_state_e adapter_state,
                                void *user_data);
 
+void CALEMainLoopThread(void *param)
+{
+    g_main_loop_run(g_mainloop);
+}
+
 /**
 * This is the callback which will be called when the connection state gets changed.
 *
@@ -96,21 +105,21 @@ CAResult_t CAInitializeLENetworkMonitor()
 
     if (NULL == g_bleDeviceStateChangedCbMutex)
     {
-        g_bleDeviceStateChangedCbMutex = ca_mutex_new();
+        g_bleDeviceStateChangedCbMutex = oc_mutex_new();
         if (NULL == g_bleDeviceStateChangedCbMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_bleConnectionStateChangedCbMutex)
     {
-        g_bleConnectionStateChangedCbMutex = ca_mutex_new();
+        g_bleConnectionStateChangedCbMutex = oc_mutex_new();
         if (NULL == g_bleConnectionStateChangedCbMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
-            ca_mutex_free(g_bleDeviceStateChangedCbMutex);
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
+            oc_mutex_free(g_bleDeviceStateChangedCbMutex);
             return CA_STATUS_FAILED;
         }
     }
@@ -124,10 +133,10 @@ void CATerminateLENetworkMonitor()
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
-    ca_mutex_free(g_bleDeviceStateChangedCbMutex);
+    oc_mutex_free(g_bleDeviceStateChangedCbMutex);
     g_bleDeviceStateChangedCbMutex = NULL;
 
-    ca_mutex_free(g_bleConnectionStateChangedCbMutex);
+    oc_mutex_free(g_bleConnectionStateChangedCbMutex);
     g_bleConnectionStateChangedCbMutex = NULL;
 
     OIC_LOG(DEBUG, TAG, "OUT");
@@ -136,6 +145,13 @@ void CATerminateLENetworkMonitor()
 CAResult_t CAInitializeLEAdapter()
 {
     OIC_LOG(DEBUG, TAG, "IN");
+    CAResult_t res = ca_thread_pool_init(2, &g_threadPoolHandle);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "thread pool initialize error.");
+        return res;
+    }
+
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
@@ -144,6 +160,20 @@ CAResult_t CAStartLEAdapter()
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
+    g_mainloop = g_main_loop_new(NULL, 0);
+    if(!g_mainloop)
+    {
+        OIC_LOG(ERROR, TAG, "g_main_loop_new failed\n");
+        return CA_STATUS_FAILED;
+    }
+
+    if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, CALEMainLoopThread,
+                                                (void *) NULL, NULL))
+    {
+        OIC_LOG(ERROR, TAG, "Failed to create thread!");
+        return CA_STATUS_FAILED;
+    }
+
     int ret = bt_initialize();
     if (BT_ERROR_NONE != ret)
     {
@@ -187,6 +217,13 @@ CAResult_t CAStopLEAdapter()
         return CA_STATUS_FAILED;
     }
 
+    if (g_mainloop)
+    {
+        g_main_loop_quit(g_mainloop);
+    }
+
+    ca_thread_pool_free(g_threadPoolHandle);
+    g_threadPoolHandle = NULL;
     return CA_STATUS_OK;
 }
 
@@ -243,9 +280,9 @@ CAResult_t CAGetLEAddress(char **local_address)
 CAResult_t CASetLEAdapterStateChangedCb(CALEDeviceStateChangedCallback callback)
 {
     OIC_LOG(DEBUG, TAG, "IN");
-    ca_mutex_lock(g_bleDeviceStateChangedCbMutex);
+    oc_mutex_lock(g_bleDeviceStateChangedCbMutex);
     g_bleDeviceStateChangedCallback = callback;
-    ca_mutex_unlock(g_bleDeviceStateChangedCbMutex);
+    oc_mutex_unlock(g_bleDeviceStateChangedCbMutex);
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
@@ -253,9 +290,9 @@ CAResult_t CASetLEAdapterStateChangedCb(CALEDeviceStateChangedCallback callback)
 CAResult_t CAUnSetLEAdapterStateChangedCb()
 {
     OIC_LOG(DEBUG, TAG, "IN");
-    ca_mutex_lock(g_bleDeviceStateChangedCbMutex);
+    oc_mutex_lock(g_bleDeviceStateChangedCbMutex);
     g_bleDeviceStateChangedCallback = NULL;
-    ca_mutex_unlock(g_bleDeviceStateChangedCbMutex);
+    oc_mutex_unlock(g_bleDeviceStateChangedCbMutex);
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
@@ -263,19 +300,19 @@ CAResult_t CAUnSetLEAdapterStateChangedCb()
 CAResult_t CASetLENWConnectionStateChangedCb(CALEConnectionStateChangedCallback callback)
 {
     OIC_LOG(DEBUG, TAG, "IN");
-    ca_mutex_lock(g_bleConnectionStateChangedCbMutex);
+    oc_mutex_lock(g_bleConnectionStateChangedCbMutex);
     g_bleConnectionStateChangedCallback = callback;
-    ca_mutex_unlock(g_bleConnectionStateChangedCbMutex);
+    oc_mutex_unlock(g_bleConnectionStateChangedCbMutex);
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
 
-CAResult_t CAUnsetLENWConnectionStateChangedCb()
+CAResult_t CAUnSetLENWConnectionStateChangedCb()
 {
     OIC_LOG(DEBUG, TAG, "IN");
-    ca_mutex_lock(g_bleConnectionStateChangedCbMutex);
+    oc_mutex_lock(g_bleConnectionStateChangedCbMutex);
     g_bleConnectionStateChangedCallback = NULL;
-    ca_mutex_unlock(g_bleConnectionStateChangedCbMutex);
+    oc_mutex_unlock(g_bleConnectionStateChangedCbMutex);
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
@@ -285,12 +322,12 @@ void CALEAdapterStateChangedCb(int result, bt_adapter_state_e adapter_state,
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
-    ca_mutex_lock(g_bleDeviceStateChangedCbMutex);
+    oc_mutex_lock(g_bleDeviceStateChangedCbMutex);
 
     if (NULL == g_bleDeviceStateChangedCallback)
     {
         OIC_LOG(ERROR, TAG, "g_bleDeviceStateChangedCallback is NULL!");
-        ca_mutex_unlock(g_bleDeviceStateChangedCbMutex);
+        oc_mutex_unlock(g_bleDeviceStateChangedCbMutex);
         return;
     }
 
@@ -298,21 +335,14 @@ void CALEAdapterStateChangedCb(int result, bt_adapter_state_e adapter_state,
     {
         OIC_LOG(DEBUG, TAG, "Adapter is disabled");
         g_bleDeviceStateChangedCallback(CA_ADAPTER_DISABLED);
-        ca_mutex_unlock(g_bleDeviceStateChangedCbMutex);
+        oc_mutex_unlock(g_bleDeviceStateChangedCbMutex);
         return;
     }
 
     OIC_LOG(DEBUG, TAG, "Adapter is Enabled");
 
-    int ret = bt_adapter_set_visibility(BT_ADAPTER_VISIBILITY_MODE_GENERAL_DISCOVERABLE, 0);
-    if (BT_ERROR_NONE != ret)
-    {
-        OIC_LOG(ERROR, TAG, "bt_adapter_set_visibility failed");
-        return;
-    }
-
     g_bleDeviceStateChangedCallback(CA_ADAPTER_ENABLED);
-    ca_mutex_unlock(g_bleDeviceStateChangedCbMutex);
+    oc_mutex_unlock(g_bleDeviceStateChangedCbMutex);
 
     OIC_LOG(DEBUG, TAG, "OUT");
 }
@@ -324,17 +354,17 @@ void CALENWConnectionStateChangedCb(int result, bool connected,
 
     VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address is NULL");
 
-    ca_mutex_lock(g_bleConnectionStateChangedCbMutex);
+    oc_mutex_lock(g_bleConnectionStateChangedCbMutex);
     char *addr = OICStrdup(remoteAddress);
     if (NULL == addr)
     {
         OIC_LOG(ERROR, TAG, "addr is NULL");
-        ca_mutex_unlock(g_bleConnectionStateChangedCbMutex);
+        oc_mutex_unlock(g_bleConnectionStateChangedCbMutex);
         return;
     }
     g_bleConnectionStateChangedCallback(CA_ADAPTER_GATT_BTLE, addr, connected);
     OICFree(addr);
-    ca_mutex_unlock(g_bleConnectionStateChangedCbMutex);
+    oc_mutex_unlock(g_bleConnectionStateChangedCbMutex);
 
     OIC_LOG(DEBUG, TAG, "OUT");
 }
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/tizen/calenwmonitor_vd.c b/resource/csdk/connectivity/src/bt_le_adapter/tizen/calenwmonitor_vd.c
new file mode 100644 (file)
index 0000000..30f74fc
--- /dev/null
@@ -0,0 +1,334 @@
+/******************************************************************
+*
+* 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 "caleinterface.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include <bluetooth.h>
+#include <bluetooth_internal.h>
+#include <bluetooth_type.h>
+
+#include "octhread.h"
+#include "caleadapter.h"
+#include "caadapterutils.h"
+#include "oic_string.h"
+#include "oic_malloc.h"
+
+/**
+ * Logging tag for module name
+ */
+#define TAG "OIC_CA_LE_MONITOR_VD"
+
+/**
+ * Maintains the callback to be notified on device state changed.
+ */
+static CALEDeviceStateChangedCallback g_bleDeviceStateChangedCallback = NULL;
+
+/**
+ * Maintains the callback to be notified on device state changed.
+ */
+static CALEConnectionStateChangedCallback g_bleConnectionStateChangedCallback = NULL;
+
+/**
+ * Mutex to synchronize access to the deviceStateChanged Callback when the state
+ *           of the LE adapter gets change.
+ */
+static oc_mutex g_bleDeviceStateChangedCbMutex = NULL;
+
+/**
+ * Mutex to synchronize access to the ConnectionStateChanged Callback when the state
+ * of the LE adapter gets change.
+ */
+static oc_mutex g_bleConnectionStateChangedCbMutex = NULL;
+
+/**
+* This is the callback which will be called when the adapter state gets changed.
+*
+* @param result         [IN] Result of the query done to the platform.
+* @param adapter_state  [IN] State of the LE adapter.
+* @param user_data      [IN] User data passed by the caller when querying for the state changed cb.
+*
+* @return  None.
+*/
+void CALEAdapterStateChangedCb(int result, bt_adapter_state_e adapter_state,
+                               void *user_data);
+
+/**
+* This is the callback which will be called when the connection state gets changed.
+*
+* @param result         [IN] Result of the query done to the platform.
+* @param connected      [IN] State of connection.
+* @param remoteAddress  [IN] LE address of the device to be notified.
+* @param user_data      [IN] User data passed by the caller when querying for the state changed cb.
+*
+* @return  None.
+*/
+void CALENWConnectionStateChangedCb(int result, bool connected,
+                                    const char *remoteAddress, void *userData);
+
+CAResult_t CAInitializeLENetworkMonitor()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    if (NULL == g_bleDeviceStateChangedCbMutex)
+    {
+        g_bleDeviceStateChangedCbMutex = oc_mutex_new();
+        if (NULL == g_bleDeviceStateChangedCbMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_bleConnectionStateChangedCbMutex)
+    {
+        g_bleConnectionStateChangedCbMutex = oc_mutex_new();
+        if (NULL == g_bleConnectionStateChangedCbMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
+            oc_mutex_free(g_bleDeviceStateChangedCbMutex);
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+
+    return CA_STATUS_OK;
+}
+
+void CATerminateLENetworkMonitor()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    oc_mutex_free(g_bleDeviceStateChangedCbMutex);
+    g_bleDeviceStateChangedCbMutex = NULL;
+
+    oc_mutex_free(g_bleConnectionStateChangedCbMutex);
+    g_bleConnectionStateChangedCbMutex = NULL;
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+CAResult_t CAInitializeLEAdapter()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAStartLEAdapter()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    int ret = bt_initialize();
+    if (BT_ERROR_NONE != ret)
+    {
+        OIC_LOG(ERROR, TAG, "bt_initialize failed");
+        return CA_STATUS_FAILED;
+    }
+
+    ret = bt_adapter_set_state_changed_cb(CALEAdapterStateChangedCb, NULL);
+    if (BT_ERROR_NONE != ret)
+    {
+        OIC_LOG(DEBUG, TAG, "bt_adapter_set_state_changed_cb failed");
+        return CA_STATUS_FAILED;
+    }
+
+    ret = bt_gatt_set_connection_state_changed_cb(CALENWConnectionStateChangedCb, NULL);
+    if (BT_ERROR_NONE != ret)
+    {
+        OIC_LOG_V(ERROR, TAG,
+                  "bt_gatt_set_connection_state_changed_cb has failed");
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAStopLEAdapter()
+{
+
+    int ret = bt_adapter_unset_state_changed_cb();
+    if (BT_ERROR_NONE != ret)
+    {
+        OIC_LOG(DEBUG, TAG, "bt_adapter_unset_state_changed_cb failed");
+        return CA_STATUS_FAILED;
+    }
+
+    ret = bt_deinitialize();
+    if (BT_ERROR_NONE != ret)
+    {
+        OIC_LOG(ERROR, TAG, "bt_deinitialize failed");
+        return CA_STATUS_FAILED;
+    }
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAGetLEAdapterState()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    bt_adapter_state_e adapterState = BT_ADAPTER_DISABLED;
+
+    //Get Bluetooth adapter state
+    int ret = bt_adapter_get_state(&adapterState);
+    if (BT_ERROR_NONE != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "Bluetooth get state failed!, error num [%x]",
+                  ret);
+        return CA_STATUS_FAILED;
+    }
+
+    if (BT_ADAPTER_ENABLED != adapterState)
+    {
+        OIC_LOG(DEBUG, TAG, "BT Adapter is not enabled");
+        return CA_ADAPTER_NOT_ENABLED;
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAGetLEAddress(char **local_address)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    VERIFY_NON_NULL(local_address, TAG, "local_address is null")
+
+    char *address = NULL;
+
+    int ret = bt_adapter_get_address(&address);
+    if (BT_ERROR_NONE != ret || !address)
+    {
+        OIC_LOG_V(ERROR, TAG, "bt_adapter_get_address failed!, error num [%x]",
+                  ret);
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "bd address[%s]", address);
+
+    *local_address = address;
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CASetLEAdapterStateChangedCb(CALEDeviceStateChangedCallback callback)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    oc_mutex_lock(g_bleDeviceStateChangedCbMutex);
+    g_bleDeviceStateChangedCallback = callback;
+    oc_mutex_unlock(g_bleDeviceStateChangedCbMutex);
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAUnSetLEAdapterStateChangedCb()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    oc_mutex_lock(g_bleDeviceStateChangedCbMutex);
+    g_bleDeviceStateChangedCallback = NULL;
+    oc_mutex_unlock(g_bleDeviceStateChangedCbMutex);
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CASetLENWConnectionStateChangedCb(CALEConnectionStateChangedCallback callback)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    oc_mutex_lock(g_bleConnectionStateChangedCbMutex);
+    g_bleConnectionStateChangedCallback = callback;
+    oc_mutex_unlock(g_bleConnectionStateChangedCbMutex);
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAUnSetLENWConnectionStateChangedCb()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    oc_mutex_lock(g_bleConnectionStateChangedCbMutex);
+    g_bleConnectionStateChangedCallback = NULL;
+    oc_mutex_unlock(g_bleConnectionStateChangedCbMutex);
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CALEAdapterStateChangedCb(int result, bt_adapter_state_e adapter_state,
+                                          void *user_data)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    oc_mutex_lock(g_bleDeviceStateChangedCbMutex);
+
+    if (NULL == g_bleDeviceStateChangedCallback)
+    {
+        OIC_LOG(ERROR, TAG, "g_bleDeviceStateChangedCallback is NULL!");
+        oc_mutex_unlock(g_bleDeviceStateChangedCbMutex);
+        return;
+    }
+
+    if (BT_ADAPTER_DISABLED == adapter_state)
+    {
+        OIC_LOG(DEBUG, TAG, "Adapter is disabled");
+        g_bleDeviceStateChangedCallback(CA_ADAPTER_DISABLED);
+        oc_mutex_unlock(g_bleDeviceStateChangedCbMutex);
+        return;
+    }
+
+    OIC_LOG(DEBUG, TAG, "Adapter is Enabled");
+
+    g_bleDeviceStateChangedCallback(CA_ADAPTER_ENABLED);
+    oc_mutex_unlock(g_bleDeviceStateChangedCbMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+void CALENWConnectionStateChangedCb(int result, bool connected,
+                                    const char *remoteAddress, void *userData)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address is NULL");
+
+    oc_mutex_lock(g_bleConnectionStateChangedCbMutex);
+    char *addr = OICStrdup(remoteAddress);
+    if (NULL == addr)
+    {
+        OIC_LOG(ERROR, TAG, "addr is NULL");
+        oc_mutex_unlock(g_bleConnectionStateChangedCbMutex);
+        return;
+    }
+    g_bleConnectionStateChangedCallback(CA_ADAPTER_GATT_BTLE, addr, connected);
+    OICFree(addr);
+    oc_mutex_unlock(g_bleConnectionStateChangedCbMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
index 532ec6a..09f36d4 100644 (file)
@@ -21,7 +21,7 @@
 #include "caleserver.h"
 #include "cacommon.h"
 #include "cacommonutil.h"
-#include "camutex.h"
+#include "octhread.h"
 #include "caqueueingthread.h"
 #include "cagattservice.h"
 #include "oic_string.h"
@@ -82,28 +82,28 @@ static bool g_isLEGattServerStarted = false;
 /**
  * Mutex to synchronize the calls to start and stop server.
  */
-static ca_mutex g_leServerStateMutex = NULL;
+static oc_mutex g_leServerStateMutex = NULL;
 
 /**
  * Mutex to synchronize writing operations on the characteristics.
  */
-static  ca_mutex g_leCharacteristicMutex = NULL;
+static  oc_mutex g_leCharacteristicMutex = NULL;
 
 /**
  * Mutex to synchronize to creation of OIC service.
  */
-static  ca_mutex g_leServiceMutex = NULL;
+static  oc_mutex g_leServiceMutex = NULL;
 
 /**
  * Mutex to synchronize access to the requestResponse callback to be called
  * when the data needs to be sent from GATTClient.
  */
-static  ca_mutex g_leReqRespCbMutex = NULL;
+static  oc_mutex g_leReqRespCbMutex = NULL;
 
 /**
  * Mutex to synchronize the task to be pushed to thread pool.
  */
-static ca_mutex g_leServerThreadPoolMutex = NULL;
+static oc_mutex g_leServerThreadPoolMutex = NULL;
 
 /**
  * Reference to threadpool.
@@ -123,33 +123,48 @@ static LEClientInfoList *g_LEClientList = NULL;
 /**
  * Mutex to synchronize access to LE ClientList.
  */
-static ca_mutex g_LEClientListMutex = NULL;
+static oc_mutex g_LEClientListMutex = NULL;
 
 void CALEGattServerConnectionStateChanged(bool connected, const char *remoteAddress)
 {
     VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address");
 
+    CAResult_t res = CA_STATUS_OK;
     if (connected)
     {
         OIC_LOG_V(DEBUG, TAG, "Connected to [%s]", remoteAddress);
         char *addr = OICStrdup(remoteAddress);
-        ca_mutex_lock(g_LEClientListMutex);
-        CAResult_t result  = CAAddLEClientInfoToList(&g_LEClientList, addr);
-        if (CA_STATUS_OK != result)
+        oc_mutex_lock(g_LEClientListMutex);
+        res  = CAAddLEClientInfoToList(&g_LEClientList, addr);
+        if (CA_STATUS_OK != res)
         {
             OIC_LOG(ERROR, TAG, "CAAddLEClientInfoToList failed");
-            ca_mutex_unlock(g_LEClientListMutex);
+            oc_mutex_unlock(g_LEClientListMutex);
             OICFree(addr);
             return;
         }
-        ca_mutex_unlock(g_LEClientListMutex);
+        oc_mutex_unlock(g_LEClientListMutex);
+
+        res = CALEStopAdvertise();
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG_V(ERROR, TAG, "Failed to stop advertising [%d]", res);
+            return;
+        }
     }
     else
     {
         OIC_LOG_V(DEBUG, TAG, "Disconnected from [%s]", remoteAddress);
-        ca_mutex_lock(g_LEClientListMutex);
+        oc_mutex_lock(g_LEClientListMutex);
         CARemoveLEClientInfoFromList(&g_LEClientList, remoteAddress);
-        ca_mutex_unlock(g_LEClientListMutex);
+        oc_mutex_unlock(g_LEClientListMutex);
+
+        res = CALEStartAdvertise();
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG_V(ERROR, TAG, "Failed to start advertising [%d]", res);
+            return;
+        }
     }
 }
 
@@ -163,11 +178,11 @@ CAResult_t CAStartLEGattServer()
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
-    ca_mutex_lock(g_leServerStateMutex);
+    oc_mutex_lock(g_leServerStateMutex);
     if (true == g_isLEGattServerStarted)
     {
         OIC_LOG(ERROR, TAG, "Gatt Server is already running");
-        ca_mutex_unlock(g_leServerStateMutex);
+        oc_mutex_unlock(g_leServerStateMutex);
         return CA_STATUS_OK;
     }
 
@@ -175,18 +190,16 @@ CAResult_t CAStartLEGattServer()
     if (CA_STATUS_OK != ret)
     {
         OIC_LOG_V(ERROR, TAG, "CAInitLEGattServer failed[%d]", ret);
-        ca_mutex_unlock(g_leServerStateMutex);
+        oc_mutex_unlock(g_leServerStateMutex);
         CATerminateLEGattServer();
         return CA_STATUS_FAILED;
     }
 
-    char *serviceUUID = CA_GATT_SERVICE_UUID;
-
-    ret  = CAAddNewLEServiceInGattServer(serviceUUID);
+    ret  = CAAddNewLEServiceInGattServer(CA_GATT_SERVICE_UUID);
     if (CA_STATUS_OK != ret)
     {
         OIC_LOG_V(ERROR, TAG, "CAAddNewLEServiceInGattServer failed[%d]", ret);
-        ca_mutex_unlock(g_leServerStateMutex);
+        oc_mutex_unlock(g_leServerStateMutex);
         CATerminateLEGattServer();
         return CA_STATUS_FAILED;
     }
@@ -200,7 +213,7 @@ CAResult_t CAStartLEGattServer()
     if (CA_STATUS_OK != ret)
     {
         OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
-        ca_mutex_unlock(g_leServerStateMutex);
+        oc_mutex_unlock(g_leServerStateMutex);
         CATerminateLEGattServer();
         return CA_STATUS_FAILED;
     }
@@ -214,7 +227,7 @@ CAResult_t CAStartLEGattServer()
     if (CA_STATUS_OK != ret )
     {
         OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
-        ca_mutex_unlock(g_leServerStateMutex);
+        oc_mutex_unlock(g_leServerStateMutex);
         CATerminateLEGattServer();
         return CA_STATUS_FAILED;
     }
@@ -223,23 +236,23 @@ CAResult_t CAStartLEGattServer()
     if (CA_STATUS_OK != ret )
     {
         OIC_LOG_V(ERROR, TAG, "CARegisterLEServicewithGattServer failed[%d]", ret);
-        ca_mutex_unlock(g_leServerStateMutex);
+        oc_mutex_unlock(g_leServerStateMutex);
         CATerminateLEGattServer();
         return CA_STATUS_FAILED;
     }
 
-    ret = CALEStartAdvertise(serviceUUID);
+    ret = CALEStartAdvertise();
     if (CA_STATUS_OK != ret)
     {
         OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret);
-        ca_mutex_unlock(g_leServerStateMutex);
+        oc_mutex_unlock(g_leServerStateMutex);
         CATerminateLEGattServer();
         return CA_STATUS_FAILED;
     }
 
     g_isLEGattServerStarted = true;
 
-    ca_mutex_unlock(g_leServerStateMutex);
+    oc_mutex_unlock(g_leServerStateMutex);
 
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
@@ -249,14 +262,35 @@ void CALENotificationCb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_han
                         void *user_data)
 {
     OIC_LOG(DEBUG, TAG, "IN");
-    if(notify)
+    if (notify)
     {
         OIC_LOG(DEBUG, TAG, "Notification is subscribed by the client");
+        CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
+                           true, "notifyChar success");
+    }
+    else
+    {
+        CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
+                           false, "notifyChar failure");
+    }
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+CAResult_t CALEStartAdvertise()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    CAResult_t res = CALEStartAdvertiseImpl(CA_GATT_SERVICE_UUID);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG_V(ERROR, TAG, "CALEStartAdvertiseImpl failed[%d]", res);
     }
+
     OIC_LOG(DEBUG, TAG, "OUT");
+    return res;
 }
 
-CAResult_t CALEStartAdvertise(const char *serviceUUID)
+CAResult_t CALEStartAdvertiseImpl(const char *serviceUUID)
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
@@ -332,21 +366,21 @@ CAResult_t CAStopLEGattServer()
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
-    ca_mutex_lock(g_leServerStateMutex);
+    oc_mutex_lock(g_leServerStateMutex);
 
     if (false == g_isLEGattServerStarted)
     {
         OIC_LOG(ERROR, TAG, "Gatt Server is not running to stop");
-        ca_mutex_unlock(g_leServerStateMutex);
+        oc_mutex_unlock(g_leServerStateMutex);
         return CA_STATUS_OK;
     }
 
     g_isLEGattServerStarted = false;
 
-    ca_mutex_lock(g_LEClientListMutex);
+    oc_mutex_lock(g_LEClientListMutex);
     CADisconnectAllClient(g_LEClientList);
     g_LEClientList = NULL;
-    ca_mutex_unlock(g_LEClientListMutex);
+    oc_mutex_unlock(g_LEClientListMutex);
 
     CAResult_t res = CALEStopAdvertise();
     {
@@ -380,7 +414,7 @@ CAResult_t CAStopLEGattServer()
         OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
     }
 
-    ca_mutex_unlock(g_leServerStateMutex);
+    oc_mutex_unlock(g_leServerStateMutex);
 
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
@@ -406,18 +440,18 @@ void CATerminateLEGattServer()
     OIC_LOG(DEBUG, TAG, "IN");
 
     // Service and characteristics path will be freed by the platform.
-    ca_mutex_lock(g_leServiceMutex);
+    oc_mutex_lock(g_leServiceMutex);
     g_gattSvcPath = NULL;
-    ca_mutex_unlock(g_leServiceMutex);
+    oc_mutex_unlock(g_leServiceMutex);
 
-    ca_mutex_lock(g_leCharacteristicMutex);
+    oc_mutex_lock(g_leCharacteristicMutex);
     g_gattReadCharPath = NULL;
     g_gattWriteCharPath = NULL;
-    ca_mutex_unlock(g_leCharacteristicMutex);
+    oc_mutex_unlock(g_leCharacteristicMutex);
 
-    ca_mutex_lock(g_leServerThreadPoolMutex);
+    oc_mutex_lock(g_leServerThreadPoolMutex);
     g_leServerThreadPool = NULL;
-    ca_mutex_unlock(g_leServerThreadPoolMutex);
+    oc_mutex_unlock(g_leServerThreadPoolMutex);
 
     // Terminating all mutex variables.
     CATerminateGattServerMutexVariables();
@@ -429,60 +463,60 @@ CAResult_t CAInitGattServerMutexVariables()
     OIC_LOG(DEBUG, TAG, "IN");
     if (NULL == g_leServerStateMutex)
     {
-        g_leServerStateMutex = ca_mutex_new();
+        g_leServerStateMutex = oc_mutex_new();
         if (NULL == g_leServerStateMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_leServiceMutex)
     {
-        g_leServiceMutex = ca_mutex_new();
+        g_leServiceMutex = oc_mutex_new();
         if (NULL == g_leServiceMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_leCharacteristicMutex)
     {
-        g_leCharacteristicMutex = ca_mutex_new();
+        g_leCharacteristicMutex = oc_mutex_new();
         if (NULL == g_leCharacteristicMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_leReqRespCbMutex)
     {
-        g_leReqRespCbMutex = ca_mutex_new();
+        g_leReqRespCbMutex = oc_mutex_new();
         if (NULL == g_leReqRespCbMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_leServerThreadPoolMutex)
     {
-        g_leServerThreadPoolMutex = ca_mutex_new();
+        g_leServerThreadPoolMutex = oc_mutex_new();
         if (NULL == g_leServerThreadPoolMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_LEClientListMutex)
     {
-        g_LEClientListMutex = ca_mutex_new();
+        g_LEClientListMutex = oc_mutex_new();
         if (NULL == g_LEClientListMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
             return CA_STATUS_FAILED;
         }
     }
@@ -494,22 +528,22 @@ CAResult_t CAInitGattServerMutexVariables()
 void CATerminateGattServerMutexVariables()
 {
     OIC_LOG(DEBUG, TAG, "IN");
-    ca_mutex_free(g_leServerStateMutex);
+    oc_mutex_free(g_leServerStateMutex);
     g_leServerStateMutex = NULL;
 
-    ca_mutex_free(g_leServiceMutex);
+    oc_mutex_free(g_leServiceMutex);
     g_leServiceMutex = NULL;
 
-    ca_mutex_free(g_leCharacteristicMutex);
+    oc_mutex_free(g_leCharacteristicMutex);
     g_leCharacteristicMutex = NULL;
 
-    ca_mutex_free(g_leReqRespCbMutex);
+    oc_mutex_free(g_leReqRespCbMutex);
     g_leReqRespCbMutex = NULL;
 
-    ca_mutex_free(g_leServerThreadPoolMutex);
+    oc_mutex_free(g_leServerThreadPoolMutex);
     g_leServerThreadPoolMutex = NULL;
 
-    ca_mutex_free(g_LEClientListMutex);
+    oc_mutex_free(g_LEClientListMutex);
     g_LEClientListMutex = NULL;
 
     OIC_LOG(DEBUG, TAG, "OUT");
@@ -579,9 +613,9 @@ CAResult_t CADeInitLEGattServer()
 void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
 {
     OIC_LOG(DEBUG, TAG, "IN");
-    ca_mutex_lock(g_leServerThreadPoolMutex);
+    oc_mutex_lock(g_leServerThreadPoolMutex);
     g_leServerThreadPool = handle;
-    ca_mutex_unlock(g_leServerThreadPoolMutex);
+    oc_mutex_unlock(g_leServerThreadPoolMutex);
     OIC_LOG(DEBUG, TAG, "OUT");
 }
 
@@ -595,16 +629,16 @@ CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
 
     bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
 
-    ca_mutex_lock(g_leServiceMutex);
+    oc_mutex_lock(g_leServiceMutex);
     int ret = bt_gatt_service_create(serviceUUID, type, &g_gattSvcPath);
     if (0 != ret)
     {
-        ca_mutex_unlock(g_leServiceMutex);
+        oc_mutex_unlock(g_leServiceMutex);
         OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
                     CALEGetErrorMsg(ret));
         return CA_STATUS_FAILED;
     }
-    ca_mutex_unlock(g_leServiceMutex);
+    oc_mutex_unlock(g_leServiceMutex);
 
     if (g_gattSvcPath)
     {
@@ -619,7 +653,7 @@ void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h s
                                          bt_gatt_h charPath, int offset, char *charValue,
                                          int charValueLen, void *userData)
 {
-    OIC_LOG(DEBUG, TAG, "IN");
+    OIC_LOG(INFO, TAG, "IN - WriteCharCB");
 
     if (NULL == charValue || NULL == remoteAddress)
     {
@@ -639,22 +673,22 @@ void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h s
 
     memcpy(data, charValue, charValueLen);
 
-    ca_mutex_lock(g_leReqRespCbMutex);
+    oc_mutex_lock(g_leReqRespCbMutex);
     if (NULL == g_leServerDataReceivedCallback)
     {
         OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!");
-        ca_mutex_unlock(g_leReqRespCbMutex);
+        oc_mutex_unlock(g_leReqRespCbMutex);
         OICFree(data);
         return;
     }
 
-    OIC_LOG(DEBUG, TAG, "Sending data up !");
+    OIC_LOG(INFO, TAG, "Sending data up !");
     uint32_t sentLength = 0;
     g_leServerDataReceivedCallback(remoteAddress, data, charValueLen,
                                     &sentLength);
-    ca_mutex_unlock(g_leReqRespCbMutex);
+    oc_mutex_unlock(g_leReqRespCbMutex);
     OICFree(data);
-    OIC_LOG(DEBUG, TAG, "OUT");
+    OIC_LOG(INFO, TAG, "OUT - WriteCharCB");
 }
 
 CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
@@ -697,7 +731,7 @@ CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const ch
     int properties;
     if (read)
     {
-        properties = BT_GATT_PROPERTY_NOTIFY | BT_GATT_PROPERTY_READ;
+        properties = BT_GATT_PROPERTY_INDICATE | BT_GATT_PROPERTY_READ;
     }
     else
     {
@@ -740,7 +774,7 @@ CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const ch
         return CA_STATUS_FAILED;
     }
 
-    ca_mutex_lock(g_leCharacteristicMutex);
+    oc_mutex_lock(g_leCharacteristicMutex);
 
     if (read)
     {
@@ -752,7 +786,7 @@ CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const ch
                                         &descriptor);
         if (0 != ret)
         {
-            ca_mutex_unlock(g_leCharacteristicMutex);
+            oc_mutex_unlock(g_leCharacteristicMutex);
             OIC_LOG_V(ERROR, TAG,
                       "bt_gatt_descriptor_create  failed with ret[%s]",
                       CALEGetErrorMsg(ret));
@@ -762,7 +796,7 @@ CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const ch
         ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
         if (0 != ret)
         {
-            ca_mutex_unlock(g_leCharacteristicMutex);
+            oc_mutex_unlock(g_leCharacteristicMutex);
             OIC_LOG_V(ERROR, TAG,
                       "bt_gatt_characteristic_add_descriptor  failed with ret[%s]",
                       CALEGetErrorMsg(ret));
@@ -776,7 +810,7 @@ CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const ch
         g_gattWriteCharPath = charPath;
     }
 
-    ca_mutex_unlock(g_leCharacteristicMutex);
+    oc_mutex_unlock(g_leCharacteristicMutex);
 
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
@@ -792,12 +826,12 @@ CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_
 
     OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address);
 
-    ca_mutex_lock(g_leCharacteristicMutex);
+    oc_mutex_lock(g_leCharacteristicMutex);
 
     if (NULL  == g_gattReadCharPath)
     {
         OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
-        ca_mutex_unlock(g_leCharacteristicMutex);
+        oc_mutex_unlock(g_leCharacteristicMutex);
         return CA_STATUS_FAILED;
     }
 
@@ -806,7 +840,7 @@ CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_
     {
         OIC_LOG_V(ERROR, TAG,
                   "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret));
-        ca_mutex_unlock(g_leCharacteristicMutex);
+        oc_mutex_unlock(g_leCharacteristicMutex);
         return CA_STATUS_FAILED;
     }
 
@@ -816,11 +850,11 @@ CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_
     {
         OIC_LOG_V(ERROR, TAG,
                   "bt_gatt_server_notify failed with return [%s]", CALEGetErrorMsg(ret));
-        ca_mutex_unlock(g_leCharacteristicMutex);
+        oc_mutex_unlock(g_leCharacteristicMutex);
         return CA_STATUS_FAILED;
     }
 
-    ca_mutex_unlock(g_leCharacteristicMutex);
+    oc_mutex_unlock(g_leCharacteristicMutex);
 
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
@@ -832,12 +866,12 @@ CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uin
 
     VERIFY_NON_NULL(charValue, TAG, "charValue");
 
-    ca_mutex_lock(g_leCharacteristicMutex);
+    oc_mutex_lock(g_leCharacteristicMutex);
 
     if (NULL  == g_gattReadCharPath)
     {
         OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
-        ca_mutex_unlock(g_leCharacteristicMutex);
+        oc_mutex_unlock(g_leCharacteristicMutex);
         return CA_STATUS_FAILED;
     }
 
@@ -845,7 +879,7 @@ CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uin
     if (0 != ret)
     {
         OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret));
-        ca_mutex_unlock(g_leCharacteristicMutex);
+        oc_mutex_unlock(g_leCharacteristicMutex);
         return CA_STATUS_FAILED;
     }
 
@@ -855,11 +889,11 @@ CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uin
     {
         OIC_LOG_V(ERROR, TAG,
                   "bt_gatt_server_notify failed with return[%s]", CALEGetErrorMsg(ret));
-        ca_mutex_unlock(g_leCharacteristicMutex);
+        oc_mutex_unlock(g_leCharacteristicMutex);
         return CA_STATUS_FAILED;
     }
 
-    ca_mutex_unlock(g_leCharacteristicMutex);
+    oc_mutex_unlock(g_leCharacteristicMutex);
 
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
@@ -869,9 +903,9 @@ void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
-    ca_mutex_lock(g_leReqRespCbMutex);
+    oc_mutex_lock(g_leReqRespCbMutex);
     g_leServerDataReceivedCallback = callback;
-    ca_mutex_unlock(g_leReqRespCbMutex);
+    oc_mutex_unlock(g_leReqRespCbMutex);
 
     OIC_LOG(DEBUG, TAG, "OUT");
 }
@@ -880,3 +914,21 @@ void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
 {
     g_serverErrorCallback = callback;
 }
+
+bool CALEServerIsConnected(const char* address)
+{
+    //@Todo
+    return true;
+}
+
+uint16_t CALEServerGetMtuSize(const char* address)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    VERIFY_NON_NULL_RET(address, TAG, "address is null",
+                        CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_MTU_HEADER_SIZE);
+    //@Todo
+    OIC_LOG(INFO, TAG,
+            "bt_device_get_att_mtu is not supported");
+    return CA_SUPPORTED_BLE_MTU_SIZE - CA_BLE_MTU_HEADER_SIZE;
+}
+
index 400f81f..f310885 100644 (file)
 #include <bluetooth.h>
 #include <bluetooth_type.h>
 #include <bluetooth_internal.h>
-
+#ifdef BLE_MCD
+#include <bluetooth_product.h>
+#endif
 #include "caadapterinterface.h"
 #include "logger.h"
 #include "cathreadpool.h"
 #include "caleinterface.h"
 
+#if defined(__TIZEN__) && defined(LE_ADAPTER) && defined(BLE_CUSTOM_ADVERTISE)
+/**
+ * Used to Start Server advertise send data
+ */
+CAResult_t CAsetServerAdvertisementData(const char *data, int length);
+
+
+/**
+ * Used to Start Server  send  response data
+ */
+CAResult_t CAsetServerSanResponseData(const char *data, int length);
+#endif
+
 /**
  * Used to initialize gatt server.
  *
@@ -78,7 +93,17 @@ CAResult_t CAInitGattServerMutexVariables();
  * @retval  ::CA_STATUS_INVALID_PARAM  Invalid input arguments.
  * @retval  ::CA_STATUS_FAILED Operation failed.
  */
-CAResult_t CALEStartAdvertise(const char *serviceUUID);
+CAResult_t CALEStartAdvertise();
+
+/**
+ * Used to start advertising with service UUID.
+ *
+ * @return  ::CA_STATUS_OK or Appropriate error code.
+ * @retval  ::CA_STATUS_OK  Successful.
+ * @retval  ::CA_STATUS_INVALID_PARAM  Invalid input arguments.
+ * @retval  ::CA_STATUS_FAILED Operation failed.
+ */
+CAResult_t CALEStartAdvertiseImpl(const char *serviceUUID);
 
 /**
  * Used to stop advertising.
@@ -145,9 +170,16 @@ CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const ch
  * @param[in] len            The length of @a value
  * @param[in] user_data      The user data passed from the registration function
  */
+#ifdef BLE_TIZEN_30
+void CALEGattRemoteCharacteristicWriteCb(const char *remoteAddress, int request_id,
+                                         bt_gatt_server_h server, bt_gatt_h gatt_handle,
+                                         bool response_needed, int offset, const char *charValue,
+                                         int charLen, void *userData);
+#else
 void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server,
-                                         bt_gatt_h charPath, int offset, char *charValue,
-                                         int charValueLen, void *userData);
+                                         bt_gatt_h gatt_handle, int offset, char *charValue,
+                                         int charLen, void *userData);
+#endif
 
 /**
  * Setting the connection state changed callback.
@@ -155,5 +187,19 @@ void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h s
  */
 void CASetLEConnectionStateChangedCallback(CALEConnectionStateChangedCallback connStateCb);
 
+/**
+ * check connection status.
+ * @param[in] address      the address of the remote device.
+ * @return  true or false.
+ */
+bool CALEServerIsConnected(const char* address);
+
+/**
+ * get MTU size.
+ * @param[in] address      the address of the remote device.
+ * @return  mtu size negotiated from remote device.
+ */
+uint16_t CALEServerGetMtuSize(const char* address);
+
 #endif /* TZ_BLE_SERVER_H_ */
 
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/tizen/caleserver_mcd.c b/resource/csdk/connectivity/src/bt_le_adapter/tizen/caleserver_mcd.c
new file mode 100644 (file)
index 0000000..a7273e7
--- /dev/null
@@ -0,0 +1,1117 @@
+/******************************************************************
+*
+* 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 "caleserver.h"
+#include "cacommon.h"
+#include "cacommonutil.h"
+#include "octhread.h"
+#include "caqueueingthread.h"
+#include "cagattservice.h"
+#include "oic_string.h"
+#include "oic_malloc.h"
+#include "caleutil.h"
+
+/**
+ * Logging tag for module name
+ */
+//#define TAG "OIC_CA_LE_SERVER_MCD"
+#define TAG BLE_SERVER_MCD_TAG
+/**
+ * Initial buffer size for Gatt Server.
+ */
+#define CA_LE_INITIAL_BUF_SIZE 512
+
+/**
+ * The handle of the OIC server.
+ */
+static bt_gatt_server_h g_gattServer = NULL;
+
+/**
+ * The handle of the OIC service.
+ */
+static bt_gatt_h g_gattSvcPath = NULL;
+
+/**
+ * The handle of the OIC read characteristics.
+ */
+static bt_gatt_h g_gattReadCharPath = NULL;
+
+/**
+ * The handle of the OIC write characteristics.
+ */
+static bt_gatt_h g_gattWriteCharPath = NULL;
+
+/**
+ * The handle to control Bluetooth LE advertising.
+ */
+static bt_advertiser_h g_hAdvertiser = NULL;
+
+/**
+ * Callback register with LE adapter.  This callback is called on reception of any
+ * data from the remote device.
+ */
+static CABLEDataReceivedCallback g_leServerDataReceivedCallback = NULL;
+
+/**
+ * Callback to notify any error in LE adapter.
+ */
+static CABLEErrorHandleCallback g_serverErrorCallback = NULL;
+
+/**
+ * To keep the state of GATT server if started or not.
+ */
+static bool g_isLEGattServerStarted = false;
+
+/**
+ * Mutex to synchronize the calls to start and stop server.
+ */
+static oc_mutex g_leServerStateMutex = NULL;
+
+/**
+ * Mutex to synchronize writing operations on the characteristics.
+ */
+static  oc_mutex g_leCharacteristicMutex = NULL;
+
+/**
+ * Mutex to synchronize to creation of OIC service.
+ */
+static  oc_mutex g_leServiceMutex = NULL;
+
+/**
+ * Mutex to synchronize access to the requestResponse callback to be called
+ * when the data needs to be sent from GATTClient.
+ */
+static  oc_mutex g_leReqRespCbMutex = NULL;
+
+/**
+ * Mutex to synchronize the task to be pushed to thread pool.
+ */
+static oc_mutex g_leServerThreadPoolMutex = NULL;
+
+/**
+ * Reference to threadpool.
+ */
+static ca_thread_pool_t g_leServerThreadPool = NULL;
+
+/**
+ * GmainLoop to manage the threads to receive the callback from the platfrom.
+ */
+static GMainLoop *g_eventLoop = NULL;
+
+/**
+ * This contains the list of OIC clients connected to the server.
+ */
+static LEClientInfoList *g_LEClientList = NULL;
+
+/**
+ * Mutex to synchronize access to LE ClientList.
+ */
+static oc_mutex g_LEClientListMutex = NULL;
+
+static const int samsung_code = 117;
+
+static bool cutom_adv_flag = false;
+static char *custom_adv_data = NULL;
+static int custom_adv_data_length = 0;
+
+static bool cutom_scanrsp_flag = false;
+static char *custom_scanrsp_data = NULL;
+static int custom_scanrsp_data_length = 0;
+
+CAResult_t CAsetServerAdvertisementData(const char *data, int length)
+{
+    int res = 0;
+    CAResult_t ret = CA_STATUS_OK;
+
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    if(!data || strlen(data) <= 0 || length <=0 )
+    {
+        OIC_LOG(ERROR, TAG, "Invalid param is passed");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    oc_mutex_lock(g_leServerStateMutex);
+
+    cutom_adv_flag = true;
+    custom_adv_data = data;
+    custom_adv_data_length = length;
+
+    oc_mutex_unlock(g_leServerStateMutex);
+
+    OIC_LOG_V(DEBUG, TAG, "Custom advertise value has set as [%s]", custom_adv_data);
+    OIC_LOG(DEBUG, TAG, "OUT");
+
+    return ret;
+}
+
+CAResult_t CAsetServerSanResponseData(const char *data, int length)
+{
+    int res = 0;
+    CAResult_t ret = CA_STATUS_OK;
+
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    if(!data || strlen(data) <= 0 || length <=0 )
+    {
+        OIC_LOG(ERROR, TAG, "Invalid param is passed");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    oc_mutex_lock(g_leServerStateMutex);
+
+    cutom_scanrsp_flag = true;
+    custom_scanrsp_data = data;
+    custom_scanrsp_data_length = length;
+
+    oc_mutex_unlock(g_leServerStateMutex);
+
+    OIC_LOG_V(DEBUG, TAG, "Custom scan response value has set as [%s]", custom_scanrsp_data);
+    OIC_LOG(DEBUG, TAG, "OUT");
+
+    return ret;
+}
+
+void CALEGattServerConnectionStateChanged(bool connected, const char *remoteAddress)
+{
+    VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address");
+
+    CAResult_t res = CA_STATUS_OK;
+    if (connected)
+    {
+        OIC_LOG_V(DEBUG, TAG, "Connected to [%s]", remoteAddress);
+        char *addr = OICStrdup(remoteAddress);
+        oc_mutex_lock(g_LEClientListMutex);
+        res  = CAAddLEClientInfoToList(&g_LEClientList, addr);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "CAAddLEClientInfoToList failed");
+            oc_mutex_unlock(g_LEClientListMutex);
+            OICFree(addr);
+            return;
+        }
+        oc_mutex_unlock(g_LEClientListMutex);
+
+        res = CALEStopAdvertise();
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG_V(ERROR, TAG, "Failed to stop advertising [%d]", res);
+            return;
+        }
+    }
+    else
+    {
+        OIC_LOG_V(DEBUG, TAG, "Disconnected from [%s]", remoteAddress);
+        oc_mutex_lock(g_LEClientListMutex);
+        CARemoveLEClientInfoFromList(&g_LEClientList, remoteAddress);
+        oc_mutex_unlock(g_LEClientListMutex);
+
+        res = CALEStartAdvertise();
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG_V(ERROR, TAG, "Failed to start advertising [%d]", res);
+            return;
+        }
+    }
+}
+
+#ifdef BLE_TIZEN_30
+void CALEServerNotificationSentCB(int result, const char *remote_address, bt_gatt_server_h server,
+                                  bt_gatt_h characteristic, bool completed, void *user_data)
+#else
+void CALEServerNotificationSentCB(int result, char *remote_address, bt_gatt_server_h server,
+                                  bt_gatt_h characteristic, bool completed, void *user_data)
+#endif
+{
+    OIC_LOG_V(DEBUG, TAG, "Notification to the device[%s] result[%d]", remote_address, result);
+}
+
+CAResult_t CAStartLEGattServer()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    oc_mutex_lock(g_leServerStateMutex);
+    if (true == g_isLEGattServerStarted)
+    {
+        OIC_LOG(ERROR, TAG, "Gatt Server is already running");
+        oc_mutex_unlock(g_leServerStateMutex);
+        return CA_STATUS_OK;
+    }
+
+    CAResult_t ret = CAInitLEGattServer();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "CAInitLEGattServer failed[%d]", ret);
+        oc_mutex_unlock(g_leServerStateMutex);
+        CATerminateLEGattServer();
+        return CA_STATUS_FAILED;
+    }
+
+    ret  = CAAddNewLEServiceInGattServer(CA_GATT_SERVICE_UUID);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "CAAddNewLEServiceInGattServer failed[%d]", ret);
+        oc_mutex_unlock(g_leServerStateMutex);
+        CATerminateLEGattServer();
+        return CA_STATUS_FAILED;
+    }
+
+    static const char charReadUUID[] = CA_GATT_RESPONSE_CHRC_UUID;
+    char charReadValue[] = {33, 44, 55, 66}; // These are initial random values
+
+    // For Read Characteristics.
+    ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue,
+                                              CA_LE_INITIAL_BUF_SIZE, true);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
+        oc_mutex_unlock(g_leServerStateMutex);
+        CATerminateLEGattServer();
+        return CA_STATUS_FAILED;
+    }
+
+    static const char charWriteUUID[] = CA_GATT_REQUEST_CHRC_UUID;
+    char charWriteValue[] = {33, 44, 55, 66}; // These are initial random values
+
+
+    ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue,
+            CA_LE_INITIAL_BUF_SIZE, false); // For Write Characteristics.
+    if (CA_STATUS_OK != ret )
+    {
+        OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
+        oc_mutex_unlock(g_leServerStateMutex);
+        CATerminateLEGattServer();
+        return CA_STATUS_FAILED;
+    }
+
+    ret = CARegisterLEServicewithGattServer(g_gattSvcPath);
+    if (CA_STATUS_OK != ret )
+    {
+        OIC_LOG_V(ERROR, TAG, "CARegisterLEServicewithGattServer failed[%d]", ret);
+        oc_mutex_unlock(g_leServerStateMutex);
+        CATerminateLEGattServer();
+        return CA_STATUS_FAILED;
+    }
+
+    ret = CALEStartAdvertise();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret);
+        oc_mutex_unlock(g_leServerStateMutex);
+        CATerminateLEGattServer();
+        return CA_STATUS_FAILED;
+    }
+
+    g_isLEGattServerStarted = true;
+
+    oc_mutex_unlock(g_leServerStateMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CALENotificationCb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_handle,
+                        void *user_data)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    if (notify)
+    {
+        OIC_LOG(DEBUG, TAG, "Notification is subscribed by the client");
+        CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
+                           true, "notifyChar success");
+    }
+    else
+    {
+        CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
+                           false, "notifyChar failure");
+    }
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+CAResult_t CALEStartAdvertise()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    CAResult_t res = CALEStartAdvertiseImpl(CA_GATT_SERVICE_UUID);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG_V(ERROR, TAG, "CALEStartAdvertiseImpl failed[%d]", res);
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return res;
+}
+
+CAResult_t CALEStartAdvertiseImpl(const char *serviceUUID)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    int length;
+
+    int res = bt_adapter_le_create_advertiser(&g_hAdvertiser);
+    if (NULL == g_hAdvertiser || BT_ERROR_NONE != res)
+    {
+        OIC_LOG_V(ERROR, TAG, "g_hAdvertiser is NULL/ Result is %d", res);
+        return CA_STATUS_FAILED;
+    }
+
+    if (cutom_adv_flag == false) // Advertise with Default Service UUID
+    {
+        OIC_LOG(DEBUG, TAG, "Advertise with default Service UUID");
+
+        res = bt_adapter_le_add_advertising_service_uuid(g_hAdvertiser,
+                                                         BT_ADAPTER_LE_PACKET_ADVERTISING,
+                                                         serviceUUID);
+        if (BT_ERROR_NONE != res)
+        {
+            OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_service_uuid failed with ret[%s]",
+                      CALEGetErrorMsg(res));
+            return CA_STATUS_FAILED;
+        }
+    }
+    else // Advertise with custom advertise data
+    {
+        OIC_LOG(DEBUG, TAG, "Advertise with custom advertise data");
+
+        res = bt_adapter_le_add_advertising_manufacturer_data(g_hAdvertiser,BT_ADAPTER_LE_PACKET_ADVERTISING, samsung_code, custom_adv_data, custom_adv_data_length);
+        if (BT_ERROR_NONE != res)
+        {
+            OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_manufacturer_data failed(BT_ADAPTER_LE_PACKET_ADVERTISING) with ret[%s]",
+                      CALEGetErrorMsg(res));
+            return CA_STATUS_FAILED;
+        }
+
+    }
+
+    if(cutom_scanrsp_flag == false)
+    {
+        OIC_LOG(DEBUG, TAG, "Advertise with default scan response data");
+
+        res = bt_adapter_le_set_advertising_device_name(g_hAdvertiser,
+                                                        BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, true);
+        if (BT_ERROR_NONE != res)
+        {
+            OIC_LOG_V(ERROR, TAG, "bt_adapter_le_set_advertising_device_name failed with ret[%s]",
+                      CALEGetErrorMsg(res));
+            return CA_STATUS_FAILED;
+        }
+    }
+    else // Advertise with custom advertise data
+    {
+        OIC_LOG(DEBUG, TAG, "Advertise with custom scan response data");
+
+        res = bt_adapter_le_add_advertising_manufacturer_data(g_hAdvertiser,BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, samsung_code, custom_scanrsp_data, custom_scanrsp_data_length);
+        if (BT_ERROR_NONE != res)
+        {
+            OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_manufacturer_data(BT_ADAPTER_LE_PACKET_SCAN_RESPONSE) failed with ret[%s]",
+                      CALEGetErrorMsg(res));
+            return CA_STATUS_FAILED;
+        }
+
+    }
+
+    res = bt_adapter_le_start_advertising_new(g_hAdvertiser, NULL, NULL);
+    if (BT_ERROR_NONE != res)
+    {
+        OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_advertising_new failed with ret[%s]",
+                  CALEGetErrorMsg(res));
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CALEStopAdvertise()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    if (NULL != g_hAdvertiser)
+    {
+        int ret  = bt_adapter_le_stop_advertising(g_hAdvertiser);
+        if (0 != ret)
+        {
+            OIC_LOG_V(ERROR, TAG,
+                      "bt_adapter_le_stop_advertising failed with ret[%s]", CALEGetErrorMsg(ret));
+        }
+
+        ret = bt_adapter_le_destroy_advertiser(g_hAdvertiser);
+        if (0 != ret)
+        {
+            OIC_LOG_V(ERROR, TAG,
+                      "bt_adapter_le_destroy_advertiser failed with ret[%s]", CALEGetErrorMsg(ret));
+        }
+        g_hAdvertiser = NULL;
+    }
+    else
+    {
+        OIC_LOG(ERROR, TAG, "Advertising is not running");
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAStopLEGattServer()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    oc_mutex_lock(g_leServerStateMutex);
+
+    if (false == g_isLEGattServerStarted)
+    {
+        OIC_LOG(ERROR, TAG, "Gatt Server is not running to stop");
+        oc_mutex_unlock(g_leServerStateMutex);
+        return CA_STATUS_OK;
+    }
+
+    g_isLEGattServerStarted = false;
+    cutom_adv_flag = false;
+    custom_adv_data = NULL;
+    custom_adv_data_length = 0;
+    cutom_scanrsp_flag = false;
+    custom_scanrsp_data = NULL;
+    custom_scanrsp_data_length = 0;
+
+    oc_mutex_lock(g_LEClientListMutex);
+    CADisconnectAllClient(g_LEClientList);
+    g_LEClientList = NULL;
+    oc_mutex_unlock(g_LEClientListMutex);
+
+    CAResult_t res = CALEStopAdvertise();
+    {
+        OIC_LOG_V(ERROR, TAG, "CALEStopAdvertise failed with ret[%d]", res);
+    }
+
+    res = CADeInitLEGattServer();
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG_V(ERROR, TAG, "CADeInitLEGattService failed with ret[%d]", res);
+    }
+
+    GMainContext  *context_event_loop = NULL;
+    // Required for waking up the thread which is running in gmain loop
+    if (NULL != g_eventLoop)
+    {
+        context_event_loop = g_main_loop_get_context(g_eventLoop);
+
+        if (context_event_loop)
+        {
+            OIC_LOG_V(DEBUG,  TAG, "g_eventLoop context %x", context_event_loop);
+            g_main_context_wakeup(context_event_loop);
+
+            // Kill g main loops and kill threads
+            g_main_loop_quit(g_eventLoop);
+        }
+        g_eventLoop = NULL;
+    }
+    else
+    {
+        OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
+    }
+
+    oc_mutex_unlock(g_leServerStateMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAInitializeLEGattServer()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    CAResult_t ret = CAInitGattServerMutexVariables();
+    if (CA_STATUS_OK != ret )
+    {
+        OIC_LOG(ERROR, TAG, "CAInitGattServerMutexVariables failed!");
+        CATerminateGattServerMutexVariables();
+        return CA_SERVER_NOT_STARTED;
+    }
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return ret;
+}
+
+void CATerminateLEGattServer()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    // Service and characteristics path will be freed by the platform.
+    oc_mutex_lock(g_leServiceMutex);
+    g_gattSvcPath = NULL;
+    oc_mutex_unlock(g_leServiceMutex);
+
+    oc_mutex_lock(g_leCharacteristicMutex);
+    g_gattReadCharPath = NULL;
+    g_gattWriteCharPath = NULL;
+    oc_mutex_unlock(g_leCharacteristicMutex);
+
+    oc_mutex_lock(g_leServerThreadPoolMutex);
+    g_leServerThreadPool = NULL;
+    oc_mutex_unlock(g_leServerThreadPoolMutex);
+
+    // Terminating all mutex variables.
+    CATerminateGattServerMutexVariables();
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+CAResult_t CAInitGattServerMutexVariables()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    if (NULL == g_leServerStateMutex)
+    {
+        g_leServerStateMutex = oc_mutex_new();
+        if (NULL == g_leServerStateMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_leServiceMutex)
+    {
+        g_leServiceMutex = oc_mutex_new();
+        if (NULL == g_leServiceMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_leCharacteristicMutex)
+    {
+        g_leCharacteristicMutex = oc_mutex_new();
+        if (NULL == g_leCharacteristicMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_leReqRespCbMutex)
+    {
+        g_leReqRespCbMutex = oc_mutex_new();
+        if (NULL == g_leReqRespCbMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_leServerThreadPoolMutex)
+    {
+        g_leServerThreadPoolMutex = oc_mutex_new();
+        if (NULL == g_leServerThreadPoolMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_LEClientListMutex)
+    {
+        g_LEClientListMutex = oc_mutex_new();
+        if (NULL == g_LEClientListMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CATerminateGattServerMutexVariables()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    oc_mutex_free(g_leServerStateMutex);
+    g_leServerStateMutex = NULL;
+
+    oc_mutex_free(g_leServiceMutex);
+    g_leServiceMutex = NULL;
+
+    oc_mutex_free(g_leCharacteristicMutex);
+    g_leCharacteristicMutex = NULL;
+
+    oc_mutex_free(g_leReqRespCbMutex);
+    g_leReqRespCbMutex = NULL;
+
+    oc_mutex_free(g_leServerThreadPoolMutex);
+    g_leServerThreadPoolMutex = NULL;
+
+    oc_mutex_free(g_LEClientListMutex);
+    g_LEClientListMutex = NULL;
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+CAResult_t CAInitLEGattServer()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    int ret =  bt_gatt_server_initialize();
+    if (0 != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "bt_gatt_server_initialize failed with ret[%s]",
+                  CALEGetErrorMsg(ret));
+        return CA_STATUS_FAILED;
+    }
+
+    if (!g_gattServer)
+    {
+        OIC_LOG(DEBUG, TAG, "g_gattServer is NULL. create gatt server..");
+        ret = bt_gatt_server_create(&g_gattServer);
+        if (0 != ret)
+        {
+            OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]",
+                      CALEGetErrorMsg(ret));
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CADeInitLEGattServer()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    int ret = bt_gatt_server_unregister_all_services(g_gattServer);
+    if (0 != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "bt_gatt_server_unregister_all_services failed with ret[%s]",
+                  CALEGetErrorMsg(ret));
+        return CA_STATUS_FAILED;
+    }
+
+    ret = bt_gatt_server_destroy(g_gattServer);
+    if (0 != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "bt_gatt_server_destroy failed with ret[%s]",
+                  CALEGetErrorMsg(ret));
+        return CA_STATUS_FAILED;
+    }
+    g_gattServer = NULL;
+
+    ret =  bt_gatt_server_deinitialize();
+    if (0 != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "bt_gatt_server_deinitialize failed with ret[%s]",
+                  CALEGetErrorMsg(ret));
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    oc_mutex_lock(g_leServerThreadPoolMutex);
+    g_leServerThreadPool = handle;
+    oc_mutex_unlock(g_leServerThreadPoolMutex);
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    VERIFY_NON_NULL(serviceUUID, TAG, "serviceUUID");
+
+    OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID);
+
+    bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
+
+    oc_mutex_lock(g_leServiceMutex);
+    int ret = bt_gatt_service_create(serviceUUID, type, &g_gattSvcPath);
+    if (0 != ret)
+    {
+        oc_mutex_unlock(g_leServiceMutex);
+        OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
+                    CALEGetErrorMsg(ret));
+        return CA_STATUS_FAILED;
+    }
+    oc_mutex_unlock(g_leServiceMutex);
+
+    if (g_gattSvcPath)
+    {
+        OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)g_gattSvcPath);
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+#ifdef BLE_TIZEN_30
+void CALEGattRemoteCharacteristicWriteCb(const char *remoteAddress, int request_id,
+                                         bt_gatt_server_h server, bt_gatt_h gatt_handle,
+                                         bool response_needed, int offset, const char *charValue,
+                                         int charLen, void *userData)
+#else
+void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server,
+                                         bt_gatt_h gatt_handle, int offset, char *charValue,
+                                         int charLen, void *userData)
+#endif
+{
+    OIC_LOG(INFO, TAG, "IN - WriteCharCB");
+
+    if (NULL == charValue || NULL == remoteAddress)
+    {
+        OIC_LOG(ERROR, TAG, "Param callback values are NULL");
+        return;
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "len [%d]", charLen);
+
+    uint8_t *data = OICMalloc(charLen);
+    if (NULL == data)
+    {
+        OIC_LOG(ERROR, TAG, "Malloc failed!");
+        return;
+    }
+
+    memcpy(data, charValue, charLen);
+
+    oc_mutex_lock(g_leReqRespCbMutex);
+    if (NULL == g_leServerDataReceivedCallback)
+    {
+        OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!");
+        oc_mutex_unlock(g_leReqRespCbMutex);
+        OICFree(data);
+        return;
+    }
+
+    OIC_LOG(INFO, TAG, "Sending data up !");
+    uint32_t sentLength = 0;
+    g_leServerDataReceivedCallback(remoteAddress, data, charLen,
+                                    &sentLength);
+    oc_mutex_unlock(g_leReqRespCbMutex);
+    OICFree(data);
+
+#ifdef BLE_TIZEN_30
+    //response
+    OIC_LOG_V(INFO, TAG, "response_needed flag : %d", response_needed);
+    if (response_needed)
+    {
+        OIC_LOG(INFO, TAG, "send response to remote client");
+        bt_gatt_server_send_response(request_id,
+                BT_GATT_REQUEST_TYPE_WRITE, offset,
+                BT_ERROR_NONE, NULL, 0);
+    }
+#endif
+
+    OIC_LOG(INFO, TAG, "OUT - WriteCharCB");
+}
+
+CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    VERIFY_NON_NULL(svcPath, TAG, "svcPath");
+
+    OIC_LOG_V(DEBUG, TAG, "svcPath:%s", svcPath);
+
+    int ret = bt_gatt_server_register_service(g_gattServer, svcPath);
+    if (0 != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "bt_gatt_server_register_service failed with ret[%s]",
+                  CALEGetErrorMsg(ret));
+        return CA_STATUS_FAILED;
+    }
+
+    ret = bt_gatt_server_start();
+    if(0 != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "bt_gatt_server_start failed with ret[%s]",
+                CALEGetErrorMsg(ret));
+        return CA_STATUS_FAILED;
+    }
+
+#ifdef BLE_TIZEN_30
+    ret = bt_gatt_server_set_write_value_requested_cb(g_gattWriteCharPath,
+#else
+    ret = bt_gatt_server_set_value_changed_cb(g_gattWriteCharPath,
+#endif
+                                              CALEGattRemoteCharacteristicWriteCb, NULL);
+
+    if (0 != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_value_changed_cb failed with ret[%s]",
+                  CALEGetErrorMsg(ret));
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const char *charUUID,
+                                               const char *charValue, int charValueLen, bool read)
+{
+
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
+    int properties;
+    if (read)
+    {
+        properties = BT_GATT_PROPERTY_INDICATE;
+    }
+    else
+    {
+        properties = BT_GATT_PROPERTY_WRITE;
+    }
+
+    bt_gatt_h charPath = NULL;
+
+    int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue,
+                                            charValueLen, &charPath);
+
+    if (0 != ret || NULL == charPath)
+    {
+        OIC_LOG_V(ERROR, TAG,
+                  "bt_gatt_add_characteristic  failed with ret [%s]", CALEGetErrorMsg(ret));
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG_V(DEBUG, TAG,
+              "bt_gatt_characteristic_create charPath obtained: %s", (char *)charPath);
+
+    if (read)
+    {
+#ifdef BLE_TIZEN_30
+        ret = bt_gatt_server_set_characteristic_notification_state_change_cb(charPath,
+                                                                             CALENotificationCb,
+                                                                             NULL);
+#else
+        ret = bt_gatt_server_set_notification_state_change_cb(charPath, CALENotificationCb, NULL);
+#endif
+        if (0 != ret)
+        {
+            OIC_LOG_V(ERROR, TAG,
+#ifdef BLE_TIZEN_30
+                      "bt_gatt_server_set_characteristic_notification_state_change_cb failed with ret[%s]",
+#else
+                      "bt_gatt_server_set_notification_state_change_cb  failed with ret[%s]",
+#endif
+                      CALEGetErrorMsg(ret));
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    ret =  bt_gatt_service_add_characteristic(svcPath, charPath);
+    if (0 != ret)
+    {
+        OIC_LOG_V(ERROR, TAG,
+                  "bt_gatt_service_add_characteristic  failed with ret[%s]",
+                  CALEGetErrorMsg(ret));
+        return CA_STATUS_FAILED;
+    }
+
+    oc_mutex_lock(g_leCharacteristicMutex);
+
+    if (read)
+    {
+        char desc_value[2] = {1, 0};  // Notification enabled.
+        bt_gatt_h descriptor = NULL;
+        permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
+        ret = bt_gatt_descriptor_create(CA_GATT_CONFIGURATION_DESC_UUID, permissions,
+                                        desc_value, sizeof(desc_value),
+                                        &descriptor);
+        if (0 != ret)
+        {
+            oc_mutex_unlock(g_leCharacteristicMutex);
+            OIC_LOG_V(ERROR, TAG,
+                      "bt_gatt_descriptor_create  failed with ret[%s]",
+                      CALEGetErrorMsg(ret));
+            return CA_STATUS_FAILED;
+        }
+
+        ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
+        if (0 != ret)
+        {
+            oc_mutex_unlock(g_leCharacteristicMutex);
+            OIC_LOG_V(ERROR, TAG,
+                      "bt_gatt_characteristic_add_descriptor  failed with ret[%s]",
+                      CALEGetErrorMsg(ret));
+            return CA_STATUS_FAILED;
+        }
+
+        g_gattReadCharPath = charPath;
+    }
+    else
+    {
+        g_gattWriteCharPath = charPath;
+    }
+
+    oc_mutex_unlock(g_leCharacteristicMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_t *charValue,
+                                               uint32_t charValueLen)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    VERIFY_NON_NULL(charValue, TAG, "charValue");
+    VERIFY_NON_NULL(address, TAG, "address");
+
+    OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address);
+
+    oc_mutex_lock(g_leCharacteristicMutex);
+
+    if (NULL  == g_gattReadCharPath)
+    {
+        OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
+        oc_mutex_unlock(g_leCharacteristicMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
+    if (0 != ret)
+    {
+        OIC_LOG_V(ERROR, TAG,
+                  "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret));
+        oc_mutex_unlock(g_leCharacteristicMutex);
+        return CA_STATUS_FAILED;
+    }
+
+#ifdef BLE_TIZEN_30
+    ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
+                                                             CALEServerNotificationSentCB,
+                                                             address, NULL);
+#else
+    ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
+                                address, NULL);
+#endif
+
+    if (0 != ret)
+    {
+        OIC_LOG_V(ERROR, TAG,
+#ifdef BLE_TIZEN_30
+                  "bt_gatt_server_notify_characteristic_changed_value failed with return [%s]",
+#else
+                  "bt_gatt_server_notify failed with return [%s]",
+#endif
+                  CALEGetErrorMsg(ret));
+        oc_mutex_unlock(g_leCharacteristicMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    oc_mutex_unlock(g_leCharacteristicMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uint32_t charValueLen)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    VERIFY_NON_NULL(charValue, TAG, "charValue");
+
+    oc_mutex_lock(g_leCharacteristicMutex);
+
+    if (NULL  == g_gattReadCharPath)
+    {
+        OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
+        oc_mutex_unlock(g_leCharacteristicMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
+    if (0 != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret));
+        oc_mutex_unlock(g_leCharacteristicMutex);
+        return CA_STATUS_FAILED;
+    }
+
+#ifdef BLE_TIZEN_30
+    ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
+                                                             CALEServerNotificationSentCB,
+                                                             NULL, NULL);
+#else
+    ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
+                                NULL, NULL);
+#endif
+    if (0 != ret)
+    {
+        OIC_LOG_V(ERROR, TAG,
+#ifdef BLE_TIZEN_30
+                  "bt_gatt_server_notify_characteristic_changed_value failed with return[%s]",
+#else
+                  "bt_gatt_server_notify failed with return[%s]",
+#endif
+                  CALEGetErrorMsg(ret));
+        oc_mutex_unlock(g_leCharacteristicMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    oc_mutex_unlock(g_leCharacteristicMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    oc_mutex_lock(g_leReqRespCbMutex);
+    g_leServerDataReceivedCallback = callback;
+    oc_mutex_unlock(g_leReqRespCbMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
+{
+    g_serverErrorCallback = callback;
+}
+
+bool CALEServerIsConnected(const char* address)
+{
+    //@Todo
+    return true;
+}
+
+uint16_t CALEServerGetMtuSize(const char* address)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    VERIFY_NON_NULL_RET(address, TAG, "address is null", CA_DEFAULT_BLE_MTU_SIZE);
+
+    unsigned int mtu;
+    int ret = bt_device_get_att_mtu(address, &mtu);
+    if (0 != ret)
+    {
+        OIC_LOG_V(ERROR, TAG,
+                  "bt_device_get_att_mtu failed with return [%s]", CALEGetErrorMsg(ret));
+        return CA_DEFAULT_BLE_MTU_SIZE;
+    }
+    OIC_LOG_V(INFO, TAG, "mtu size(including header) from bt_device_get_att_mtu is %d", mtu);
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return mtu - CA_BLE_MTU_HEADER_SIZE;
+}
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/tizen/caleserver_vd.c b/resource/csdk/connectivity/src/bt_le_adapter/tizen/caleserver_vd.c
new file mode 100755 (executable)
index 0000000..ef3654b
--- /dev/null
@@ -0,0 +1,1046 @@
+/******************************************************************
+*
+* 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 "caleserver.h"
+#include "cacommon.h"
+#include "cacommonutil.h"
+#include "octhread.h"
+#include "caqueueingthread.h"
+#include "cagattservice.h"
+#include "oic_string.h"
+#include "oic_malloc.h"
+#include "caleutil.h"
+
+/**
+ * Logging tag for module name
+ */
+#define TAG "OIC_CA_LE_SERVER_VD"
+/**
+ * Initial buffer size for Gatt Server.
+ */
+#define CA_LE_INITIAL_BUF_SIZE 512
+
+/**
+ * The handle of the OIC server.
+ */
+static bt_gatt_server_h g_gattServer = NULL;
+
+/**
+ * The handle of the OIC service.
+ */
+static bt_gatt_h g_gattSvcPath = NULL;
+
+/**
+ * The handle of the OIC read characteristics.
+ */
+static bt_gatt_h g_gattReadCharPath = NULL;
+
+/**
+ * The handle of the OIC write characteristics.
+ */
+static bt_gatt_h g_gattWriteCharPath = NULL;
+
+/**
+ * The handle to control Bluetooth LE advertising.
+ */
+static bt_advertiser_h g_hAdvertiser = NULL;
+
+/**
+ * Callback register with LE adapter.  This callback is called on reception of any
+ * data from the remote device.
+ */
+static CABLEDataReceivedCallback g_leServerDataReceivedCallback = NULL;
+
+/**
+ * Callback to notify any error in LE adapter.
+ */
+static CABLEErrorHandleCallback g_serverErrorCallback = NULL;
+
+/**
+ * To keep the state of GATT server if started or not.
+ */
+static bool g_isLEGattServerStarted = false;
+
+/**
+ * Mutex to synchronize the calls to start and stop server.
+ */
+static oc_mutex g_leServerStateMutex = NULL;
+
+/**
+ * Mutex to synchronize writing operations on the characteristics.
+ */
+static  oc_mutex g_leCharacteristicMutex = NULL;
+
+/**
+ * Mutex to synchronize to creation of OIC service.
+ */
+static  oc_mutex g_leServiceMutex = NULL;
+
+/**
+ * Mutex to synchronize access to the requestResponse callback to be called
+ * when the data needs to be sent from GATTClient.
+ */
+static  oc_mutex g_leReqRespCbMutex = NULL;
+
+/**
+ * Mutex to synchronize the task to be pushed to thread pool.
+ */
+static oc_mutex g_leServerThreadPoolMutex = NULL;
+
+/**
+ * Reference to threadpool.
+ */
+static ca_thread_pool_t g_leServerThreadPool = NULL;
+
+/**
+ * GmainLoop to manage the threads to receive the callback from the platfrom.
+ */
+static GMainLoop *g_eventLoop = NULL;
+
+/**
+ * This contains the list of OIC clients connected to the server.
+ */
+static LEClientInfoList *g_LEClientList = NULL;
+
+/**
+ * Mutex to synchronize access to LE ClientList.
+ */
+static oc_mutex g_LEClientListMutex = NULL;
+
+/**
+ * State of connect state
+ */
+static bool g_LEConnectedState = false;
+
+void CALEGattServerConnectionStateChanged(bool connected, const char *remoteAddress)
+{
+    VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address");
+
+    CAResult_t res = CA_STATUS_OK;
+    if (connected)
+    {
+        OIC_LOG_V(DEBUG, TAG, "Connected to [%s]", remoteAddress);
+        g_LEConnectedState = true;
+        char *addr = OICStrdup(remoteAddress);
+        oc_mutex_lock(g_LEClientListMutex);
+        res  = CAAddLEClientInfoToList(&g_LEClientList, addr);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "CAAddLEClientInfoToList failed");
+            oc_mutex_unlock(g_LEClientListMutex);
+            OICFree(addr);
+            return;
+        }
+        oc_mutex_unlock(g_LEClientListMutex);
+
+        /*
+         * TV Easysetup does not use IoTivity BLE advertisement.
+         */
+
+        // res = CALEStopAdvertise();
+        // if (CA_STATUS_OK != res)
+        // {
+        //     OIC_LOG_V(ERROR, TAG, "Failed to stop advertising [%d]", res);
+        //     return;
+        // }
+    }
+    else
+    {
+        OIC_LOG_V(DEBUG, TAG, "Disconnected from [%s]", remoteAddress);
+        g_LEConnectedState = false;
+        oc_mutex_lock(g_LEClientListMutex);
+        CARemoveLEClientInfoFromList(&g_LEClientList, remoteAddress);
+        oc_mutex_unlock(g_LEClientListMutex);
+
+        /*
+         * TV Easysetup does not use IoTivity BLE advertisement.
+         */
+
+        // res = CALEStartAdvertise();
+        // if (CA_STATUS_OK != res)
+        // {
+        //     OIC_LOG_V(ERROR, TAG, "Failed to start advertising [%d]", res);
+        //     return;
+        // }
+    }
+}
+
+#ifdef BLE_TIZEN_30
+void CALEServerNotificationSentCB(int result, const char *remote_address, bt_gatt_server_h server,
+                                  bt_gatt_h characteristic, bool completed, void *user_data)
+#else
+void CALEServerNotificationSentCB(int result, char *remote_address, bt_gatt_server_h server,
+                                  bt_gatt_h characteristic, bool completed, void *user_data)
+#endif
+{
+    OIC_LOG_V(DEBUG, TAG, "Notification to the device[%s] result[%d]", remote_address, result);
+}
+
+CAResult_t CAStartLEGattServer()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    oc_mutex_lock(g_leServerStateMutex);
+    if (true == g_isLEGattServerStarted)
+    {
+        OIC_LOG(ERROR, TAG, "Gatt Server is already running");
+        oc_mutex_unlock(g_leServerStateMutex);
+        return CA_STATUS_OK;
+    }
+
+    CAResult_t ret = CAInitLEGattServer();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "CAInitLEGattServer failed[%d]", ret);
+        oc_mutex_unlock(g_leServerStateMutex);
+        CATerminateLEGattServer();
+        return CA_STATUS_FAILED;
+    }
+
+    ret  = CAAddNewLEServiceInGattServer(CA_GATT_SERVICE_UUID);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "CAAddNewLEServiceInGattServer failed[%d]", ret);
+        oc_mutex_unlock(g_leServerStateMutex);
+        CATerminateLEGattServer();
+        return CA_STATUS_FAILED;
+    }
+
+    static const char charReadUUID[] = CA_GATT_RESPONSE_CHRC_UUID;
+    char charReadValue[] = {33, 44, 55, 66}; // These are initial random values
+
+    // For Read Characteristics.
+    ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charReadUUID, charReadValue,
+                                              CA_LE_INITIAL_BUF_SIZE, true);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
+        oc_mutex_unlock(g_leServerStateMutex);
+        CATerminateLEGattServer();
+        return CA_STATUS_FAILED;
+    }
+
+    static const char charWriteUUID[] = CA_GATT_REQUEST_CHRC_UUID;
+    char charWriteValue[] = {33, 44, 55, 66}; // These are initial random values
+
+
+    ret = CAAddNewCharacteristicsToGattServer(g_gattSvcPath, charWriteUUID, charWriteValue,
+            CA_LE_INITIAL_BUF_SIZE, false); // For Write Characteristics.
+    if (CA_STATUS_OK != ret )
+    {
+        OIC_LOG_V(ERROR, TAG, "CAAddNewCharacteristicsToGattServer failed[%d]", ret);
+        oc_mutex_unlock(g_leServerStateMutex);
+        CATerminateLEGattServer();
+        return CA_STATUS_FAILED;
+    }
+
+    ret = CARegisterLEServicewithGattServer(g_gattSvcPath);
+    if (CA_STATUS_OK != ret )
+    {
+        OIC_LOG_V(ERROR, TAG, "CARegisterLEServicewithGattServer failed[%d]", ret);
+        oc_mutex_unlock(g_leServerStateMutex);
+        CATerminateLEGattServer();
+        return CA_STATUS_FAILED;
+    }
+
+    /*
+     * TV Easysetup does not use IoTivity BLE advertisement.
+     */
+
+    // ret = CALEStartAdvertise();
+    // if (CA_STATUS_OK != ret)
+    // {
+    //     OIC_LOG_V(ERROR, TAG, "CALEStartAdvertise failed[%d]", ret);
+    //     oc_mutex_unlock(g_leServerStateMutex);
+    //     CATerminateLEGattServer();
+    //     return CA_STATUS_FAILED;
+    // }
+
+    g_isLEGattServerStarted = true;
+
+    oc_mutex_unlock(g_leServerStateMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CALENotificationCb(bool notify, bt_gatt_server_h server, bt_gatt_h gatt_handle,
+                        void *user_data)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    if (notify)
+    {
+        OIC_LOG(DEBUG, TAG, "Notification is subscribed by the client");
+        CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
+                           true, "notifyChar success");
+    }
+    else
+    {
+        CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
+                           false, "notifyChar failure");
+    }
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+CAResult_t CALEStartAdvertise()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    CAResult_t res = CALEStartAdvertiseImpl(CA_GATT_SERVICE_UUID);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG_V(ERROR, TAG, "CALEStartAdvertiseImpl failed[%d]", res);
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return res;
+}
+
+CAResult_t CALEStartAdvertiseImpl(const char *serviceUUID)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    int res = bt_adapter_le_create_advertiser(&g_hAdvertiser);
+    if (NULL == g_hAdvertiser || BT_ERROR_NONE != res)
+    {
+        OIC_LOG_V(ERROR, TAG, "g_hAdvertiser is NULL/ Result is %d", res);
+        return CA_STATUS_FAILED;
+    }
+
+    res = bt_adapter_le_add_advertising_service_uuid(g_hAdvertiser,
+                                                     BT_ADAPTER_LE_PACKET_ADVERTISING,
+                                                     serviceUUID);
+    if (BT_ERROR_NONE != res)
+    {
+        OIC_LOG_V(ERROR, TAG, "bt_adapter_le_add_advertising_service_uuid failed with ret[%s]",
+                  CALEGetErrorMsg(res));
+        return CA_STATUS_FAILED;
+    }
+
+    res = bt_adapter_le_set_advertising_device_name(g_hAdvertiser,
+                                                    BT_ADAPTER_LE_PACKET_SCAN_RESPONSE, true);
+    if (BT_ERROR_NONE != res)
+    {
+        OIC_LOG_V(ERROR, TAG, "bt_adapter_le_set_advertising_device_name failed with ret[%s]",
+                  CALEGetErrorMsg(res));
+        return CA_STATUS_FAILED;
+    }
+
+    res = bt_adapter_le_start_advertising_new(g_hAdvertiser, NULL, NULL);
+    if (BT_ERROR_NONE != res)
+    {
+        OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_advertising_new failed with ret[%s]",
+                  CALEGetErrorMsg(res));
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CALEStopAdvertise()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    if (NULL != g_hAdvertiser)
+    {
+        int ret  = bt_adapter_le_stop_advertising(g_hAdvertiser);
+        if (0 != ret)
+        {
+            OIC_LOG_V(ERROR, TAG,
+                      "bt_adapter_le_stop_advertising failed with ret[%s]", CALEGetErrorMsg(ret));
+        }
+
+        ret = bt_adapter_le_destroy_advertiser(g_hAdvertiser);
+        if (0 != ret)
+        {
+            OIC_LOG_V(ERROR, TAG,
+                      "bt_adapter_le_destroy_advertiser failed with ret[%s]", CALEGetErrorMsg(ret));
+        }
+        g_hAdvertiser = NULL;
+    }
+    else
+    {
+        OIC_LOG(ERROR, TAG, "Advertising is not running");
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAStopLEGattServer()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    oc_mutex_lock(g_leServerStateMutex);
+
+    if (false == g_isLEGattServerStarted)
+    {
+        OIC_LOG(ERROR, TAG, "Gatt Server is not running to stop");
+        oc_mutex_unlock(g_leServerStateMutex);
+        return CA_STATUS_OK;
+    }
+
+    g_isLEGattServerStarted = false;
+
+    oc_mutex_lock(g_LEClientListMutex);
+    CADisconnectAllClient(g_LEClientList);
+    g_LEClientList = NULL;
+    oc_mutex_unlock(g_LEClientListMutex);
+
+    /*
+     * TV Easysetup does not use IoTivity BLE advertisement.
+     */
+
+    // CAResult_t res = CALEStopAdvertise();
+    // {
+    //     OIC_LOG_V(ERROR, TAG, "CALEStopAdvertise failed with ret[%d]", res);
+    // }
+
+    CAResult_t res = CADeInitLEGattServer();
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG_V(ERROR, TAG, "CADeInitLEGattService failed with ret[%d]", res);
+    }
+
+    GMainContext  *context_event_loop = NULL;
+    // Required for waking up the thread which is running in gmain loop
+    if (NULL != g_eventLoop)
+    {
+        context_event_loop = g_main_loop_get_context(g_eventLoop);
+
+        if (context_event_loop)
+        {
+            OIC_LOG_V(DEBUG,  TAG, "g_eventLoop context %x", context_event_loop);
+            g_main_context_wakeup(context_event_loop);
+
+            // Kill g main loops and kill threads
+            g_main_loop_quit(g_eventLoop);
+        }
+        g_eventLoop = NULL;
+    }
+    else
+    {
+        OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
+    }
+
+    oc_mutex_unlock(g_leServerStateMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAInitializeLEGattServer()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    CAResult_t ret = CAInitGattServerMutexVariables();
+    if (CA_STATUS_OK != ret )
+    {
+        OIC_LOG(ERROR, TAG, "CAInitGattServerMutexVariables failed!");
+        CATerminateGattServerMutexVariables();
+        return CA_SERVER_NOT_STARTED;
+    }
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return ret;
+}
+
+void CATerminateLEGattServer()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    // Service and characteristics path will be freed by the platform.
+    oc_mutex_lock(g_leServiceMutex);
+    g_gattSvcPath = NULL;
+    oc_mutex_unlock(g_leServiceMutex);
+
+    oc_mutex_lock(g_leCharacteristicMutex);
+    g_gattReadCharPath = NULL;
+    g_gattWriteCharPath = NULL;
+    oc_mutex_unlock(g_leCharacteristicMutex);
+
+    oc_mutex_lock(g_leServerThreadPoolMutex);
+    g_leServerThreadPool = NULL;
+    oc_mutex_unlock(g_leServerThreadPoolMutex);
+
+    // Terminating all mutex variables.
+    CATerminateGattServerMutexVariables();
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+CAResult_t CAInitGattServerMutexVariables()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    if (NULL == g_leServerStateMutex)
+    {
+        g_leServerStateMutex = oc_mutex_new();
+        if (NULL == g_leServerStateMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_leServiceMutex)
+    {
+        g_leServiceMutex = oc_mutex_new();
+        if (NULL == g_leServiceMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_leCharacteristicMutex)
+    {
+        g_leCharacteristicMutex = oc_mutex_new();
+        if (NULL == g_leCharacteristicMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_leReqRespCbMutex)
+    {
+        g_leReqRespCbMutex = oc_mutex_new();
+        if (NULL == g_leReqRespCbMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_leServerThreadPoolMutex)
+    {
+        g_leServerThreadPoolMutex = oc_mutex_new();
+        if (NULL == g_leServerThreadPoolMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_LEClientListMutex)
+    {
+        g_LEClientListMutex = oc_mutex_new();
+        if (NULL == g_LEClientListMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CATerminateGattServerMutexVariables()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    oc_mutex_free(g_leServerStateMutex);
+    g_leServerStateMutex = NULL;
+
+    oc_mutex_free(g_leServiceMutex);
+    g_leServiceMutex = NULL;
+
+    oc_mutex_free(g_leCharacteristicMutex);
+    g_leCharacteristicMutex = NULL;
+
+    oc_mutex_free(g_leReqRespCbMutex);
+    g_leReqRespCbMutex = NULL;
+
+    oc_mutex_free(g_leServerThreadPoolMutex);
+    g_leServerThreadPoolMutex = NULL;
+
+    oc_mutex_free(g_LEClientListMutex);
+    g_LEClientListMutex = NULL;
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+CAResult_t CAInitLEGattServer()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    int ret =  bt_gatt_server_initialize();
+    if (0 != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "bt_gatt_server_initialize failed with ret[%s]",
+                  CALEGetErrorMsg(ret));
+        return CA_STATUS_FAILED;
+    }
+
+    if (!g_gattServer)
+    {
+        OIC_LOG(DEBUG, TAG, "g_gattServer is NULL. create gatt server..");
+        ret = bt_gatt_server_create(&g_gattServer);
+        if (0 != ret)
+        {
+            OIC_LOG_V(ERROR, TAG, "bt_gatt_server_create failed with ret[%s]",
+                      CALEGetErrorMsg(ret));
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CADeInitLEGattServer()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    int ret = bt_gatt_server_unregister_all_services(g_gattServer);
+    if (0 != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "bt_gatt_server_unregister_all_services failed with ret[%s]",
+                  CALEGetErrorMsg(ret));
+        return CA_STATUS_FAILED;
+    }
+
+    ret = bt_gatt_server_destroy(g_gattServer);
+    if (0 != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "bt_gatt_server_destroy failed with ret[%s]",
+                  CALEGetErrorMsg(ret));
+        return CA_STATUS_FAILED;
+    }
+    g_gattServer = NULL;
+
+    ret =  bt_gatt_server_deinitialize();
+    if (0 != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "bt_gatt_server_deinitialize failed with ret[%s]",
+                  CALEGetErrorMsg(ret));
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CASetLEServerThreadPoolHandle(ca_thread_pool_t handle)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    oc_mutex_lock(g_leServerThreadPoolMutex);
+    g_leServerThreadPool = handle;
+    oc_mutex_unlock(g_leServerThreadPoolMutex);
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+CAResult_t CAAddNewLEServiceInGattServer(const char *serviceUUID)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    VERIFY_NON_NULL(serviceUUID, TAG, "serviceUUID");
+
+    OIC_LOG_V(DEBUG, TAG, "service uuid %s", serviceUUID);
+
+    bt_gatt_service_type_e type = BT_GATT_SERVICE_TYPE_PRIMARY;
+
+    oc_mutex_lock(g_leServiceMutex);
+    int ret = bt_gatt_service_create(serviceUUID, type, &g_gattSvcPath);
+    if (0 != ret)
+    {
+        oc_mutex_unlock(g_leServiceMutex);
+        OIC_LOG_V(ERROR, TAG, "bt_gatt_service_create failed with ret [%s]",
+                    CALEGetErrorMsg(ret));
+        return CA_STATUS_FAILED;
+    }
+    oc_mutex_unlock(g_leServiceMutex);
+
+    if (g_gattSvcPath)
+    {
+        OIC_LOG_V(DEBUG, TAG, "ServicePath obtained is %s", (char *)g_gattSvcPath);
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+#ifdef BLE_TIZEN_30
+void CALEGattRemoteCharacteristicWriteCb(const char *remoteAddress, int request_id,
+                                         bt_gatt_server_h server, bt_gatt_h gatt_handle,
+                                         bool response_needed, int offset, const char *charValue,
+                                         int charLen, void *userData)
+#else
+void CALEGattRemoteCharacteristicWriteCb(char *remoteAddress, bt_gatt_server_h server,
+                                         bt_gatt_h gatt_handle, int offset, char *charValue,
+                                         int charLen, void *userData)
+#endif
+{
+    OIC_LOG(INFO, TAG, "IN - WriteCharCB");
+
+    if (NULL == charValue || NULL == remoteAddress)
+    {
+        OIC_LOG(ERROR, TAG, "Param callback values are NULL");
+        return;
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "len [%d]", charLen);
+
+    uint8_t *data = OICMalloc(charLen);
+    if (NULL == data)
+    {
+        OIC_LOG(ERROR, TAG, "Malloc failed!");
+        return;
+    }
+
+    memcpy(data, charValue, charLen);
+
+    oc_mutex_lock(g_leReqRespCbMutex);
+    if (NULL == g_leServerDataReceivedCallback)
+    {
+        OIC_LOG(ERROR, TAG, "gReqRespCallback is NULL!");
+        oc_mutex_unlock(g_leReqRespCbMutex);
+        OICFree(data);
+        return;
+    }
+
+    OIC_LOG(INFO, TAG, "Sending data up !");
+    uint32_t sentLength = 0;
+    g_leServerDataReceivedCallback(remoteAddress, data, charLen,
+                                    &sentLength);
+    oc_mutex_unlock(g_leReqRespCbMutex);
+    OICFree(data);
+
+#ifdef BLE_TIZEN_30
+    //response
+    OIC_LOG_V(INFO, TAG, "response_needed flag : %d", response_needed);
+    if (response_needed)
+    {
+        OIC_LOG(INFO, TAG, "send response to remote client");
+        bt_gatt_server_send_response(request_id,
+                BT_GATT_REQUEST_TYPE_WRITE, offset,
+                BT_ERROR_NONE, NULL, 0);
+    }
+#endif
+
+    OIC_LOG(INFO, TAG, "OUT - WriteCharCB");
+}
+
+CAResult_t CARegisterLEServicewithGattServer(const bt_gatt_h svcPath)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    VERIFY_NON_NULL(svcPath, TAG, "svcPath");
+
+    OIC_LOG_V(DEBUG, TAG, "svcPath:%s", svcPath);
+
+    int ret = bt_gatt_server_register_service(g_gattServer, svcPath);
+    if (0 != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "bt_gatt_server_register_service failed with ret[%s]",
+                  CALEGetErrorMsg(ret));
+        return CA_STATUS_FAILED;
+    }
+
+#ifdef BLE_TIZEN_30
+    ret = bt_gatt_server_start();
+    if (0 != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "bt_gatt_server_start failed with ret[%s]",
+                CALEGetErrorMsg(ret));
+        return CA_STATUS_FAILED;
+    }
+#endif
+
+#ifdef BLE_TIZEN_30
+    ret = bt_gatt_server_set_write_value_requested_cb(g_gattWriteCharPath,
+#else
+    ret = bt_gatt_server_set_value_changed_cb(g_gattWriteCharPath,
+#endif
+                                              CALEGattRemoteCharacteristicWriteCb, NULL);
+
+    if (0 != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "bt_gatt_server_set_value_changed_cb failed with ret[%s]",
+                  CALEGetErrorMsg(ret));
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const char *charUUID,
+                                               const char *charValue, int charValueLen, bool read)
+{
+
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    int permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
+    int properties;
+    if (read)
+    {
+        properties = BT_GATT_PROPERTY_INDICATE | BT_GATT_PROPERTY_READ;
+    }
+    else
+    {
+        properties = BT_GATT_PROPERTY_WRITE | BT_GATT_PROPERTY_READ;
+    }
+
+    bt_gatt_h charPath = NULL;
+
+    int ret = bt_gatt_characteristic_create(charUUID, permissions, properties, charValue,
+                                            charValueLen, &charPath);
+
+    if (0 != ret || NULL == charPath)
+    {
+        OIC_LOG_V(ERROR, TAG,
+                  "bt_gatt_add_characteristic  failed with ret [%s]", CALEGetErrorMsg(ret));
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG_V(DEBUG, TAG,
+              "bt_gatt_characteristic_create charPath obtained: %s", (char *)charPath);
+
+    if (read)
+    {
+#ifdef BLE_TIZEN_30
+        ret = bt_gatt_server_set_characteristic_notification_state_change_cb(charPath,
+                                                                             CALENotificationCb,
+                                                                             NULL);
+#else
+        ret = bt_gatt_server_set_notification_state_change_cb(charPath, CALENotificationCb, NULL);
+#endif
+        if (0 != ret)
+        {
+            OIC_LOG_V(ERROR, TAG,
+#ifdef BLE_TIZEN_30
+                      "bt_gatt_server_set_characteristic_notification_state_change_cb failed with ret[%s]",
+#else
+                      "bt_gatt_server_set_notification_state_change_cb  failed with ret[%s]",
+#endif
+                      CALEGetErrorMsg(ret));
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    ret =  bt_gatt_service_add_characteristic(svcPath, charPath);
+    if (0 != ret)
+    {
+        OIC_LOG_V(ERROR, TAG,
+                  "bt_gatt_service_add_characteristic  failed with ret[%s]",
+                  CALEGetErrorMsg(ret));
+        return CA_STATUS_FAILED;
+    }
+
+    oc_mutex_lock(g_leCharacteristicMutex);
+
+    if (read)
+    {
+        g_gattReadCharPath = charPath;
+    }
+    else
+    {
+        char desc_value[2] = {0, 0};  // Notification enabled.
+        bt_gatt_h descriptor = NULL;
+        permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
+        ret = bt_gatt_descriptor_create(CA_GATT_CONFIGURATION_DESC_UUID, permissions,
+                                        desc_value, sizeof(desc_value),
+                                        &descriptor);
+        if (0 != ret)
+        {
+            oc_mutex_unlock(g_leCharacteristicMutex);
+            OIC_LOG_V(ERROR, TAG,
+                      "bt_gatt_descriptor_create  failed with ret[%s]",
+                      CALEGetErrorMsg(ret));
+            return CA_STATUS_FAILED;
+        }
+
+        ret = bt_gatt_characteristic_add_descriptor(charPath, descriptor);
+        if (0 != ret)
+        {
+            oc_mutex_unlock(g_leCharacteristicMutex);
+            OIC_LOG_V(ERROR, TAG,
+                      "bt_gatt_characteristic_add_descriptor  failed with ret[%s]",
+                      CALEGetErrorMsg(ret));
+            return CA_STATUS_FAILED;
+        }
+        g_gattWriteCharPath = charPath;
+    }
+
+    oc_mutex_unlock(g_leCharacteristicMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAUpdateCharacteristicsToGattClient(const char *address, const uint8_t *charValue,
+                                               uint32_t charValueLen)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    VERIFY_NON_NULL(charValue, TAG, "charValue");
+    VERIFY_NON_NULL(address, TAG, "address");
+
+    OIC_LOG_V(DEBUG, TAG, "Client's Unicast address for sending data [%s]", address);
+
+    oc_mutex_lock(g_leCharacteristicMutex);
+
+    if (!g_LEConnectedState)
+    {
+        OIC_LOG(ERROR, TAG, "g_LEConnectedState is false");
+        oc_mutex_unlock(g_leCharacteristicMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    if (NULL  == g_gattReadCharPath)
+    {
+        OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
+        oc_mutex_unlock(g_leCharacteristicMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
+    if (0 != ret)
+    {
+        OIC_LOG_V(ERROR, TAG,
+                  "bt_gatt_set_value failed with return [%s]", CALEGetErrorMsg(ret));
+        oc_mutex_unlock(g_leCharacteristicMutex);
+        return CA_STATUS_FAILED;
+    }
+
+#ifdef BLE_TIZEN_30
+    ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
+                                                             CALEServerNotificationSentCB,
+                                                             address, NULL);
+#else
+    ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
+                                NULL);
+#endif
+
+    if (0 != ret)
+    {
+        OIC_LOG_V(ERROR, TAG,
+#ifdef BLE_TIZEN_30
+                  "bt_gatt_server_notify_characteristic_changed_value failed with return [%s]",
+#else
+                  "bt_gatt_server_notify failed with return [%s]",
+#endif
+                  CALEGetErrorMsg(ret));
+        oc_mutex_unlock(g_leCharacteristicMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    oc_mutex_unlock(g_leCharacteristicMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAUpdateCharacteristicsToAllGattClients(const uint8_t *charValue, uint32_t charValueLen)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    VERIFY_NON_NULL(charValue, TAG, "charValue");
+
+    oc_mutex_lock(g_leCharacteristicMutex);
+
+    if (!g_LEConnectedState)
+    {
+        OIC_LOG(ERROR, TAG, "g_LEConnectedState is false");
+        oc_mutex_unlock(g_leCharacteristicMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    if (NULL  == g_gattReadCharPath)
+    {
+        OIC_LOG(ERROR, TAG, "g_gattReadCharPath is NULL");
+        oc_mutex_unlock(g_leCharacteristicMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    int ret = bt_gatt_set_value(g_gattReadCharPath, (char *)charValue, charValueLen);
+    if (0 != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "bt_gatt_set_value failed with return[%s]", CALEGetErrorMsg(ret));
+        oc_mutex_unlock(g_leCharacteristicMutex);
+        return CA_STATUS_FAILED;
+    }
+
+#ifdef BLE_TIZEN_30
+    ret = bt_gatt_server_notify_characteristic_changed_value(g_gattReadCharPath,
+                                                             CALEServerNotificationSentCB,
+                                                             NULL, NULL);
+#else
+    ret = bt_gatt_server_notify(g_gattReadCharPath, false, CALEServerNotificationSentCB,
+                                NULL);
+#endif
+    if (0 != ret)
+    {
+        OIC_LOG_V(ERROR, TAG,
+#ifdef BLE_TIZEN_30
+                  "bt_gatt_server_notify_characteristic_changed_value failed with return[%s]",
+#else
+                  "bt_gatt_server_notify failed with return[%s]",
+#endif
+                  CALEGetErrorMsg(ret));
+        oc_mutex_unlock(g_leCharacteristicMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    oc_mutex_unlock(g_leCharacteristicMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CASetLEReqRespServerCallback(CABLEDataReceivedCallback callback)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    oc_mutex_lock(g_leReqRespCbMutex);
+    g_leServerDataReceivedCallback = callback;
+    oc_mutex_unlock(g_leReqRespCbMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+void CASetBLEServerErrorHandleCallback(CABLEErrorHandleCallback callback)
+{
+    g_serverErrorCallback = callback;
+}
+
+bool CALEServerIsConnected(const char* address)
+{
+    //@Todo
+    return true;
+}
+
+uint16_t CALEServerGetMtuSize(const char* address)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+    VERIFY_NON_NULL_RET(address, TAG, "address is null", CA_DEFAULT_BLE_MTU_SIZE);
+
+    unsigned int mtu;
+    int ret = bt_device_get_att_mtu(address, &mtu);
+    if (0 != ret)
+    {
+        OIC_LOG_V(ERROR, TAG,
+                  "bt_device_get_att_mtu failed with return [%s]", CALEGetErrorMsg(ret));
+        return CA_DEFAULT_BLE_MTU_SIZE;
+    }
+    OIC_LOG_V(INFO, TAG, "mtu size(including header) from bt_device_get_att_mtu is %d", mtu);
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return mtu - CA_BLE_MTU_HEADER_SIZE;
+}
index dd17fe9..94a642b 100644 (file)
@@ -41,8 +41,9 @@
 #include "cablockwisetransfer.h"
 #include "oic_malloc.h"
 #include "oic_string.h"
-#include "camutex.h"
+#include "octhread.h"
 #include "logger.h"
+#include "oic_time.h"
 
 #define TAG "OIC_CA_BWT"
 
@@ -53,6 +54,9 @@
 
 #define BLOCK_SIZE(arg) (1 << ((arg) + 4))
 
+#define BLOCK_DATA_TIMEOUT_SECONDS   (60 * 1)  // 1 minutes.
+static const uint64_t USECS_PER_SEC = 1000000;
+
 // context for block-wise transfer
 static CABlockWiseContext_t g_context = { .sendThreadFunc = NULL,
                                           .receivedThreadFunc = NULL,
@@ -126,20 +130,20 @@ CAResult_t CAInitBlockWiseMutexVariables()
 {
     if (!g_context.blockDataListMutex)
     {
-        g_context.blockDataListMutex = ca_mutex_new();
+        g_context.blockDataListMutex = oc_mutex_new();
         if (!g_context.blockDataListMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (!g_context.blockDataSenderMutex)
     {
-        g_context.blockDataSenderMutex = ca_mutex_new();
+        g_context.blockDataSenderMutex = oc_mutex_new();
         if (!g_context.blockDataSenderMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
             CATerminateBlockWiseMutexVariables();
             return CA_STATUS_FAILED;
         }
@@ -152,13 +156,13 @@ void CATerminateBlockWiseMutexVariables()
 {
     if (g_context.blockDataListMutex)
     {
-        ca_mutex_free(g_context.blockDataListMutex);
+        oc_mutex_free(g_context.blockDataListMutex);
         g_context.blockDataListMutex = NULL;
     }
 
     if (g_context.blockDataSenderMutex)
     {
-        ca_mutex_free(g_context.blockDataSenderMutex);
+        oc_mutex_free(g_context.blockDataSenderMutex);
         g_context.blockDataSenderMutex = NULL;
     }
 }
@@ -266,9 +270,9 @@ CAResult_t CAAddSendThreadQueue(const CAData_t *sendData, const CABlockDataID_t
 
     if (g_context.sendThreadFunc)
     {
-        ca_mutex_lock(g_context.blockDataSenderMutex);
+        oc_mutex_lock(g_context.blockDataSenderMutex);
         g_context.sendThreadFunc(cloneData);
-        ca_mutex_unlock(g_context.blockDataSenderMutex);
+        oc_mutex_unlock(g_context.blockDataSenderMutex);
     }
     else
     {
@@ -689,6 +693,19 @@ CAResult_t CASendErrorMessage(const coap_pdu_t *pdu, uint8_t status,
         return CA_STATUS_FAILED;
     }
 
+    if (!data->sentData)
+    {
+        OIC_LOG(ERROR, TAG, "data has no sent-data");
+        return CA_STATUS_FAILED;
+    }
+
+    CAData_t *cloneData = CACloneCAData(data->sentData);
+    if (!cloneData)
+    {
+        OIC_LOG(ERROR, TAG, "clone has failed");
+        return CA_MEMORY_ALLOC_FAILED;
+    }
+
     CAMessageType_t sentMsgType = CA_MSG_NONCONFIRM;
     switch (pdu->transport_hdr->udp.type)
     {
@@ -702,53 +719,40 @@ CAResult_t CASendErrorMessage(const coap_pdu_t *pdu, uint8_t status,
             sentMsgType = CA_MSG_NONCONFIRM;
     }
 
-    CAData_t *cloneData = NULL;
-    if (data->sentData)
+    if (cloneData->responseInfo)
+    {
+        cloneData->responseInfo->info.messageId = pdu->transport_hdr->udp.id;
+        cloneData->responseInfo->info.type = sentMsgType;
+        cloneData->responseInfo->result = responseResult;
+    }
+    else
     {
-        cloneData = CACloneCAData(data->sentData);
-        if (!cloneData)
+        CAInfo_t responseData = { .tokenLength = pdu->transport_hdr->udp.token_length };
+        responseData.token = (CAToken_t) OICMalloc(responseData.tokenLength);
+        if (!responseData.token)
         {
-            OIC_LOG(ERROR, TAG, "clone has failed");
+            OIC_LOG(ERROR, TAG, "out of memory");
+            CADestroyDataSet(cloneData);
             return CA_MEMORY_ALLOC_FAILED;
         }
+        memcpy(responseData.token, pdu->transport_hdr->udp.token, responseData.tokenLength);
 
-        if (cloneData->responseInfo)
+        cloneData->responseInfo = (CAResponseInfo_t*) OICCalloc(1, sizeof(CAResponseInfo_t));
+        if (!cloneData->responseInfo)
         {
-            cloneData->responseInfo->info.messageId = pdu->transport_hdr->udp.id;
-            cloneData->responseInfo->info.type = sentMsgType;
-            cloneData->responseInfo->result = responseResult;
+            OIC_LOG(ERROR, TAG, "out of memory");
+            CADestroyDataSet(cloneData);
+            OICFree(responseData.token);
+            return CA_MEMORY_ALLOC_FAILED;
         }
-        else
-        {
-            CAInfo_t responseData = { .tokenLength = pdu->transport_hdr->udp.token_length };
-            responseData.token = (CAToken_t) OICMalloc(responseData.tokenLength);
-            if (!responseData.token)
-            {
-                OIC_LOG(ERROR, TAG, "out of memory");
-                return CA_MEMORY_ALLOC_FAILED;
-            }
-            memcpy(responseData.token, pdu->transport_hdr->udp.token, responseData.tokenLength);
 
-            cloneData->responseInfo = (CAResponseInfo_t*) OICCalloc(1, sizeof(CAResponseInfo_t));
-            if (!cloneData->responseInfo)
-            {
-                OIC_LOG(ERROR, TAG, "out of memory");
-                OICFree(responseData.token);
-                return CA_MEMORY_ALLOC_FAILED;
-            }
-
-            cloneData->responseInfo->info = responseData;
-            cloneData->responseInfo->info.type = sentMsgType;
-            cloneData->responseInfo->result = responseResult;
-        }
-        OIC_LOG(DEBUG, TAG, "set response message to send error code");
-    }
-    else
-    {
-        OIC_LOG(ERROR, TAG, "data has no sent-data");
-        return CA_MEMORY_ALLOC_FAILED;
+        cloneData->responseInfo->info = responseData;
+        cloneData->responseInfo->info.type = sentMsgType;
+        cloneData->responseInfo->result = responseResult;
     }
 
+    OIC_LOG(DEBUG, TAG, "set response message to send error code");
+
     // if there is a requestInfo, remove it to send response message
     if (cloneData->requestInfo)
     {
@@ -759,9 +763,9 @@ CAResult_t CASendErrorMessage(const coap_pdu_t *pdu, uint8_t status,
     // add data to send thread
     if (g_context.sendThreadFunc)
     {
-        ca_mutex_lock(g_context.blockDataSenderMutex);
+        oc_mutex_lock(g_context.blockDataSenderMutex);
         g_context.sendThreadFunc(cloneData);
-        ca_mutex_unlock(g_context.blockDataSenderMutex);
+        oc_mutex_unlock(g_context.blockDataSenderMutex);
     }
     else
     {
@@ -1451,20 +1455,24 @@ CAResult_t CAAddBlockOption(coap_pdu_t **pdu, const CAInfo_t *info,
             {
                 OIC_LOG_V(DEBUG, TAG, "[%s] opt will be added.",
                           COAP_OPTION_DATA(*(coap_option *) opt->data));
-
                 OIC_LOG_V(DEBUG, TAG, "[%d] pdu length", (*pdu)->length);
-                coap_add_option(*pdu, COAP_OPTION_KEY(*(coap_option *) opt->data),
-                                COAP_OPTION_LENGTH(*(coap_option *) opt->data),
-                                COAP_OPTION_DATA(*(coap_option *) opt->data));
+
+                if (0 == coap_add_option(*pdu, COAP_OPTION_KEY(*(coap_option *) opt->data),
+                                         COAP_OPTION_LENGTH(*(coap_option *) opt->data),
+                                         COAP_OPTION_DATA(*(coap_option *) opt->data)))
+                {
+                    OIC_LOG(ERROR, TAG, "coap_add_option has failed");
+                    res = CA_STATUS_FAILED;
+                    goto exit;
+                }
             }
         }
-
         OIC_LOG_V(DEBUG, TAG, "[%d] pdu length after option", (*pdu)->length);
 
         // if response data is so large. it have to send as block transfer
         if (!coap_add_data(*pdu, dataLength, (const unsigned char *) info->payload))
         {
-            OIC_LOG(INFO, TAG, "it have to use block");
+            OIC_LOG(INFO, TAG, "it has to use block");
             res = CA_STATUS_FAILED;
             goto exit;
         }
@@ -1491,6 +1499,7 @@ CAResult_t CAAddBlockOption(coap_pdu_t **pdu, const CAInfo_t *info,
         }
     }
 
+    CAResetBlockDataTTL(blockDataID);
 exit:
     CADestroyBlockID(blockDataID);
     OIC_LOG(DEBUG, TAG, "OUT-AddBlockOption");
@@ -2065,12 +2074,14 @@ CAData_t* CACreateNewDataSet(const coap_pdu_t *pdu, const CAEndpoint_t *endpoint
         {
             OIC_LOG(ERROR, TAG, "memory allocation failed");
             OICFree(requestData.token);
+            OICFree(requestInfo);
             return NULL;
         }
 
         CAGetResponseInfoFromPDU(pdu, resInfo, endpoint);
         requestInfo->method = CA_GET;
-        requestInfo->info.messageId = CAGetMessageIdFromPduBinaryData(pdu->transport_hdr, pdu->length);
+        requestInfo->info.messageId = CAGetMessageIdFromPduBinaryData(pdu->transport_hdr,
+                                                                      pdu->length);
         requestInfo->info.resourceUri = OICStrdup(resInfo->info.resourceUri);
 
         // after copying the resource uri, destroy response info.
@@ -2081,8 +2092,17 @@ CAData_t* CACreateNewDataSet(const coap_pdu_t *pdu, const CAEndpoint_t *endpoint
     if (!data)
     {
         OIC_LOG(ERROR, TAG, "out of memory");
-        OICFree(requestInfo);
-        OICFree(responseInfo);
+        if (NULL != requestInfo)
+        {
+            OICFree(requestInfo->info.resourceUri);
+            OICFree(requestInfo->info.token);
+            OICFree(requestInfo);
+        }
+        if (NULL != responseInfo)
+        {
+            OICFree(responseInfo->info.token);
+            OICFree(responseInfo);
+        }
         return NULL;
     }
 
@@ -2239,7 +2259,7 @@ CAResult_t CAUpdateBlockOptionType(const CABlockDataID_t *blockID, uint8_t block
     OIC_LOG(DEBUG, TAG, "IN-UpdateBlockOptionType");
     VERIFY_NON_NULL(blockID, TAG, "blockID");
 
-    ca_mutex_lock(g_context.blockDataListMutex);
+    oc_mutex_lock(g_context.blockDataListMutex);
 
     size_t len = u_arraylist_length(g_context.dataList);
     for (size_t i = 0; i < len; i++)
@@ -2248,12 +2268,12 @@ CAResult_t CAUpdateBlockOptionType(const CABlockDataID_t *blockID, uint8_t block
         if (CABlockidMatches(currData, blockID))
         {
             currData->type = blockType;
-            ca_mutex_unlock(g_context.blockDataListMutex);
+            oc_mutex_unlock(g_context.blockDataListMutex);
             OIC_LOG(DEBUG, TAG, "OUT-UpdateBlockOptionType");
             return CA_STATUS_OK;
         }
     }
-    ca_mutex_unlock(g_context.blockDataListMutex);
+    oc_mutex_unlock(g_context.blockDataListMutex);
 
     OIC_LOG(DEBUG, TAG, "OUT-UpdateBlockOptionType");
     return CA_STATUS_FAILED;
@@ -2264,7 +2284,7 @@ uint8_t CAGetBlockOptionType(const CABlockDataID_t *blockID)
     OIC_LOG(DEBUG, TAG, "IN-GetBlockOptionType");
     VERIFY_NON_NULL_RET(blockID, TAG, "blockID", 0);
 
-    ca_mutex_lock(g_context.blockDataListMutex);
+    oc_mutex_lock(g_context.blockDataListMutex);
 
     size_t len = u_arraylist_length(g_context.dataList);
     for (size_t i = 0; i < len; i++)
@@ -2272,12 +2292,12 @@ uint8_t CAGetBlockOptionType(const CABlockDataID_t *blockID)
         CABlockData_t *currData = (CABlockData_t *) u_arraylist_get(g_context.dataList, i);
         if (CABlockidMatches(currData, blockID))
         {
-            ca_mutex_unlock(g_context.blockDataListMutex);
+            oc_mutex_unlock(g_context.blockDataListMutex);
             OIC_LOG(DEBUG, TAG, "OUT-GetBlockOptionType");
             return currData->type;
         }
     }
-    ca_mutex_unlock(g_context.blockDataListMutex);
+    oc_mutex_unlock(g_context.blockDataListMutex);
 
     OIC_LOG(DEBUG, TAG, "OUT-GetBlockOptionType");
     return 0;
@@ -2287,7 +2307,7 @@ CAData_t *CAGetDataSetFromBlockDataList(const CABlockDataID_t *blockID)
 {
     VERIFY_NON_NULL_RET(blockID, TAG, "blockID", NULL);
 
-    ca_mutex_lock(g_context.blockDataListMutex);
+    oc_mutex_lock(g_context.blockDataListMutex);
 
     size_t len = u_arraylist_length(g_context.dataList);
     for (size_t i = 0; i < len; i++)
@@ -2295,11 +2315,11 @@ CAData_t *CAGetDataSetFromBlockDataList(const CABlockDataID_t *blockID)
         CABlockData_t *currData = (CABlockData_t *) u_arraylist_get(g_context.dataList, i);
         if (CABlockidMatches(currData, blockID))
         {
-            ca_mutex_unlock(g_context.blockDataListMutex);
+            oc_mutex_unlock(g_context.blockDataListMutex);
             return currData->sentData;
         }
     }
-    ca_mutex_unlock(g_context.blockDataListMutex);
+    oc_mutex_unlock(g_context.blockDataListMutex);
 
     return NULL;
 }
@@ -2310,7 +2330,7 @@ CABlockData_t *CAUpdateDataSetFromBlockDataList(const CABlockDataID_t *blockID,
     VERIFY_NON_NULL_RET(blockID, TAG, "blockID", NULL);
     VERIFY_NON_NULL_RET(sendData, TAG, "sendData", NULL);
 
-    ca_mutex_lock(g_context.blockDataListMutex);
+    oc_mutex_lock(g_context.blockDataListMutex);
 
     size_t len = u_arraylist_length(g_context.dataList);
     for (size_t i = 0; i < len; i++)
@@ -2320,11 +2340,11 @@ CABlockData_t *CAUpdateDataSetFromBlockDataList(const CABlockDataID_t *blockID,
         {
             CADestroyDataSet(currData->sentData);
             currData->sentData = CACloneCAData(sendData);
-            ca_mutex_unlock(g_context.blockDataListMutex);
+            oc_mutex_unlock(g_context.blockDataListMutex);
             return currData;
         }
     }
-    ca_mutex_unlock(g_context.blockDataListMutex);
+    oc_mutex_unlock(g_context.blockDataListMutex);
 
     return NULL;
 }
@@ -2337,7 +2357,7 @@ CAResult_t CAGetTokenFromBlockDataList(const coap_pdu_t *pdu, const CAEndpoint_t
     VERIFY_NON_NULL(endpoint, TAG, "endpoint");
     VERIFY_NON_NULL(responseInfo, TAG, "responseInfo");
 
-    ca_mutex_lock(g_context.blockDataListMutex);
+    oc_mutex_lock(g_context.blockDataListMutex);
 
     size_t len = u_arraylist_length(g_context.dataList);
     for (size_t i = 0; i < len; i++)
@@ -2361,13 +2381,13 @@ CAResult_t CAGetTokenFromBlockDataList(const coap_pdu_t *pdu, const CAEndpoint_t
                     if (NULL == responseInfo->info.token)
                     {
                         OIC_LOG(ERROR, TAG, "out of memory");
-                        ca_mutex_unlock(g_context.blockDataListMutex);
+                        oc_mutex_unlock(g_context.blockDataListMutex);
                         return CA_MEMORY_ALLOC_FAILED;
                     }
                     memcpy(responseInfo->info.token, currData->sentData->requestInfo->info.token,
                            responseInfo->info.tokenLength);
 
-                    ca_mutex_unlock(g_context.blockDataListMutex);
+                    oc_mutex_unlock(g_context.blockDataListMutex);
                     OIC_LOG(DEBUG, TAG, "OUT-CAGetTokenFromBlockDataList");
                     return CA_STATUS_OK;
                 }
@@ -2375,7 +2395,7 @@ CAResult_t CAGetTokenFromBlockDataList(const coap_pdu_t *pdu, const CAEndpoint_t
         }
     }
 
-    ca_mutex_unlock(g_context.blockDataListMutex);
+    oc_mutex_unlock(g_context.blockDataListMutex);
 
     OIC_LOG(DEBUG, TAG, "OUT-CAGetTokenFromBlockDataList");
     return CA_STATUS_FAILED;
@@ -2417,7 +2437,7 @@ CABlockData_t *CAGetBlockDataFromBlockDataList(const CABlockDataID_t *blockID)
 {
     VERIFY_NON_NULL_RET(blockID, TAG, "blockID", NULL);
 
-    ca_mutex_lock(g_context.blockDataListMutex);
+    oc_mutex_lock(g_context.blockDataListMutex);
 
     size_t len = u_arraylist_length(g_context.dataList);
     for (size_t i = 0; i < len; i++)
@@ -2425,11 +2445,11 @@ CABlockData_t *CAGetBlockDataFromBlockDataList(const CABlockDataID_t *blockID)
         CABlockData_t *currData = (CABlockData_t *) u_arraylist_get(g_context.dataList, i);
         if (CABlockidMatches(currData, blockID))
         {
-            ca_mutex_unlock(g_context.blockDataListMutex);
+            oc_mutex_unlock(g_context.blockDataListMutex);
             return currData;
         }
     }
-    ca_mutex_unlock(g_context.blockDataListMutex);
+    oc_mutex_unlock(g_context.blockDataListMutex);
 
     return NULL;
 }
@@ -2439,7 +2459,7 @@ coap_block_t *CAGetBlockOption(const CABlockDataID_t *blockID, uint16_t blockTyp
     OIC_LOG(DEBUG, TAG, "IN-GetBlockOption");
     VERIFY_NON_NULL_RET(blockID, TAG, "blockID", NULL);
 
-    ca_mutex_lock(g_context.blockDataListMutex);
+    oc_mutex_lock(g_context.blockDataListMutex);
 
     size_t len = u_arraylist_length(g_context.dataList);
     for (size_t i = 0; i < len; i++)
@@ -2447,7 +2467,7 @@ coap_block_t *CAGetBlockOption(const CABlockDataID_t *blockID, uint16_t blockTyp
         CABlockData_t *currData = (CABlockData_t *) u_arraylist_get(g_context.dataList, i);
         if (CABlockidMatches(currData, blockID))
         {
-            ca_mutex_unlock(g_context.blockDataListMutex);
+            oc_mutex_unlock(g_context.blockDataListMutex);
             OIC_LOG(DEBUG, TAG, "OUT-GetBlockOption");
             if (COAP_OPTION_BLOCK2 == blockType)
             {
@@ -2459,7 +2479,7 @@ coap_block_t *CAGetBlockOption(const CABlockDataID_t *blockID, uint16_t blockTyp
             }
         }
     }
-    ca_mutex_unlock(g_context.blockDataListMutex);
+    oc_mutex_unlock(g_context.blockDataListMutex);
 
     OIC_LOG(DEBUG, TAG, "OUT-GetBlockOption");
     return NULL;
@@ -2472,7 +2492,7 @@ CAPayload_t CAGetPayloadFromBlockDataList(const CABlockDataID_t *blockID,
     VERIFY_NON_NULL_RET(blockID, TAG, "blockID", NULL);
     VERIFY_NON_NULL_RET(fullPayloadLen, TAG, "fullPayloadLen", NULL);
 
-    ca_mutex_lock(g_context.blockDataListMutex);
+    oc_mutex_lock(g_context.blockDataListMutex);
 
     size_t len = u_arraylist_length(g_context.dataList);
     for (size_t i = 0; i < len; i++)
@@ -2480,13 +2500,13 @@ CAPayload_t CAGetPayloadFromBlockDataList(const CABlockDataID_t *blockID,
         CABlockData_t *currData = (CABlockData_t *) u_arraylist_get(g_context.dataList, i);
         if (CABlockidMatches(currData, blockID))
         {
-            ca_mutex_unlock(g_context.blockDataListMutex);
+            oc_mutex_unlock(g_context.blockDataListMutex);
             *fullPayloadLen = currData->receivedPayloadLen;
             OIC_LOG(DEBUG, TAG, "OUT-GetFullPayload");
             return currData->payload;
         }
     }
-    ca_mutex_unlock(g_context.blockDataListMutex);
+    oc_mutex_unlock(g_context.blockDataListMutex);
 
     OIC_LOG(DEBUG, TAG, "OUT-GetFullPayload");
     return NULL;
@@ -2548,8 +2568,10 @@ CABlockData_t *CACreateNewBlockData(const CAData_t *sendData)
         return NULL;
     }
     data->blockDataId = blockDataID;
+    uint64_t now = OICGetCurrentTime(TIME_IN_US);
+    data->ttl = now + (BLOCK_DATA_TIMEOUT_SECONDS * USECS_PER_SEC);
 
-    ca_mutex_lock(g_context.blockDataListMutex);
+    oc_mutex_lock(g_context.blockDataListMutex);
 
     bool res = u_arraylist_add(g_context.dataList, (void *) data);
     if (!res)
@@ -2558,10 +2580,10 @@ CABlockData_t *CACreateNewBlockData(const CAData_t *sendData)
         CADestroyBlockID(data->blockDataId);
         CADestroyDataSet(data->sentData);
         OICFree(data);
-        ca_mutex_unlock(g_context.blockDataListMutex);
+        oc_mutex_unlock(g_context.blockDataListMutex);
         return NULL;
     }
-    ca_mutex_unlock(g_context.blockDataListMutex);
+    oc_mutex_unlock(g_context.blockDataListMutex);
 
     OIC_LOG(DEBUG, TAG, "OUT-CreateBlockData");
     return data;
@@ -2569,10 +2591,10 @@ CABlockData_t *CACreateNewBlockData(const CAData_t *sendData)
 
 CAResult_t CARemoveBlockDataFromList(const CABlockDataID_t *blockID)
 {
-    OIC_LOG(DEBUG, TAG, "CARemoveBlockData");
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
     VERIFY_NON_NULL(blockID, TAG, "blockID");
 
-    ca_mutex_lock(g_context.blockDataListMutex);
+    oc_mutex_lock(g_context.blockDataListMutex);
 
     size_t len = u_arraylist_length(g_context.dataList);
     for (size_t i = 0; i < len; i++)
@@ -2584,21 +2606,25 @@ CAResult_t CARemoveBlockDataFromList(const CABlockDataID_t *blockID)
             if (!removedData)
             {
                 OIC_LOG(ERROR, TAG, "data is NULL");
-                ca_mutex_unlock(g_context.blockDataListMutex);
+                oc_mutex_unlock(g_context.blockDataListMutex);
                 return CA_STATUS_FAILED;
             }
 
+            OIC_LOG(DEBUG, TAG, "Removed BlockID is ");
+            OIC_LOG_BUFFER(DEBUG, TAG, (const uint8_t *) removedData->blockDataId->id,
+                           removedData->blockDataId->idLength);
+
             // destroy memory
             CADestroyDataSet(removedData->sentData);
             CADestroyBlockID(removedData->blockDataId);
             OICFree(removedData->payload);
             OICFree(removedData);
-            ca_mutex_unlock(g_context.blockDataListMutex);
+            oc_mutex_unlock(g_context.blockDataListMutex);
             return CA_STATUS_OK;
         }
     }
-    ca_mutex_unlock(g_context.blockDataListMutex);
-
+    oc_mutex_unlock(g_context.blockDataListMutex);
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
     return CA_STATUS_OK;
 }
 
@@ -2606,7 +2632,7 @@ CAResult_t CARemoveAllBlockDataFromList()
 {
     OIC_LOG(DEBUG, TAG, "CARemoveAllBlockDataFromList");
 
-    ca_mutex_lock(g_context.blockDataListMutex);
+    oc_mutex_lock(g_context.blockDataListMutex);
 
     size_t len = u_arraylist_length(g_context.dataList);
     for (size_t i = len; i > 0; i--)
@@ -2624,7 +2650,7 @@ CAResult_t CARemoveAllBlockDataFromList()
             OICFree(removedData);
         }
     }
-    ca_mutex_unlock(g_context.blockDataListMutex);
+    oc_mutex_unlock(g_context.blockDataListMutex);
 
     return CA_STATUS_OK;
 }
@@ -2743,3 +2769,57 @@ CAResult_t CARemoveBlockDataFromListWithSeed(const CAToken_t token, uint8_t toke
     CADestroyBlockID(blockDataID);
     return res;
 }
+
+void CAResetBlockDataTTL(const CABlockDataID_t *blockID)
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+
+    oc_mutex_lock(g_context.blockDataListMutex);
+    size_t len = u_arraylist_length(g_context.dataList);
+    for (size_t i = 0; i < len; i++)
+    {
+        CABlockData_t *blockData = (CABlockData_t *) u_arraylist_get(g_context.dataList, i);
+        if (CABlockidMatches(blockData, blockID))
+        {
+            uint64_t now = OICGetCurrentTime(TIME_IN_US);
+            blockData->ttl = now + (BLOCK_DATA_TIMEOUT_SECONDS * USECS_PER_SEC);
+            oc_mutex_unlock(g_context.blockDataListMutex);
+            OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+            return;
+        }
+    }
+    oc_mutex_unlock(g_context.blockDataListMutex);
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+}
+
+void CACheckAndDeleteTimedOutBlockData()
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+
+    uint64_t now = OICGetCurrentTime(TIME_IN_US);
+
+    oc_mutex_lock(g_context.blockDataListMutex);
+    for (size_t i = 0; i < u_arraylist_length(g_context.dataList); i++)
+    {
+        CABlockData_t *blockData = (CABlockData_t *) u_arraylist_get(g_context.dataList, i);
+        if (blockData && blockData->ttl < now)
+        {
+            OIC_LOG(INFO, TAG, "Deleting timed-out BlockData");
+            OIC_LOG(DEBUG, TAG, "BlockID is ");
+            OIC_LOG_BUFFER(DEBUG, TAG, (const uint8_t *) blockData->blockDataId->id,
+                           blockData->blockDataId->idLength);
+
+            blockData = (CABlockData_t *) u_arraylist_remove(g_context.dataList, i);
+            if (blockData)
+            {
+                // destroy memory
+                CADestroyDataSet(blockData->sentData);
+                CADestroyBlockID(blockData->blockDataId);
+                OICFree(blockData->payload);
+                OICFree(blockData);
+            }
+        }
+    }
+    oc_mutex_unlock(g_context.blockDataListMutex);
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+}
index 9cbc52f..c3247d2 100644 (file)
@@ -23,6 +23,7 @@
 #include <stdint.h>
 #include <stdbool.h>
 
+#include "octypes.h"
 #include "ocrandom.h"
 #include "cainterface.h"
 #include "caremotehandler.h"
@@ -51,13 +52,14 @@ static bool g_isInitialized = false;
 extern void CAsetPkixInfoCallback(CAgetPkixInfoHandler infCallback);
 extern void CAsetPskCredentialsCallback(CAgetPskCredentialsHandler credCallback);
 extern void CAsetCredentialTypesCallback(CAgetCredentialTypesHandler credCallback);
+extern void CAsetSetupPkContextCallback(CAsetupPkContextHandler setupPkCtxCallback);
 #endif // __WITH_DTLS__ or __WITH_TLS__
 
 
-CAResult_t CAInitialize()
+CAResult_t CAInitialize(CATransportAdapter_t transportType)
 {
     OIC_LOG_V(DEBUG, TAG, "IoTivity version is v%s", IOTIVITY_VERSION);
-    OIC_LOG(DEBUG, TAG, "CAInitialize");
+    OIC_LOG_V(DEBUG, TAG, "CAInitialize type : %d", transportType);
 
     if (!g_isInitialized)
     {
@@ -66,10 +68,11 @@ CAResult_t CAInitialize()
             OIC_LOG(ERROR, TAG, "Seed Random Failed");
         }
 
-        CAResult_t res = CAInitializeMessageHandler();
+        CAResult_t res = CAInitializeMessageHandler(transportType);
         if (res != CA_STATUS_OK)
         {
             OIC_LOG(ERROR, TAG, "CAInitialize has failed");
+            CATerminateMessageHandler();
             return res;
         }
         g_isInitialized = true;
@@ -142,7 +145,7 @@ void CARegisterHandler(CARequestCallback ReqHandler, CAResponseCallback RespHand
 }
 
 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 const CASecureEndpoint_t *CAGetSecureEndpointData(const CAEndpoint_t *peer)
 {
     OIC_LOG(DEBUG, TAG, "IN CAGetSecurePeerInfo");
@@ -156,7 +159,7 @@ const CASecureEndpoint_t *CAGetSecureEndpointData(const CAEndpoint_t *peer)
     OIC_LOG(DEBUG, TAG, "OUT CAGetSecurePeerInfo");
     return GetCASecureEndpointData(peer);
 }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
 CAResult_t CAregisterSslHandshakeCallback(CAErrorCallback tlsHandshakeCallback)
 {
@@ -208,6 +211,19 @@ CAResult_t CAregisterGetCredentialTypesHandler(CAgetCredentialTypesHandler getCr
     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
     return CA_STATUS_OK;
 }
+
+CAResult_t CAregisterSetupPkContextHandler(CAsetupPkContextHandler setupPkContextCallback)
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+
+    if (!g_isInitialized)
+    {
+        return CA_STATUS_NOT_INITIALIZED;
+    }
+    CAsetSetupPkContextCallback(setupPkContextCallback);
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+    return CA_STATUS_OK;
+}
 #endif // __WITH_DTLS__ or __WITH_TLS__
 
 CAResult_t CACreateEndpoint(CATransportFlags_t flags,
@@ -323,6 +339,11 @@ CAResult_t CASendRequest(const CAEndpoint_t *object, const CARequestInfo_t *requ
     {
         return CASendMessageMultiAdapter(object, requestInfo, CA_REQUEST_DATA);
     }
+    else if (requestInfo && requestInfo->info.event == CA_REQ_DISCONNECT &&
+            (object->adapter == CA_ADAPTER_TCP || object->adapter == CA_ALL_ADAPTERS))
+    {
+        return CADetachSendNetworkReqMessage(object, requestInfo->info.event, CA_NETWORK_COMMAND);
+    }
     else
     {
         return CADetachSendMessage(object, requestInfo, CA_REQUEST_DATA);
@@ -356,8 +377,6 @@ CAResult_t CASendResponse(const CAEndpoint_t *object, const CAResponseInfo_t *re
 
 CAResult_t CASelectNetwork(CATransportAdapter_t interestedNetwork)
 {
-    OIC_LOG_V(DEBUG, TAG, "Selected network : %d", interestedNetwork);
-
     if (!g_isInitialized)
     {
         return CA_STATUS_NOT_INITIALIZED;
@@ -499,8 +518,7 @@ CAResult_t CAEnableAnonECDHCipherSuite(const bool enable)
     CAResult_t res = CA_STATUS_FAILED;
 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
     // TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256    0xFF00 replaces 0xC018
-    // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256    0xC037
-    res = CAsetTlsCipherSuite(enable ? 0xFF00 : 0xC037);
+    res = CAsetTlsCipherSuite(enable ? 0xFF00 : 0x00);
     if (CA_STATUS_OK != res)
     {
         OIC_LOG_V(ERROR, TAG, "Failed to CAsetTlsCipherSuite : %d", res);
old mode 100644 (file)
new mode 100755 (executable)
index b0ffc3f..525f79f
@@ -35,6 +35,7 @@
 #include "cathreadpool.h"
 #include "caipadapter.h"
 #include "cainterface.h"
+#include "caipinterface.h"
 #include <coap/utlist.h>
 
 #ifdef RA_ADAPTER
 #include "catcpadapter.h"
 #endif
 
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+#include "ca_adapter_net_ssl.h"
+#endif
+
 #define TAG "OIC_CA_INF_CTR"
 
 #define CA_MEMORY_ALLOC_CHECK(arg) {if (arg == NULL) \
@@ -86,6 +91,7 @@ static int CAGetAdapterIndex(CATransportAdapter_t cType)
              return index;
          }
     }
+    OIC_LOG_V(ERROR, TAG, "adapter info [%d]", g_numberOfAdapters);
     return -1;
 }
 
@@ -160,6 +166,8 @@ static CAResult_t AddNetworkStateChangedCallback(CAAdapterStateChangedCB adapter
     callback->adapter = adapterCB;
     callback->conn = connCB;
     LL_APPEND(g_networkChangeCallbackList, callback);
+    OIC_LOG_V(INFO, TAG, "Added NetworkStateChanged Callback [%p]", callback);
+
     return CA_STATUS_OK;
 }
 
@@ -191,22 +199,6 @@ static CAResult_t RemoveNetworkStateChangedCallback(CAAdapterStateChangedCB adap
     return CA_STATUS_OK;
 }
 
-/**
- * Remove all network callback from the network callback list
- */
-static void RemoveAllNetworkStateChangedCallback()
-{
-    OIC_LOG(DEBUG, TAG, "Remove All NetworkStateChanged Callback");
-
-    CANetworkCallback_t* callback = NULL;
-    LL_FOREACH(g_networkChangeCallbackList, callback)
-    {
-        OIC_LOG(DEBUG, TAG, "remove all callbacks");
-        LL_DELETE(g_networkChangeCallbackList, callback);
-        OICFree(callback);
-    }
-}
-
 #ifdef RA_ADAPTER
 CAResult_t CASetAdapterRAInfo(const CARAInfo_t *caraInfo)
 {
@@ -214,16 +206,17 @@ CAResult_t CASetAdapterRAInfo(const CARAInfo_t *caraInfo)
 }
 #endif
 
-static void CAReceivedPacketCallback(const CASecureEndpoint_t *sep,
-                                     const void *data, uint32_t dataLen)
+static CAResult_t CAReceivedPacketCallback(const CASecureEndpoint_t *sep,
+                                           const void *data, uint32_t dataLen)
 {
     if (g_networkPacketReceivedCallback != NULL)
     {
-        g_networkPacketReceivedCallback(sep, data, dataLen);
+        return g_networkPacketReceivedCallback(sep, data, dataLen);
     }
     else
     {
-        OIC_LOG(ERROR, TAG, "network packet received callback is NULL!");
+        OIC_LOG(INFO, TAG, "network packet received callback is NULL!");
+        return CA_STATUS_OK;
     }
 }
 
@@ -235,6 +228,7 @@ static void CAAdapterChangedCallback(CATransportAdapter_t adapter, CANetworkStat
     {
         if (callback && callback->adapter)
         {
+            OIC_LOG_V(INFO, TAG, "IN application adapter changed callback [%p]", callback);
             if (CA_INTERFACE_UP == status)
             {
                 callback->adapter(adapter, true);
@@ -243,6 +237,7 @@ static void CAAdapterChangedCallback(CATransportAdapter_t adapter, CANetworkStat
             {
                 callback->adapter(adapter, false);
             }
+            OIC_LOG_V(INFO, TAG, "OUT application adapter changed callback [%p]", callback);
         }
     }
     OIC_LOG_V(DEBUG, TAG, "[%d] adapter status is changed to [%d]", adapter, status);
@@ -277,39 +272,71 @@ static void CAAdapterErrorHandleCallback(const CAEndpoint_t *endpoint,
     }
 }
 
-void CAInitializeAdapters(ca_thread_pool_t handle)
+void CAInitializeAdapters(ca_thread_pool_t handle, CATransportAdapter_t transportType)
 {
-    OIC_LOG(DEBUG, TAG, "initialize adapters..");
+    OIC_LOG_V(DEBUG, TAG, "initialize adapters %d", transportType);
+
+    // Initialize ssl adapter.
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+    if (CA_STATUS_OK != CAinitSslAdapter())
+    {
+        OIC_LOG(ERROR, TAG, "Failed to init SSL adapter");
+    }
+#endif
 
     // Initialize adapters and register callback.
 #ifdef IP_ADAPTER
-    CAInitializeIP(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback,
-                   CAAdapterErrorHandleCallback, handle);
+    if ((transportType & CA_ADAPTER_IP) || (CA_DEFAULT_ADAPTER == transportType)
+            || (transportType == CA_ALL_ADAPTERS))
+    {
+        CAInitializeIP(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback,
+                       CAAdapterErrorHandleCallback, handle);
+    }
 #endif /* IP_ADAPTER */
 
 #ifdef EDR_ADAPTER
-    CAInitializeEDR(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback,
-                    CAConnectionChangedCallback, CAAdapterErrorHandleCallback, handle);
+    if ((transportType & CA_ADAPTER_RFCOMM_BTEDR) || (CA_DEFAULT_ADAPTER == transportType)
+            || (transportType == CA_ALL_ADAPTERS))
+    {
+        CAInitializeEDR(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback,
+                        CAConnectionChangedCallback, CAAdapterErrorHandleCallback, handle);
+    }
 #endif /* EDR_ADAPTER */
 
 #ifdef LE_ADAPTER
-    CAInitializeLE(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback,
-                   CAConnectionChangedCallback, CAAdapterErrorHandleCallback, handle);
+    if ((transportType & CA_ADAPTER_GATT_BTLE) || (CA_DEFAULT_ADAPTER == transportType)
+            || (transportType == CA_ALL_ADAPTERS))
+    {
+        CAInitializeLE(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback,
+                       CAConnectionChangedCallback, CAAdapterErrorHandleCallback, handle);
+    }
 #endif /* LE_ADAPTER */
 
 #ifdef RA_ADAPTER
-    CAInitializeRA(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback,
-                   handle);
+    if ((transportType & CA_ADAPTER_REMOTE_ACCESS) || (CA_DEFAULT_ADAPTER == transportType)
+            || (transportType == CA_ALL_ADAPTERS))
+    {
+        CAInitializeRA(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback,
+                       handle);
+    }
 #endif /* RA_ADAPTER */
 
 #ifdef TCP_ADAPTER
-    CAInitializeTCP(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback,
-                    CAConnectionChangedCallback, CAAdapterErrorHandleCallback, handle);
+    if ((transportType & CA_ADAPTER_TCP) || (CA_DEFAULT_ADAPTER == transportType)
+            || (transportType == CA_ALL_ADAPTERS))
+    {
+        CAInitializeTCP(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback,
+                        CAConnectionChangedCallback, CAAdapterErrorHandleCallback, handle);
+    }
 #endif /* TCP_ADAPTER */
 
 #ifdef NFC_ADAPTER
-    CAInitializeNFC(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback,
-                    CAAdapterErrorHandleCallback, handle);
+    if ((transportType & CA_ADAPTER_NFC) || (CA_DEFAULT_ADAPTER == transportType)
+            || (transportType == CA_ALL_ADAPTERS))
+    {
+        CAInitializeNFC(CARegisterCallback, CAReceivedPacketCallback, CAAdapterChangedCallback,
+                        CAAdapterErrorHandleCallback, handle);
+    }
 #endif /* NFC_ADAPTER */
 }
 
@@ -423,12 +450,14 @@ CAResult_t CAGetNetworkInfo(CAEndpoint_t **info, uint32_t *size)
                 resSize += tempSize[index];
             }
 
+#ifndef __TIZENRT__
             OIC_LOG_V(DEBUG,
                       TAG,
                       "%" PRIu32 " adapter network info size is %" PRIu32 " res:%d",
                       index,
                       tempSize[index],
                       res);
+#endif
         }
     }
 
@@ -532,7 +561,7 @@ CAResult_t CASendUnicastData(const CAEndpoint_t *endpoint, const void *data, uin
 
         if (-1 == index)
         {
-            OIC_LOG(ERROR, TAG, "unknown transport type!");
+            OIC_LOG_V(ERROR, TAG, "unknown transport type[%d]", connType);
             return CA_STATUS_INVALID_PARAM;
         }
 
@@ -759,6 +788,10 @@ void CATerminateAdapters()
         }
     }
 
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+    CAdeinitSslAdapter();
+#endif
+
     OICFree(g_adapterHandler);
     g_adapterHandler = NULL;
     g_numberOfAdapters = 0;
@@ -803,3 +836,33 @@ CAResult_t CAReadData()
 }
 #endif
 
+#ifdef IP_ADAPTER
+CAResult_t CASetMulticastTTL(size_t ttl)
+{
+    return CAIPSetMulticastTTL(ttl);
+}
+
+CAResult_t CAGetMulticastTTL(size_t *ttl)
+{
+    return CAIPGetMulticastTTL(ttl);
+}
+#endif
+
+#ifdef TCP_ADAPTER
+CAResult_t CADisconnectSession(const CAEndpoint_t *endpoint)
+{
+    return CATCPDisconnectSession(endpoint);
+}
+#endif
+
+#ifdef LE_ADAPTER
+void CAStartGattServer()
+{
+       CALEStartGattServer();
+}
+
+void CAStopGattServer()
+{
+       CALEStopGattServer();
+}
+#endif
old mode 100644 (file)
new mode 100755 (executable)
index 10390eb..dcc172e
@@ -28,6 +28,7 @@
 #include "caremotehandler.h"
 #include "caprotocolmessage.h"
 #include "logger.h"
+#include "trace.h"
 #ifndef WITH_UPSTREAM_LIBCOAP
 #include "coap/config.h"
 #endif
@@ -90,6 +91,19 @@ static void CALogPayloadInfo(CAInfo_t *info);
 static bool CADropSecondMessage(CAHistory_t *history, const CAEndpoint_t *endpoint, uint16_t id,
                                 CAToken_t token, uint8_t tokenLength);
 
+/**
+ * print send / receive message of CoAP.
+ * @param[in] data      CA information which has send/receive message and endpoint.
+ * @param[in] pdu       CoAP pdu low data.
+ */
+static void CALogPDUInfo(const CAData_t *data, const coap_pdu_t *pdu);
+
+#ifndef ARDUINO
+static char g_headerBuffer[MAX_LOG_BUFFER_SIZE] = {0};
+static size_t g_headerIndex = 0;
+static void CASamsungLogMessage(const CAData_t *data, const coap_pdu_t *pdu);
+#endif
+
 #ifdef WITH_BWT
 void CAAddDataToSendThread(CAData_t *data)
 {
@@ -190,7 +204,7 @@ static CAData_t* CAGenerateHandlerData(const CAEndpoint_t *endpoint,
         if (CADropSecondMessage(&caglobals.ca.requestHistory, endpoint, reqInfo->info.messageId,
                                 reqInfo->info.token, reqInfo->info.tokenLength))
         {
-            OIC_LOG(ERROR, TAG, "Second Request with same Token, Drop it");
+            OIC_LOG(INFO, TAG, "Second Request with same Token, Drop it");
             CADestroyRequestInfoInternal(reqInfo);
             goto exit;
         }
@@ -406,7 +420,9 @@ static void CAReceiveThreadProcess(void *threadData)
 {
 #ifndef SINGLE_HANDLE
     CAData_t *data = (CAData_t *) threadData;
+    OIC_TRACE_BEGIN(%s:CAProcessReceivedData, TAG);
     CAProcessReceivedData(data);
+    OIC_TRACE_END();
 #else
     (void)threadData;
 #endif
@@ -467,7 +483,7 @@ static CAResult_t CAProcessMulticastData(const CAData_t *data)
     }
 #endif // WITH_BWT
 
-    CALogPDUInfo(pdu, data->remoteEndpoint);
+    CALogPDUInfo(data, pdu);
 
     res = CASendMulticastData(data->remoteEndpoint, pdu->transport_hdr, pdu->length, data->dataType);
     if (CA_STATUS_OK != res)
@@ -494,6 +510,21 @@ static CAResult_t CAProcessSendData(const CAData_t *data)
 
     CAResult_t res = CA_STATUS_FAILED;
 
+    if (CA_NETWORK_COMMAND == data->dataType)
+    {
+        if (CA_REQ_DISCONNECT == data->eventInfo)
+        {
+#ifdef TCP_ADAPTER
+            // request TCP disconnect
+            if (CA_ADAPTER_TCP == data->remoteEndpoint->adapter)
+            {
+                OIC_LOG(INFO, TAG, "request TCP disconnect");
+                return CADisconnectSession(data->remoteEndpoint);
+            }
+#endif
+        }
+    }
+
     CASendDataType_t type = data->type;
 
     coap_pdu_t *pdu = NULL;
@@ -564,7 +595,7 @@ static CAResult_t CAProcessSendData(const CAData_t *data)
                 }
             }
 #endif // WITH_BWT
-            CALogPDUInfo(pdu, data->remoteEndpoint);
+            CALogPDUInfo(data, pdu);
 
             OIC_LOG_V(INFO, TAG, "CASendUnicastData type : %d", data->dataType);
             res = CASendUnicastData(data->remoteEndpoint, pdu->transport_hdr, pdu->length, data->dataType);
@@ -585,7 +616,7 @@ static CAResult_t CAProcessSendData(const CAData_t *data)
             else
 #endif
 #ifdef ROUTING_GATEWAY
-            if(!skipRetransmission)
+            if (!skipRetransmission)
 #endif
             {
                 // for retransmission
@@ -647,7 +678,6 @@ static CAResult_t CAProcessSendData(const CAData_t *data)
         CAProcessMulticastData(data);
 #endif
     }
-
     return CA_STATUS_OK;
 }
 
@@ -655,7 +685,9 @@ static CAResult_t CAProcessSendData(const CAData_t *data)
 static void CASendThreadProcess(void *threadData)
 {
     CAData_t *data = (CAData_t *) threadData;
+    OIC_TRACE_BEGIN(%s:CAProcessSendData, TAG);
     CAProcessSendData(data);
+    OIC_TRACE_END();
 }
 #endif
 
@@ -723,15 +755,33 @@ static bool CADropSecondMessage(CAHistory_t *history, const CAEndpoint_t *ep, ui
     return ret;
 }
 
-static void CAReceivedPacketCallback(const CASecureEndpoint_t *sep,
-                                     const void *data, uint32_t dataLen)
+static CAResult_t CAReceivedPacketCallback(const CASecureEndpoint_t *sep,
+                                           const void *data, uint32_t dataLen)
 {
-    VERIFY_NON_NULL_VOID(sep, TAG, "remoteEndpoint");
-    VERIFY_NON_NULL_VOID(data, TAG, "data");
+    VERIFY_NON_NULL(sep, TAG, "remoteEndpoint");
+    VERIFY_NON_NULL(data, TAG, "data");
+    OIC_TRACE_BEGIN(%s:CAReceivedPacketCallback, TAG);
+
+    if (0 == dataLen)
+    {
+        OIC_LOG(ERROR, TAG, "dataLen is zero");
+        OIC_TRACE_END();
 
+        return CA_STATUS_FAILED;
+    }
+
+    // samsung log
     OIC_LOG(DEBUG, TAG, "received pdu data :");
-    OIC_LOG_BUFFER(DEBUG, TAG,  data, dataLen);
+    if (dataLen < 32)
+    {
+        OIC_LOG_BUFFER(DEBUG, TAG,  data, dataLen);
+    }
+    else
+    {
+        OIC_LOG_BUFFER(DEBUG, TAG,  data, 32);
+    }
 
+    CAResult_t res = CA_STATUS_OK;
     uint32_t code = CA_NOT_FOUND;
     CAData_t *cadata = NULL;
 
@@ -740,7 +790,8 @@ static void CAReceivedPacketCallback(const CASecureEndpoint_t *sep,
     if (NULL == pdu)
     {
         OIC_LOG(ERROR, TAG, "Parse PDU failed");
-        return;
+        res = CA_STATUS_FAILED;
+        goto exit;
     }
 
     OIC_LOG_V(DEBUG, TAG, "code = %d", code);
@@ -751,7 +802,7 @@ static void CAReceivedPacketCallback(const CASecureEndpoint_t *sep,
         {
             OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, CAGenerateHandlerData failed!");
             coap_delete_pdu(pdu);
-            return;
+            goto exit;
         }
     }
     else
@@ -761,7 +812,7 @@ static void CAReceivedPacketCallback(const CASecureEndpoint_t *sep,
         {
             OIC_LOG(ERROR, TAG, "CAReceivedPacketCallback, CAGenerateHandlerData failed!");
             coap_delete_pdu(pdu);
-            return;
+            goto exit;
         }
 
 #ifdef WITH_TCP
@@ -799,6 +850,8 @@ static void CAReceivedPacketCallback(const CASecureEndpoint_t *sep,
 
     cadata->type = SEND_TYPE_UNICAST;
 
+    CALogPDUInfo(cadata, pdu);
+
 #ifdef SINGLE_THREAD
     CAProcessReceivedData(cadata);
 #else
@@ -824,6 +877,55 @@ static void CAReceivedPacketCallback(const CASecureEndpoint_t *sep,
 #endif // SINGLE_THREAD
 
     coap_delete_pdu(pdu);
+
+exit:
+    OIC_LOG(DEBUG, TAG, "OUT - Recv Thread");
+    OIC_TRACE_END();
+    return res;
+}
+
+static void CAAdapterStateChangedCallback(CATransportAdapter_t transportType, bool enabled)
+{
+    if (!enabled)
+    {
+        CAClearMessageHandler(transportType);
+    }
+}
+
+static bool CAClearQueueEndpointDataContext(void *data, uint32_t size, void *ctx)
+{
+    if (NULL == data || NULL == ctx)
+    {
+        return false;
+    }
+
+    CAData_t *caData = (CAData_t *)data;
+    const CAEndpoint_t *endpoint = (const CAEndpoint_t *)ctx;
+
+    if (NULL != caData && NULL != caData->remoteEndpoint)
+    {
+        if (strcmp(caData->remoteEndpoint->addr, endpoint->addr) == 0
+            && caData->remoteEndpoint->port == endpoint->port
+            && caData->remoteEndpoint->adapter == endpoint->adapter)
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
+static void CAConnectionStateChangedCallback(const CAEndpoint_t *info, bool isConnected)
+{
+    if (!isConnected)
+    {
+        CAResult_t res = CAQueueingThreadClearContextData(&g_sendThread,
+                                                          CAClearQueueEndpointDataContext,
+                                                          info);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "Could not clear the send queue");
+        }
+    }
 }
 
 void CAHandleRequestResponseCallbacks()
@@ -837,11 +939,11 @@ void CAHandleRequestResponseCallbacks()
     // #1 parse the data
     // #2 get endpoint
 
-    ca_mutex_lock(g_receiveThread.threadMutex);
+    oc_mutex_lock(g_receiveThread.threadMutex);
 
     u_queue_message_t *item = u_queue_get_element(g_receiveThread.dataQueue);
 
-    ca_mutex_unlock(g_receiveThread.threadMutex);
+    oc_mutex_unlock(g_receiveThread.threadMutex);
 
     if (NULL == item || NULL == item->msg)
     {
@@ -909,7 +1011,7 @@ static CAData_t* CAPrepareSendData(const CAEndpoint_t *endpoint, const void *sen
 #else
         // clone response info
         CAResponseInfo_t *response = CACloneResponseInfo((CAResponseInfo_t *)sendData);
-        if(!response)
+        if (!response)
         {
             OIC_LOG(ERROR, TAG, "CACloneResponseInfo failed");
             goto exit;
@@ -947,6 +1049,43 @@ exit:
     return NULL;
 }
 
+CAResult_t CADetachSendNetworkReqMessage(const CAEndpoint_t *endpoint,
+                                         CAConnectEvent_t event,
+                                         CADataType_t dataType)
+{
+    VERIFY_NON_NULL(endpoint, TAG, "endpoint");
+
+    if (false == CAIsSelectedNetworkAvailable())
+    {
+        return CA_STATUS_FAILED;
+    }
+
+#ifndef SINGLE_THREAD
+    CAData_t *cadata = (CAData_t *) OICCalloc(1, sizeof(CAData_t));
+    if (!cadata)
+    {
+        OIC_LOG(ERROR, TAG, "cadata memory allocation failed");
+        return CA_STATUS_FAILED;
+    }
+
+    CAEndpoint_t* ep = CACloneEndpoint(endpoint);
+    if (!ep)
+    {
+        OIC_LOG(ERROR, TAG, "endpoint clone failed");
+        OICFree(cadata);
+        return CA_STATUS_FAILED;
+    }
+
+    cadata->remoteEndpoint = ep;
+    cadata->eventInfo = event;
+    cadata->dataType = dataType;
+
+    CAQueueingThreadAddData(&g_sendThread, cadata, sizeof(CAData_t));
+#endif
+
+    return CA_STATUS_OK;
+}
+
 CAResult_t CADetachSendMessage(const CAEndpoint_t *endpoint, const void *sendMsg,
                                CADataType_t dataType)
 {
@@ -974,6 +1113,8 @@ CAResult_t CADetachSendMessage(const CAEndpoint_t *endpoint, const void *sendMsg
         return CA_MEMORY_ALLOC_FAILED;
     }
 
+    OIC_LOG_V(INFO_PRIVATE, TAG, "DID of endpoint of this message is %s", endpoint->remoteId);
+
 #ifdef SINGLE_THREAD
     CAResult_t result = CAProcessSendData(data);
     if (CA_STATUS_OK != result)
@@ -989,6 +1130,7 @@ CAResult_t CADetachSendMessage(const CAEndpoint_t *endpoint, const void *sendMsg
 #ifdef WITH_BWT
     if (CAIsSupportedBlockwiseTransfer(endpoint->adapter))
     {
+        CACheckAndDeleteTimedOutBlockData();
         // send block data
         CAResult_t res = CASendBlockWiseData(data);
         if (CA_NOT_SUPPORTED == res)
@@ -1001,6 +1143,7 @@ CAResult_t CADetachSendMessage(const CAEndpoint_t *endpoint, const void *sendMsg
         {
             CADestroyData(data, sizeof(CAData_t));
         }
+
         return res;
     }
     else
@@ -1026,7 +1169,7 @@ void CASetNetworkMonitorCallback(CANetworkMonitorCallback nwMonitorHandler)
     g_nwMonitorHandler = nwMonitorHandler;
 }
 
-CAResult_t CAInitializeMessageHandler()
+CAResult_t CAInitializeMessageHandler(CATransportAdapter_t transportType)
 {
     CASetPacketReceivedCallback(CAReceivedPacketCallback);
     CASetErrorHandleCallback(CAErrorHandler);
@@ -1046,19 +1189,18 @@ CAResult_t CAInitializeMessageHandler()
     if (CA_STATUS_OK != res)
     {
         OIC_LOG(ERROR, TAG, "Failed to Initialize send queue thread");
-        ca_thread_pool_free(g_threadPoolHandle);
-        g_threadPoolHandle = NULL;
         return res;
     }
 
     // start send thread
+#ifndef __TIZENRT__
     res = CAQueueingThreadStart(&g_sendThread);
+#else
+    res = CAQueueingThreadStart(&g_sendThread, "IoT_MessageHandlerQueue");
+#endif
     if (CA_STATUS_OK != res)
     {
         OIC_LOG(ERROR, TAG, "thread start error(send thread).");
-        ca_thread_pool_free(g_threadPoolHandle);
-        g_threadPoolHandle = NULL;
-        CAQueueingThreadDestroy(&g_sendThread);
         return res;
     }
 
@@ -1068,9 +1210,6 @@ CAResult_t CAInitializeMessageHandler()
     if (CA_STATUS_OK != res)
     {
         OIC_LOG(ERROR, TAG, "Failed to Initialize receive queue thread");
-        ca_thread_pool_free(g_threadPoolHandle);
-        g_threadPoolHandle = NULL;
-        CAQueueingThreadDestroy(&g_sendThread);
         return res;
     }
 
@@ -1080,10 +1219,6 @@ CAResult_t CAInitializeMessageHandler()
     if (CA_STATUS_OK != res)
     {
         OIC_LOG(ERROR, TAG, "thread start error(receive thread).");
-        ca_thread_pool_free(g_threadPoolHandle);
-        g_threadPoolHandle = NULL;
-        CAQueueingThreadDestroy(&g_sendThread);
-        CAQueueingThreadDestroy(&g_receiveThread);
         return res;
     }
 #endif // SINGLE_HANDLE
@@ -1094,10 +1229,6 @@ CAResult_t CAInitializeMessageHandler()
     if (CA_STATUS_OK != res)
     {
         OIC_LOG(ERROR, TAG, "Failed to Initialize Retransmission.");
-        ca_thread_pool_free(g_threadPoolHandle);
-        g_threadPoolHandle = NULL;
-        CAQueueingThreadDestroy(&g_sendThread);
-        CAQueueingThreadDestroy(&g_receiveThread);
         return res;
     }
 
@@ -1107,11 +1238,6 @@ CAResult_t CAInitializeMessageHandler()
     if (CA_STATUS_OK != res)
     {
         OIC_LOG(ERROR, TAG, "Failed to Initialize BlockWiseTransfer.");
-        ca_thread_pool_free(g_threadPoolHandle);
-        g_threadPoolHandle = NULL;
-        CAQueueingThreadDestroy(&g_sendThread);
-        CAQueueingThreadDestroy(&g_receiveThread);
-        CARetransmissionDestroy(&g_retransmissionContext);
         return res;
     }
 #endif
@@ -1121,16 +1247,12 @@ CAResult_t CAInitializeMessageHandler()
     if (CA_STATUS_OK != res)
     {
         OIC_LOG(ERROR, TAG, "thread start error(retransmission thread).");
-        ca_thread_pool_free(g_threadPoolHandle);
-        g_threadPoolHandle = NULL;
-        CAQueueingThreadDestroy(&g_sendThread);
-        CAQueueingThreadDestroy(&g_receiveThread);
-        CARetransmissionDestroy(&g_retransmissionContext);
         return res;
     }
 
     // initialize interface adapters by controller
-    CAInitializeAdapters(g_threadPoolHandle);
+    CAInitializeAdapters(g_threadPoolHandle, transportType);
+    CASetNetworkMonitorCallbacks(CAAdapterStateChangedCallback, CAConnectionStateChangedCallback);
 #else
     // retransmission initialize
     CAResult_t res = CARetransmissionInitialize(&g_retransmissionContext, NULL, CASendUnicastData,
@@ -1147,6 +1269,44 @@ CAResult_t CAInitializeMessageHandler()
     return CA_STATUS_OK;
 }
 
+static bool CAClearQueueAdapterDataContext(void *data, uint32_t size, void *ctx)
+{
+    if (NULL == data || NULL == ctx)
+    {
+        return false;
+    }
+
+    CAData_t *caData = (CAData_t *)data;
+    CATransportAdapter_t *type = (CATransportAdapter_t *)ctx;
+
+    if (NULL != caData && NULL != caData->remoteEndpoint
+        && caData->remoteEndpoint->adapter == *type)
+    {
+        return true;
+    }
+    return false;
+}
+
+void CAClearMessageHandler(CATransportAdapter_t transportType)
+{
+    CATransportAdapter_t *typeCtx = &transportType;
+
+    CAResult_t res = CAQueueingThreadClearContextData(&g_sendThread,
+                                                      CAClearQueueAdapterDataContext,
+                                                      typeCtx);
+
+    if (res != CA_STATUS_OK)
+    {
+        OIC_LOG_V(ERROR, TAG, "Clear send data failed[%d]", res);
+    }
+
+    res = CARetransmissionClearAdapterData(&g_retransmissionContext, transportType);
+    if (res != CA_STATUS_OK)
+    {
+        OIC_LOG_V(ERROR, TAG, "Clear retransmission data failed[%d]", res);
+    }
+}
+
 void CATerminateMessageHandler()
 {
 #ifndef SINGLE_THREAD
@@ -1216,28 +1376,6 @@ void CATerminateMessageHandler()
 #endif // SINGLE_THREAD
 }
 
-void CALogPDUInfo(coap_pdu_t *pdu, const CAEndpoint_t *endpoint)
-{
-    VERIFY_NON_NULL_VOID(pdu, TAG, "pdu");
-    VERIFY_NON_NULL_VOID(endpoint, TAG, "endpoint");
-
-#ifdef WITH_BWT
-    if (CAIsSupportedBlockwiseTransfer(endpoint->adapter))
-    {
-        OIC_LOG_V(DEBUG, TAG, "PDU Maker - type : %d", pdu->transport_hdr->udp.type);
-
-        OIC_LOG_V(DEBUG, TAG, "PDU Maker - code : %d", pdu->transport_hdr->udp.code);
-    }
-#endif
-
-    OIC_LOG(DEBUG, TAG, "PDU Maker - token :");
-    OIC_LOG_BUFFER(DEBUG, TAG, pdu->transport_hdr->udp.token,
-                   pdu->transport_hdr->udp.token_length);
-
-    OIC_LOG(DEBUG, TAG, "PDU Maker - payload :");
-    OIC_LOG_BUFFER(DEBUG, TAG,  (const uint8_t *) pdu->transport_hdr, pdu->length);
-}
-
 static void CALogPayloadInfo(CAInfo_t *info)
 {
     if (info)
@@ -1277,11 +1415,16 @@ void CAErrorHandler(const CAEndpoint_t *endpoint,
                     CAResult_t result)
 {
     OIC_LOG(DEBUG, TAG, "CAErrorHandler IN");
-
-#ifndef SINGLE_THREAD
     VERIFY_NON_NULL_VOID(endpoint, TAG, "remoteEndpoint");
     VERIFY_NON_NULL_VOID(data, TAG, "data");
 
+    if (0 == dataLen)
+    {
+        OIC_LOG(ERROR, TAG, "dataLen is zero");
+        return;
+    }
+
+#ifndef SINGLE_THREAD
     uint32_t code = CA_NOT_FOUND;
     //Do not free remoteEndpoint and data. Currently they will be freed in data thread
     //Get PDU data
@@ -1304,6 +1447,8 @@ void CAErrorHandler(const CAEndpoint_t *endpoint,
 
     CAQueueingThreadAddData(&g_receiveThread, cadata, sizeof(CAData_t));
     coap_delete_pdu(pdu);
+#else
+    (void)result;
 #endif
 
     OIC_LOG(DEBUG, TAG, "CAErrorHandler OUT");
@@ -1357,3 +1502,311 @@ static void CASendErrorInfo(const CAEndpoint_t *endpoint, const CAInfo_t *info,
 #endif
     OIC_LOG(DEBUG, TAG, "CASendErrorInfo OUT");
 }
+
+
+
+#ifndef ARDUINO
+#ifdef __TIZENRT__
+static void CALogPDUInfo(const CAData_t *data, const coap_pdu_t *pdu)
+{
+
+       if(data == NULL || pdu == NULL)
+       {
+               printf("INVALID INPUT, CALogPDUInfo FAIL\n");
+       }
+
+       char type[30] = "";
+
+       switch(data->dataType)
+       {
+               case CA_REQUEST_DATA:
+                       strncpy(type, "\e[32mREQUEST  <<<<\e[m", 30);
+                       break;
+               case CA_RESPONSE_DATA:
+                       strncpy(type, "\e[36mRESPONSE >>>>\e[m", 30);
+                       break;
+               case CA_ERROR_DATA:
+                       strncpy(type, "ERROR", 30);
+                       break;
+               case CA_RESPONSE_FOR_RES:
+                       strncpy(type, "RESP_RES >>>>", 30);
+                       break;
+               default:
+                       snprintf(type, 30, "Type : %d", data->dataType);
+                       break;
+       }
+
+
+       char method[20] = "";
+       const CAInfo_t *info = NULL;
+       if (NULL != data->requestInfo)
+       {
+               switch(data->requestInfo->method)
+               {
+                       case CA_GET:
+                               strncpy(method, "GET", 20);
+                               break;
+                       case CA_POST:
+                               strncpy(method, "POST", 20);
+                               break;
+                       case CA_PUT:
+                               strncpy(method, "PUT", 20);
+                               break;
+                       case CA_DELETE:
+                               strncpy(method, "DEL", 20);
+                               break;
+                       default:
+                               sprintf(method, "Method : %d", data->requestInfo->method);
+                               break;
+               }
+               info = &data->requestInfo->info;
+       }
+
+       if(NULL != data->responseInfo)
+       {
+
+               sprintf(method, "result : %d", data->responseInfo->result);
+               info = &data->responseInfo->info;
+       }
+
+
+       char log_buffer[1024] = "";
+       sprintf(log_buffer, "CA_LOG [%5d] | %-13s | %-12s | msg size : %4d | %s", pdu->transport_hdr->udp.id , type, method, pdu->length, info->resourceUri);
+
+       puts(log_buffer);
+}
+
+
+#else
+
+static void CALogPDUInfo(const CAData_t *data, const coap_pdu_t *pdu)
+{
+    OIC_LOG(DEBUG, TAG, "CALogPDUInfo");
+
+    VERIFY_NON_NULL_VOID(data, TAG, "data");
+    VERIFY_NON_NULL_VOID(pdu, TAG, "pdu");
+    OIC_TRACE_BEGIN(%s:CALogPDUInfo, TAG);
+
+    OIC_LOG(INFO, ANALYZER_TAG, "=================================================");
+    if(SEND_TYPE_MULTICAST == data->type)
+    {
+        OIC_LOG(INFO, ANALYZER_TAG, "Is Multicast = true");
+    }
+    else
+    {
+        OIC_LOG(INFO, ANALYZER_TAG, "Is Multicast = false");
+    }
+
+    if (NULL != data->remoteEndpoint)
+    {
+        CALogAdapterTypeInfo(data->remoteEndpoint->adapter);
+        OIC_LOG_V(INFO, ANALYZER_TAG, "Address = [%s]:[%d]", data->remoteEndpoint->addr,
+                  data->remoteEndpoint->port);
+    }
+
+    switch(data->dataType)
+    {
+        case CA_REQUEST_DATA:
+            OIC_LOG(INFO, ANALYZER_TAG, "Data Type = [CA_REQUEST_DATA]");
+            break;
+        case CA_RESPONSE_DATA:
+            OIC_LOG(INFO, ANALYZER_TAG, "Data Type = [CA_RESPONSE_DATA]");
+            break;
+        case CA_ERROR_DATA:
+            OIC_LOG(INFO, ANALYZER_TAG, "Data Type = [CA_ERROR_DATA]");
+            break;
+        case CA_RESPONSE_FOR_RES:
+            OIC_LOG(INFO, ANALYZER_TAG, "Data Type = [CA_RESPONSE_FOR_RES]");
+            break;
+        default:
+            OIC_LOG_V(INFO, ANALYZER_TAG, "Data Type = [%d]", data->dataType);
+            break;
+    }
+
+    const CAInfo_t *info = NULL;
+    if (NULL != data->requestInfo)
+    {
+        switch(data->requestInfo->method)
+        {
+            case CA_GET:
+                OIC_LOG(INFO, ANALYZER_TAG, "Method = [GET]");
+                break;
+            case CA_POST:
+                OIC_LOG(INFO, ANALYZER_TAG, "Method = [POST]");
+                break;
+            case CA_PUT:
+                OIC_LOG(INFO, ANALYZER_TAG, "Method = [PUT]");
+                break;
+            case CA_DELETE:
+                OIC_LOG(INFO, ANALYZER_TAG, "Method = [DELETE]");
+                break;
+            default:
+                OIC_LOG_V(INFO, ANALYZER_TAG, "Method = [%d]", data->requestInfo->method);
+                break;
+        }
+        info = &data->requestInfo->info;
+    }
+
+    if (NULL != data->responseInfo)
+    {
+        OIC_LOG_V(INFO, ANALYZER_TAG, "result code = [%d]", data->responseInfo->result);
+        info = &data->responseInfo->info;
+    }
+
+    if (pdu->transport_hdr)
+    {
+        OIC_LOG_V(INFO, ANALYZER_TAG, "Msg ID = [%d]", pdu->transport_hdr->udp.id);
+    }
+
+    if (info)
+    {
+        OIC_LOG(INFO, ANALYZER_TAG, "Coap Token");
+        OIC_LOG_BUFFER(INFO, ANALYZER_TAG, (const uint8_t *) info->token, info->tokenLength);
+        OIC_TRACE_BUFFER("OIC_CA_MSG_HANDLE:CALogPDUInfo:token",
+                         (const uint8_t *) info->token, info->tokenLength);
+        OIC_LOG_V(INFO, ANALYZER_TAG, "Res URI = [%s]", info->resourceUri);
+        OIC_TRACE_MARK(%s:CALogPDUInfo:uri:%s, TAG, info->resourceUri);
+
+        if (CA_FORMAT_APPLICATION_CBOR == info->payloadFormat)
+        {
+            OIC_LOG(INFO, ANALYZER_TAG, "Payload Format = [CA_FORMAT_APPLICATION_CBOR]");
+        }
+        else
+        {
+            OIC_LOG_V(INFO, ANALYZER_TAG, "Payload Format = [%d]", info->payloadFormat);
+        }
+    }
+
+    size_t payloadLen = (pdu->data) ? (unsigned char *) pdu->hdr + pdu->length - pdu->data : 0;
+    OIC_LOG_V(INFO, ANALYZER_TAG, "CoAP Message Full Size = [%lu]", pdu->length);
+    OIC_LOG(INFO, ANALYZER_TAG, "CoAP Header (+ 0xFF)");
+    OIC_LOG_BUFFER(INFO, ANALYZER_TAG,  (const uint8_t *) pdu->transport_hdr,
+                   pdu->length - payloadLen);
+    OIC_LOG_V(INFO, ANALYZER_TAG, "CoAP Header size = [%lu]", pdu->length - payloadLen);
+
+    OIC_LOG_V(INFO, ANALYZER_TAG, "CoAP Payload");
+    OIC_LOG_BUFFER(INFO_PRIVATE, ANALYZER_TAG, pdu->data, payloadLen);
+    OIC_LOG_V(INFO, ANALYZER_TAG, "CoAP Payload Size = [%lu]", payloadLen);
+    OIC_LOG(INFO, ANALYZER_TAG, "=================================================");
+
+    // samsung log
+    CASamsungLogMessage(data, pdu);
+    OIC_TRACE_END();
+}
+
+static void CASamsungLogMessage(const CAData_t *data, const coap_pdu_t *pdu)
+{
+    OIC_LOG(INFO, TAG, "CASamsungLogMessage");
+    VERIFY_NON_NULL_VOID(data, TAG, "data");
+    VERIFY_NON_NULL_VOID(pdu, TAG, "pdu");
+    VERIFY_NON_NULL_VOID(data->remoteEndpoint, TAG, "data->remoteEndpoint");
+
+    const CAInfo_t *info = NULL;
+    if (NULL != data->requestInfo)
+    {
+        info = &data->requestInfo->info;
+    }
+
+    if (NULL != data->responseInfo)
+    {
+        info = &data->responseInfo->info;
+    }
+
+    VERIFY_NON_NULL_VOID(info, TAG, "info");
+
+    memset(g_headerBuffer, 0, MAX_LOG_BUFFER_SIZE);
+    g_headerIndex = 0;
+
+    g_headerBuffer[g_headerIndex++] = data->dataType;
+    g_headerBuffer[g_headerIndex++] = '|';
+    g_headerBuffer[g_headerIndex++] = data->remoteEndpoint->adapter;
+    g_headerBuffer[g_headerIndex++] = '|';
+    g_headerBuffer[g_headerIndex++] = data->type;
+    g_headerBuffer[g_headerIndex++] = '|';
+
+    if (NULL != data->remoteEndpoint)
+    {
+        int i = 0;
+        while (NULL != data->remoteEndpoint->addr[i])
+        {
+            g_headerBuffer[g_headerIndex++] = data->remoteEndpoint->addr[i];
+            i++;
+        }
+        g_headerBuffer[g_headerIndex++] = ':';
+        g_headerBuffer[g_headerIndex++] = (data->remoteEndpoint->port >> 8) & 0x0000ff;
+        g_headerBuffer[g_headerIndex++] = data->remoteEndpoint->port & 0x000000ff;
+    }
+
+    g_headerBuffer[g_headerIndex++] = '|';
+    if (data->requestInfo)
+    {
+        g_headerBuffer[g_headerIndex++] = data->requestInfo->method;
+    }
+    else
+    {
+        g_headerBuffer[g_headerIndex++] = 0;
+    }
+
+    g_headerBuffer[g_headerIndex++] = '|';
+    if (data->responseInfo)
+    {
+        g_headerBuffer[g_headerIndex++] = data->responseInfo->result;
+    }
+    else
+    {
+        g_headerBuffer[g_headerIndex++] = 0;
+    }
+    g_headerBuffer[g_headerIndex++] = '|';
+
+    if (pdu->transport_hdr)
+    {
+        g_headerBuffer[g_headerIndex++] = (pdu->transport_hdr->udp.id >> 8) & 0x0000ff;
+        g_headerBuffer[g_headerIndex++] = pdu->transport_hdr->udp.id & 0x000000ff;
+    }
+    else
+    {
+        g_headerBuffer[g_headerIndex++] = 0;
+        g_headerBuffer[g_headerIndex++] = 0;
+    }
+    g_headerBuffer[g_headerIndex++] = '|';
+
+    if (info->token && info->tokenLength > 0)
+    {
+        for (size_t i = 0; i < info->tokenLength; i++)
+        {
+            g_headerBuffer[g_headerIndex++] = info->token[i];
+        }
+        g_headerBuffer[g_headerIndex++] = '|';
+    }
+
+    if (info->resourceUri)
+    {
+        size_t i = 0;
+        while (NULL != info->resourceUri[i])
+        {
+            g_headerBuffer[g_headerIndex++] = info->resourceUri[i];
+            i++;
+        }
+        g_headerBuffer[g_headerIndex++] = '|';
+    }
+
+    OIC_LOG_CA_BUFFER(INFO, TAG, (uint8_t *) g_headerBuffer, g_headerIndex, 1);
+    size_t payloadLen = (unsigned char *) pdu->hdr + pdu->length - pdu->data;
+    OIC_LOG_CA_BUFFER(INFO_PRIVATE, TAG, pdu->data, payloadLen, 0);
+}
+#endif
+
+#else
+static void CALogPDUInfo(const CAData_t *data, const coap_pdu_t *pdu)
+{
+    VERIFY_NON_NULL_VOID(pdu, TAG, "pdu");
+    (void)data;
+
+    OIC_LOG_V(DEBUG, TAG, "PDU Maker - payload : %s", pdu->data);
+    OIC_LOG_V(DEBUG, TAG, "PDU Maker - type : %d", pdu->transport_hdr->udp.type);
+    OIC_LOG_V(DEBUG, TAG, "PDU Maker - code : %d", pdu->transport_hdr->udp.code);
+    OIC_LOG(DEBUG, TAG, "PDU Maker - token :");
+    OIC_LOG_BUFFER(DEBUG, TAG, pdu->transport_hdr->udp.token,
+                   pdu->transport_hdr->udp.token_length);
+}
+#endif
index 1db90e8..9f822e4 100644 (file)
@@ -71,11 +71,9 @@ CAResult_t CAAddNetworkType(CATransportAdapter_t transportType)
     {
         case CA_ADAPTER_IP:
 #ifndef IP_ADAPTER
-            OIC_LOG(DEBUG, TAG, "Add network type(IP) - Not Supported");
             return CA_NOT_SUPPORTED;
 #else
 
-            OIC_LOG(DEBUG, TAG, "Add network type(IP)");
             if (u_arraylist_contains(g_selectedNetworkList, &NETWORK_IP))
             {
                 goto exit;
@@ -87,11 +85,9 @@ CAResult_t CAAddNetworkType(CATransportAdapter_t transportType)
 
         case CA_ADAPTER_RFCOMM_BTEDR:
 #ifndef EDR_ADAPTER
-            OIC_LOG(DEBUG, TAG, "Add network type(EDR) - Not Supported");
             return CA_NOT_SUPPORTED;
 #else
 
-            OIC_LOG(DEBUG, TAG, "Add network type(EDR)");
             if (u_arraylist_contains(g_selectedNetworkList, &NETWORK_RFCOMM))
             {
                 goto exit;
@@ -103,11 +99,9 @@ CAResult_t CAAddNetworkType(CATransportAdapter_t transportType)
 
         case CA_ADAPTER_GATT_BTLE:
 #ifndef LE_ADAPTER
-            OIC_LOG(DEBUG, TAG, "Add network type(LE) - Not Supported");
             return CA_NOT_SUPPORTED;
 #else
 
-            OIC_LOG(DEBUG, TAG, "Add network type(LE)");
             if (u_arraylist_contains(g_selectedNetworkList, &NETWORK_GATT))
             {
                 goto exit;
@@ -120,7 +114,6 @@ CAResult_t CAAddNetworkType(CATransportAdapter_t transportType)
 #ifdef RA_ADAPTER
         case CA_ADAPTER_REMOTE_ACCESS:
 
-           OIC_LOG(DEBUG, TAG, "Add network type(RA)");
            if (u_arraylist_contains(g_selectedNetworkList, &NETWORK_RA))
            {
                goto exit;
@@ -132,7 +125,6 @@ CAResult_t CAAddNetworkType(CATransportAdapter_t transportType)
 #ifdef TCP_ADAPTER
         case CA_ADAPTER_TCP:
 
-           OIC_LOG(DEBUG, TAG, "Add network type(TCP)");
            if (u_arraylist_contains(g_selectedNetworkList, &NETWORK_TCP))
            {
                goto exit;
@@ -144,11 +136,9 @@ CAResult_t CAAddNetworkType(CATransportAdapter_t transportType)
 
         case CA_ADAPTER_NFC:
  #ifndef NFC_ADAPTER
-            OIC_LOG(DEBUG, TAG, "Add network type(NFC) - Not Supported");
             return CA_NOT_SUPPORTED;
 
 #else
-           OIC_LOG(DEBUG, TAG, "Add network type(NFC)");
            if (u_arraylist_contains(g_selectedNetworkList, &NETWORK_NFC))
            {
                goto exit;
old mode 100644 (file)
new mode 100755 (executable)
index 6f37b7a..4f2f4a0
@@ -247,6 +247,8 @@ coap_pdu_t *CAParsePDU(const char *data, uint32_t length, uint32_t *outCode,
     return outpdu;
 
 exit:
+    OIC_LOG(DEBUG, TAG, "data :");
+    OIC_LOG_BUFFER(DEBUG, TAG, (const uint8_t*) data, length);
     coap_delete_pdu(outpdu);
     return NULL;
 }
@@ -459,12 +461,14 @@ CAResult_t CAParseUriPartial(const unsigned char *str, size_t length, int target
     {
         unsigned char uriBuffer[CA_MAX_URI_LENGTH] = { 0 };
         unsigned char *pBuf = uriBuffer;
-        size_t buflen = sizeof(uriBuffer);
-        int res = (target == COAP_OPTION_URI_PATH) ? coap_split_path(str, length, pBuf, &buflen) :
-                                                     coap_split_query(str, length, pBuf, &buflen);
+        size_t unusedBufferSize = sizeof(uriBuffer);
+        int res = (target == COAP_OPTION_URI_PATH) ? coap_split_path(str, length, pBuf, &unusedBufferSize) :
+                                                     coap_split_query(str, length, pBuf, &unusedBufferSize);
 
         if (res > 0)
         {
+            assert(unusedBufferSize < sizeof(uriBuffer));
+            size_t usedBufferSize = sizeof(uriBuffer) - unusedBufferSize;
             size_t prevIdx = 0;
             while (res--)
             {
@@ -478,11 +482,13 @@ CAResult_t CAParseUriPartial(const unsigned char *str, size_t length, int target
                 }
 
                 size_t optSize = COAP_OPT_SIZE(pBuf);
-                if ((prevIdx + optSize) < buflen)
+                if (prevIdx + optSize > usedBufferSize)
                 {
-                    pBuf += optSize;
-                    prevIdx += optSize;
+                    assert(false);
+                    return CA_STATUS_INVALID_PARAM;
                 }
+                pBuf += optSize;
+                prevIdx += optSize;
             }
         }
         else
@@ -528,9 +534,7 @@ CAResult_t CAParseHeadOption(uint32_t code, const CAInfo_t *info, coap_list_t **
         }
         else
         {
-            OIC_LOG_V(DEBUG, TAG, "Head opt ID: %d", id);
-            OIC_LOG_V(DEBUG, TAG, "Head opt data: %s", (info->options + i)->optionData);
-            OIC_LOG_V(DEBUG, TAG, "Head opt length: %d", (info->options + i)->optionLength);
+            OIC_LOG_V(DEBUG, TAG, "Head opt ID[%d], length[%d]", id, (info->options + i)->optionLength);
             int ret = coap_insert(optlist,
                                   CACreateNewOptionNode(id, (info->options + i)->optionLength,
                                                         (info->options + i)->optionData),
@@ -1011,7 +1015,7 @@ CAResult_t CAGetTokenFromPDU(const coap_hdr_transport_t *pdu_hdr,
     coap_get_token2(pdu_hdr, transport, &token, &token_length);
 
     // set token data
-    if (token_length > 0)
+    if (token && token_length > 0)
     {
         OIC_LOG_V(DEBUG, TAG, "token len:%d", token_length);
         outInfo->token = (char *) OICMalloc(token_length);
@@ -1176,6 +1180,7 @@ bool CAIsSupportedBlockwiseTransfer(CATransportAdapter_t adapter)
     {
         return true;
     }
+    OIC_LOG_V(DEBUG, TAG, "adapter value of BWT is %d", adapter);
     return false;
 }
 #endif
@@ -1188,6 +1193,7 @@ bool CAIsSupportedCoAPOverTCP(CATransportAdapter_t adapter)
     {
         return true;
     }
+    OIC_LOG_V(DEBUG, TAG, "adapter value of CoAP/TCP is %d", adapter);
     return false;
 }
 #endif
index 1542098..0eb1f3c 100644 (file)
  *
  ******************************************************************/
 
+#ifdef __TIZENRT__
+#include <tinyara/config.h>
+#endif
+
 #include "iotivity_config.h"
 #include <stdio.h>
 #include <stdlib.h>
@@ -30,6 +34,7 @@
 #endif
 
 #include "caqueueingthread.h"
+#include "camessagehandler.h"
 #include "oic_malloc.h"
 #include "logger.h"
 
@@ -50,7 +55,7 @@ static void CAQueueingThreadBaseRoutine(void *threadValue)
     while (!thread->isStop)
     {
         // mutex lock
-        ca_mutex_lock(thread->threadMutex);
+        oc_mutex_lock(thread->threadMutex);
 
         // if queue is empty, thread will wait
         if (!thread->isStop && u_queue_get_size(thread->dataQueue) <= 0)
@@ -58,7 +63,7 @@ static void CAQueueingThreadBaseRoutine(void *threadValue)
             OIC_LOG(DEBUG, TAG, "wait..");
 
             // wait
-            ca_cond_wait(thread->threadCond, thread->threadMutex);
+            oc_cond_wait(thread->threadCond, thread->threadMutex);
 
             OIC_LOG(DEBUG, TAG, "wake up..");
         }
@@ -67,14 +72,14 @@ static void CAQueueingThreadBaseRoutine(void *threadValue)
         if (thread->isStop)
         {
             // mutex unlock
-            ca_mutex_unlock(thread->threadMutex);
+            oc_mutex_unlock(thread->threadMutex);
             continue;
         }
 
         // get data
         u_queue_message_t *message = u_queue_get_element(thread->dataQueue);
         // mutex unlock
-        ca_mutex_unlock(thread->threadMutex);
+        oc_mutex_unlock(thread->threadMutex);
         if (NULL == message)
         {
             continue;
@@ -96,9 +101,9 @@ static void CAQueueingThreadBaseRoutine(void *threadValue)
         OICFree(message);
     }
 
-    ca_mutex_lock(thread->threadMutex);
-    ca_cond_signal(thread->threadCond);
-    ca_mutex_unlock(thread->threadMutex);
+    oc_mutex_lock(thread->threadMutex);
+    oc_cond_signal(thread->threadCond);
+    oc_mutex_unlock(thread->threadMutex);
 
     OIC_LOG(DEBUG, TAG, "message handler main thread end..");
 }
@@ -123,8 +128,8 @@ CAResult_t CAQueueingThreadInitialize(CAQueueingThread_t *thread, ca_thread_pool
     // set send thread data
     thread->threadPool = handle;
     thread->dataQueue = u_queue_create();
-    thread->threadMutex = ca_mutex_new();
-    thread->threadCond = ca_cond_new();
+    thread->threadMutex = oc_mutex_new();
+    thread->threadCond = oc_cond_new();
     thread->isStop = true;
     thread->threadTask = task;
     thread->destroy = destroy;
@@ -143,18 +148,21 @@ ERROR_MEM_FAILURE:
     }
     if (thread->threadMutex)
     {
-        ca_mutex_free(thread->threadMutex);
+        oc_mutex_free(thread->threadMutex);
         thread->threadMutex = NULL;
     }
     if (thread->threadCond)
     {
-        ca_cond_free(thread->threadCond);
+        oc_cond_free(thread->threadCond);
         thread->threadCond = NULL;
     }
     return CA_MEMORY_ALLOC_FAILED;
 }
-
+#ifndef __TIZENRT__
 CAResult_t CAQueueingThreadStart(CAQueueingThread_t *thread)
+#else
+CAResult_t CAQueueingThreadStart(CAQueueingThread_t *thread, const char *thread_name)
+#endif
 {
     if (NULL == thread)
     {
@@ -175,15 +183,25 @@ CAResult_t CAQueueingThreadStart(CAQueueingThread_t *thread)
     }
 
     // mutex lock
-    ca_mutex_lock(thread->threadMutex);
+    oc_mutex_lock(thread->threadMutex);
     thread->isStop = false;
     // mutex unlock
-    ca_mutex_unlock(thread->threadMutex);
-
+    oc_mutex_unlock(thread->threadMutex);
+#ifndef __TIZENRT__
     CAResult_t res = ca_thread_pool_add_task(thread->threadPool, CAQueueingThreadBaseRoutine,
-                                            thread);
+                                             thread, NULL);
+#else
+    CAResult_t res = ca_thread_pool_add_task(thread->threadPool, CAQueueingThreadBaseRoutine,
+                                             thread, NULL, thread_name,
+                                             CONFIG_IOTIVITY_QUEING_PTHREAD_STACKSIZE);
+#endif
     if (res != CA_STATUS_OK)
     {
+        // update thread status.
+        oc_mutex_lock(thread->threadMutex);
+        thread->isStop = true;
+        oc_mutex_unlock(thread->threadMutex);
+
         OIC_LOG(ERROR, TAG, "thread pool add task error(send thread).");
     }
 
@@ -201,7 +219,6 @@ CAResult_t CAQueueingThreadAddData(CAQueueingThread_t *thread, void *data, uint3
     if (NULL == data || 0 == size)
     {
         OIC_LOG(ERROR, TAG, "data is empty..");
-
         return CA_STATUS_INVALID_PARAM;
     }
 
@@ -218,16 +235,92 @@ CAResult_t CAQueueingThreadAddData(CAQueueingThread_t *thread, void *data, uint3
     message->size = size;
 
     // mutex lock
-    ca_mutex_lock(thread->threadMutex);
+    oc_mutex_lock(thread->threadMutex);
 
     // add thread data into list
     u_queue_add_element(thread->dataQueue, message);
 
     // notity the thread
-    ca_cond_signal(thread->threadCond);
+    oc_cond_signal(thread->threadCond);
 
     // mutex unlock
-    ca_mutex_unlock(thread->threadMutex);
+    oc_mutex_unlock(thread->threadMutex);
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAQueueingThreadClearData(CAQueueingThread_t *thread)
+{
+    if (NULL == thread)
+    {
+        OIC_LOG(ERROR, TAG, "thread instance is empty..");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    OIC_LOG(DEBUG, TAG, "clear queue data..");
+
+    // mutex lock
+    oc_mutex_lock(thread->threadMutex);
+
+    // remove all remained list data.
+    while (u_queue_get_size(thread->dataQueue) > 0)
+    {
+        // get data
+        u_queue_message_t *message = u_queue_get_element(thread->dataQueue);
+
+        // free
+        if (NULL != message)
+        {
+            if (NULL != thread->destroy)
+            {
+                thread->destroy(message->msg, message->size);
+            }
+            else
+            {
+                OICFree(message->msg);
+            }
+
+            OICFree(message);
+        }
+    }
+
+    // mutex unlock
+    oc_mutex_unlock(thread->threadMutex);
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAQueueingThreadClearContextData(CAQueueingThread_t *thread,
+                                            CAContextDataDestroy callback, void *ctx)
+{
+    if (NULL == thread)
+    {
+        OIC_LOG(ERROR, TAG, "thread instance is empty..");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    if (NULL == callback)
+    {
+        OIC_LOG(ERROR, TAG, "callback is NULL..");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    if (NULL == ctx)
+    {
+        OIC_LOG(ERROR, TAG, "ctx is NULL..");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    OIC_LOG(DEBUG, TAG, "Clear thread data according to context");
+
+    // mutex lock
+    oc_mutex_lock(thread->threadMutex);
+
+    // remove adapter related list data.
+    u_queue_remove_req_elements(thread->dataQueue, callback, ctx, thread->destroy);
+
+    // mutex unlock
+    oc_mutex_unlock(thread->threadMutex);
 
     return CA_STATUS_OK;
 }
@@ -242,9 +335,8 @@ CAResult_t CAQueueingThreadDestroy(CAQueueingThread_t *thread)
 
     OIC_LOG(DEBUG, TAG, "thread destroy..");
 
-    ca_mutex_free(thread->threadMutex);
-    thread->threadMutex = NULL;
-    ca_cond_free(thread->threadCond);
+    // mutex lock
+    oc_mutex_lock(thread->threadMutex);
 
     // remove all remained list data.
     while (u_queue_get_size(thread->dataQueue) > 0)
@@ -268,6 +360,13 @@ CAResult_t CAQueueingThreadDestroy(CAQueueingThread_t *thread)
         }
     }
 
+    // mutex unlock
+    oc_mutex_unlock(thread->threadMutex);
+
+    oc_mutex_free(thread->threadMutex);
+    thread->threadMutex = NULL;
+    oc_cond_free(thread->threadCond);
+
     u_queue_delete(thread->dataQueue);
     thread->dataQueue = NULL;
 
@@ -287,18 +386,18 @@ CAResult_t CAQueueingThreadStop(CAQueueingThread_t *thread)
     if (!thread->isStop)
     {
         // mutex lock
-        ca_mutex_lock(thread->threadMutex);
+        oc_mutex_lock(thread->threadMutex);
 
         // set stop flag
         thread->isStop = true;
 
         // notify the thread
-        ca_cond_signal(thread->threadCond);
+        oc_cond_signal(thread->threadCond);
 
-        ca_cond_wait(thread->threadCond, thread->threadMutex);
+        oc_cond_wait(thread->threadCond, thread->threadMutex);
 
         // mutex unlock
-        ca_mutex_unlock(thread->threadMutex);
+        oc_mutex_unlock(thread->threadMutex);
     }
 
     return CA_STATUS_OK;
index 65d32c7..611ee5d 100644 (file)
 #define _POSIX_C_SOURCE 200809L
 #endif
 
+#ifdef __TIZENRT__
+#include <tinyara/config.h>
+#endif
+
 #include "iotivity_config.h"
 #include <stdio.h>
 #include <stdlib.h>
@@ -105,8 +109,8 @@ static const uint64_t MSECS_PER_SEC = 1000;
  */
 static uint64_t CAGetTimeoutValue()
 {
-    return ((DEFAULT_ACK_TIMEOUT_SEC * 1000) + ((1000 * OCGetRandomByte()) >> 8)) *
-            (uint64_t) 1000;
+    return ((DEFAULT_ACK_TIMEOUT_SEC * MSECS_PER_SEC)
+            + ((MSECS_PER_SEC * OCGetRandomByte()) >> 8)) * MSECS_PER_SEC;
 }
 
 CAResult_t CARetransmissionStart(CARetransmission_t *context)
@@ -122,10 +126,14 @@ CAResult_t CARetransmissionStart(CARetransmission_t *context)
         OIC_LOG(ERROR, TAG, "thread pool handle is empty..");
         return CA_STATUS_INVALID_PARAM;
     }
-
+#ifndef __TIZENRT__
     CAResult_t res = ca_thread_pool_add_task(context->threadPool, CARetransmissionBaseRoutine,
-                                             context);
-
+                                             context, NULL);
+#else
+    CAResult_t res = ca_thread_pool_add_task(context->threadPool, CARetransmissionBaseRoutine,
+                                             context, NULL, "IoT_Retransmit",
+                                             CONFIG_IOTIVITY_RETRANSMIT_PTHREAD_STACKSIZE);
+#endif
     if (CA_STATUS_OK != res)
     {
         OIC_LOG(ERROR, TAG, "thread pool add task error(send thread).");
@@ -147,17 +155,19 @@ static bool CACheckTimeout(uint64_t currentTime, CARetransmissionData_t *retData
 #ifndef SINGLE_THREAD
     // #1. calculate timeout
     uint32_t milliTimeoutValue = retData->timeout * 0.001;
-    uint64_t timeout = (milliTimeoutValue << retData->triedCount) * (uint64_t) 1000;
+    uint64_t timeout = ((uint64_t) milliTimeoutValue << retData->triedCount) * MSECS_PER_SEC;
 
     if (currentTime >= retData->timeStamp + timeout)
     {
+#ifndef __TIZENRT__
         OIC_LOG_V(DEBUG, TAG, "%" PRIu64 " microseconds time out!!, tried count(%d)",
                   timeout, retData->triedCount);
+#endif
         return true;
     }
 #else
     // #1. calculate timeout
-    uint64_t timeOut = (2 << retData->triedCount) * (uint64_t) 1000000;
+    uint64_t timeOut = (2 << retData->triedCount) * USECS_PER_SEC;
 
     if (currentTime >= retData->timeStamp + timeOut)
     {
@@ -178,7 +188,7 @@ static void CACheckRetransmissionList(CARetransmission_t *context)
     }
 
     // mutex lock
-    ca_mutex_lock(context->threadMutex);
+    oc_mutex_lock(context->threadMutex);
 
     uint32_t i = 0;
     uint32_t len = u_arraylist_length(context->dataList);
@@ -218,7 +228,7 @@ static void CACheckRetransmissionList(CARetransmission_t *context)
             {
                 OIC_LOG(ERROR, TAG, "Removed data is NULL");
                 // mutex unlock
-                ca_mutex_unlock(context->threadMutex);
+                oc_mutex_unlock(context->threadMutex);
                 return;
             }
             OIC_LOG_V(DEBUG, TAG, "max trying count, remove RTCON data,"
@@ -243,7 +253,7 @@ static void CACheckRetransmissionList(CARetransmission_t *context)
     }
 
     // mutex unlock
-    ca_mutex_unlock(context->threadMutex);
+    oc_mutex_unlock(context->threadMutex);
 }
 
 void CARetransmissionBaseRoutine(void *threadValue)
@@ -271,7 +281,7 @@ void CARetransmissionBaseRoutine(void *threadValue)
     while (!context->isStop)
     {
         // mutex lock
-        ca_mutex_lock(context->threadMutex);
+        oc_mutex_lock(context->threadMutex);
 
         if (!context->isStop && u_arraylist_length(context->dataList) <= 0)
         {
@@ -279,19 +289,21 @@ void CARetransmissionBaseRoutine(void *threadValue)
             OIC_LOG(DEBUG, TAG, "wait..there is no retransmission data.");
 
             // wait
-            ca_cond_wait(context->threadCond, context->threadMutex);
+            oc_cond_wait(context->threadCond, context->threadMutex);
 
             OIC_LOG(DEBUG, TAG, "wake up..");
         }
         else if (!context->isStop)
         {
             // check each RETRANSMISSION_CHECK_PERIOD_SEC time.
+#ifndef __TIZENRT__
             OIC_LOG_V(DEBUG, TAG, "wait..(%" PRIu64 ")microseconds",
                       RETRANSMISSION_CHECK_PERIOD_SEC * (uint64_t) USECS_PER_SEC);
+#endif
 
             // wait
             uint64_t absTime = RETRANSMISSION_CHECK_PERIOD_SEC * (uint64_t) USECS_PER_SEC;
-            ca_cond_wait_for(context->threadCond, context->threadMutex, absTime );
+            oc_cond_wait_for(context->threadCond, context->threadMutex, absTime );
         }
         else
         {
@@ -299,7 +311,7 @@ void CARetransmissionBaseRoutine(void *threadValue)
         }
 
         // mutex unlock
-        ca_mutex_unlock(context->threadMutex);
+        oc_mutex_unlock(context->threadMutex);
 
         // check stop flag
         if (context->isStop)
@@ -310,9 +322,9 @@ void CARetransmissionBaseRoutine(void *threadValue)
         CACheckRetransmissionList(context);
     }
 
-    ca_mutex_lock(context->threadMutex);
-    ca_cond_signal(context->threadCond);
-    ca_mutex_unlock(context->threadMutex);
+    oc_mutex_lock(context->threadMutex);
+    oc_cond_signal(context->threadCond);
+    oc_mutex_unlock(context->threadMutex);
 
 #endif
     OIC_LOG(DEBUG, TAG, "retransmission main thread end");
@@ -351,8 +363,8 @@ CAResult_t CARetransmissionInitialize(CARetransmission_t *context,
 
     // set send thread data
     context->threadPool = handle;
-    context->threadMutex = ca_mutex_new();
-    context->threadCond = ca_cond_new();
+    context->threadMutex = oc_mutex_new();
+    context->threadCond = oc_cond_new();
     context->dataSendMethod = retransmissionSendMethod;
     context->timeoutCallback = timeoutCallback;
     context->config = cfg;
@@ -435,7 +447,7 @@ CAResult_t CARetransmissionSentData(CARetransmission_t *context,
     retData->dataType = dataType;
 #ifndef SINGLE_THREAD
     // mutex lock
-    ca_mutex_lock(context->threadMutex);
+    oc_mutex_lock(context->threadMutex);
 
     uint32_t i = 0;
     uint32_t len = u_arraylist_length(context->dataList);
@@ -457,7 +469,7 @@ CAResult_t CARetransmissionSentData(CARetransmission_t *context,
             OIC_LOG(ERROR, TAG, "Duplicate message ID");
 
             // mutex unlock
-            ca_mutex_unlock(context->threadMutex);
+            oc_mutex_unlock(context->threadMutex);
 
             OICFree(retData);
             OICFree(pduData);
@@ -466,16 +478,38 @@ CAResult_t CARetransmissionSentData(CARetransmission_t *context,
         }
     }
 
-    u_arraylist_add(context->dataList, (void *) retData);
+    bool res = u_arraylist_add(context->dataList, (void *) retData);
+    if (!res)
+    {
+        OIC_LOG(ERROR, TAG, "u_arraylist_add failed.");
+
+        oc_mutex_unlock(context->threadMutex);
+
+        OICFree(retData);
+        OICFree(pduData);
+        OICFree(remoteEndpoint);
+        return CA_MEMORY_ALLOC_FAILED;
+    }
 
     // notify the thread
-    ca_cond_signal(context->threadCond);
+    oc_cond_signal(context->threadCond);
 
     // mutex unlock
-    ca_mutex_unlock(context->threadMutex);
+    oc_mutex_unlock(context->threadMutex);
 
 #else
-    u_arraylist_add(context->dataList, (void *) retData);
+    bool res = u_arraylist_add(context->dataList, (void *) retData);
+    if (!res)
+    {
+        OIC_LOG(ERROR, TAG, "u_arraylist_add failed.");
+
+        oc_mutex_unlock(context->threadMutex);
+
+        OICFree(retData);
+        OICFree(pduData);
+        OICFree(remoteEndpoint);
+        return CA_MEMORY_ALLOC_FAILED;
+    }
 
     CACheckRetransmissionList(context);
 #endif
@@ -516,7 +550,7 @@ CAResult_t CARetransmissionReceivedData(CARetransmission_t *context,
     }
 
     // mutex lock
-    ca_mutex_lock(context->threadMutex);
+    oc_mutex_lock(context->threadMutex);
     uint32_t len = u_arraylist_length(context->dataList);
 
     // find index
@@ -546,7 +580,7 @@ CAResult_t CARetransmissionReceivedData(CARetransmission_t *context,
                     OIC_LOG(ERROR, TAG, "retData->pdu is null");
                     OICFree(retData);
                     // mutex unlock
-                    ca_mutex_unlock(context->threadMutex);
+                    oc_mutex_unlock(context->threadMutex);
 
                     return CA_STATUS_FAILED;
                 }
@@ -559,7 +593,7 @@ CAResult_t CARetransmissionReceivedData(CARetransmission_t *context,
                     OIC_LOG(ERROR, TAG, "memory error");
 
                     // mutex unlock
-                    ca_mutex_unlock(context->threadMutex);
+                    oc_mutex_unlock(context->threadMutex);
 
                     return CA_MEMORY_ALLOC_FAILED;
                 }
@@ -573,7 +607,7 @@ CAResult_t CARetransmissionReceivedData(CARetransmission_t *context,
                 OIC_LOG(ERROR, TAG, "Removed data is NULL");
 
                 // mutex unlock
-                ca_mutex_unlock(context->threadMutex);
+                oc_mutex_unlock(context->threadMutex);
 
                 return CA_STATUS_FAILED;
             }
@@ -589,12 +623,51 @@ CAResult_t CARetransmissionReceivedData(CARetransmission_t *context,
     }
 
     // mutex unlock
-    ca_mutex_unlock(context->threadMutex);
+    oc_mutex_unlock(context->threadMutex);
 
     OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
 
+CAResult_t CARetransmissionClearAdapterData(CARetransmission_t *context, CATransportAdapter_t type)
+{
+    if (NULL == context)
+    {
+        OIC_LOG(ERROR, TAG, "thread instance is empty..");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "clear queue data for Adapter : %d ", type);
+
+    // mutex lock
+    oc_mutex_lock(context->threadMutex);
+
+    uint32_t len = u_arraylist_length(context->dataList);
+
+    // find index
+    uint32_t i;
+    for (i = 0; i < len; i++)
+    {
+        // get data
+        CARetransmissionData_t *removedData = (CARetransmissionData_t *) u_arraylist_get(
+            context->dataList, i);
+
+        // free
+        if (NULL != removedData && NULL != removedData->endpoint &&
+                removedData->endpoint->adapter == type)
+        {
+            CAFreeEndpoint(removedData->endpoint);
+            OICFree(removedData->pdu);
+            OICFree(removedData);
+        }
+    }
+
+    // mutex unlock
+    oc_mutex_unlock(context->threadMutex);
+
+    return CA_STATUS_OK;
+}
+
 CAResult_t CARetransmissionStop(CARetransmission_t *context)
 {
     if (NULL == context)
@@ -606,18 +679,18 @@ CAResult_t CARetransmissionStop(CARetransmission_t *context)
     OIC_LOG(DEBUG, TAG, "retransmission stop request!!");
 
     // mutex lock
-    ca_mutex_lock(context->threadMutex);
+    oc_mutex_lock(context->threadMutex);
 
     // set stop flag
     context->isStop = true;
 
     // notify the thread
-    ca_cond_signal(context->threadCond);
+    oc_cond_signal(context->threadCond);
 
-    ca_cond_wait(context->threadCond, context->threadMutex);
+    oc_cond_wait(context->threadCond, context->threadMutex);
 
     // mutex unlock
-    ca_mutex_unlock(context->threadMutex);
+    oc_mutex_unlock(context->threadMutex);
 
     return CA_STATUS_OK;
 }
@@ -632,22 +705,9 @@ CAResult_t CARetransmissionDestroy(CARetransmission_t *context)
 
     OIC_LOG(DEBUG, TAG, "retransmission context destroy..");
 
-    ca_mutex_lock(context->threadMutex);
-    uint32_t len = u_arraylist_length(context->dataList);
-    for (uint32_t i = 0; i < len; i++)
-    {
-        CARetransmissionData_t *data = u_arraylist_get(context->dataList, i);
-        if (NULL == data)
-        {
-            continue;
-        }
-        CAFreeEndpoint(data->endpoint);
-        OICFree(data->pdu);
-    }
-    ca_mutex_unlock(context->threadMutex);
-    ca_mutex_free(context->threadMutex);
+    oc_mutex_free(context->threadMutex);
     context->threadMutex = NULL;
-    ca_cond_free(context->threadCond);
+    oc_cond_free(context->threadCond);
     u_arraylist_free(&context->dataList);
 
     return CA_STATUS_OK;
index 8706ecf..8cb1cbb 100644 (file)
@@ -44,10 +44,13 @@ if os.path.exists(target_sconscript_abspath):
 target_files = [ os.path.join(src_dir, target_os, f) for f in target_files ]
 
 # Source files to build for Linux-like platforms
-if target_os in ['linux','darwin','ios']:
+if target_os in ['linux','darwin','tizenrt']:
     target_files += [ os.path.join(src_dir,
                                    'linux/caipnwmonitor.c') ]
 
+if target_os in ['ios']:
+    target_files += [ os.path.join(src_dir, 'ios/caipnwmonitor.m') ]
+
 if target_os in ['msys_nt']:
        target_files += [ os.path.join(src_dir, 'windows/caipnwmonitor.c') ]
 
index 72750e3..a64cfd4 100644 (file)
@@ -1,22 +1,22 @@
-/******************************************************************
-*
-* Copyright 2016 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.
-*
-******************************************************************/
+/* *****************************************************************
+ *
+ * Copyright 2016 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 "caifaddrs.h"
 #include "oic_malloc.h"
@@ -34,7 +34,7 @@
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
 #include "logger.h"
-#define TAG "OIC_CA_ifaddrs"
+#define TAG "OIC_CA_IFADDRS"
 #define VERIFY_NON_NULL(arg) { if (!arg) {OIC_LOG(ERROR, TAG, #arg " is NULL"); goto exit;} }
 
 #define NETLINK_MESSAGE_LENGTH  (4096)
@@ -195,7 +195,6 @@ CAResult_t CAGetIfaddrsUsingNetlink(struct ifaddrs **ifap)
                     goto exit;
 
                 case RTM_NEWADDR:
-                    OIC_LOG(DEBUG, TAG, "RTM_NEWADDR");
                     node = CAParsingAddr(recvMsg);
                     state = CA_MEMORY_ALLOC_FAILED;
                     VERIFY_NON_NULL(node);
index b728119..a576af6 100644 (file)
@@ -1,22 +1,22 @@
-/******************************************************************
-*
-* Copyright 2016 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.
-*
-******************************************************************/
+/* *****************************************************************
+ *
+ * Copyright 2016 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 "cacommon.h"
 
 /**
index 6f92929..3df9ca6 100644 (file)
@@ -31,7 +31,7 @@
 #ifdef __WITH_DTLS__
 #include "ca_adapter_net_ssl.h"
 #endif
-#include "camutex.h"
+#include "octhread.h"
 #include "uarraylist.h"
 #include "caremotehandler.h"
 #include "logger.h"
@@ -76,8 +76,8 @@ static CAAdapterChangeCallback g_networkChangeCallback = NULL;
  */
 static CAErrorHandleCallback g_errorCallback = NULL;
 
-static void CAIPPacketReceivedCB(const CASecureEndpoint_t *endpoint,
-                                 const void *data, size_t dataLength);
+static CAResult_t CAIPPacketReceivedCB(const CASecureEndpoint_t *endpoint,
+                                       const void *data, size_t dataLength);
 #ifdef __WITH_DTLS__
 static ssize_t CAIPPacketSendCB(CAEndpoint_t *endpoint,
                                 const void *data, size_t dataLength);
@@ -148,6 +148,22 @@ void CAIPAdapterHandler(CATransportAdapter_t adapter, CANetworkStatus_t status)
     {
         OIC_LOG(ERROR, TAG, "g_networkChangeCallback is NULL");
     }
+
+    if (CA_INTERFACE_DOWN == status)
+    {
+        OIC_LOG(DEBUG, TAG, "Network status for IP is down");
+
+        CAResult_t res = CAQueueingThreadClearData(g_sendQueueHandle);
+        if (res != CA_STATUS_OK)
+        {
+            OIC_LOG_V(ERROR, TAG, "CAQueueingThreadClearData failed[%d]", res);
+        }
+
+#ifdef __WITH_DTLS__
+        OIC_LOG(DEBUG, TAG, "close all ssl session");
+        CAcloseSslConnectionAll(CA_ADAPTER_IP);
+#endif
+    }
 }
 
 #ifdef __WITH_DTLS__
@@ -162,18 +178,24 @@ static ssize_t CAIPPacketSendCB(CAEndpoint_t *endpoint, const void *data, size_t
 #endif
 
 
-void CAIPPacketReceivedCB(const CASecureEndpoint_t *sep, const void *data,
-                          size_t dataLength)
+CAResult_t CAIPPacketReceivedCB(const CASecureEndpoint_t *sep, const void *data,
+                                size_t dataLength)
 {
-    VERIFY_NON_NULL_VOID(sep, TAG, "sep is NULL");
-    VERIFY_NON_NULL_VOID(data, TAG, "data is NULL");
+    VERIFY_NON_NULL(sep, TAG, "sep is NULL");
+    VERIFY_NON_NULL(data, TAG, "data is NULL");
 
     OIC_LOG_V(DEBUG, TAG, "Address: %s, port:%d", sep->endpoint.addr, sep->endpoint.port);
 
+    CAResult_t res = CA_STATUS_OK;
     if (g_networkPacketCallback)
     {
-        g_networkPacketCallback(sep, data, dataLength);
+        res = g_networkPacketCallback(sep, data, dataLength);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "Error parsing CoAP data");
+        }
     }
+    return res;
 }
 
 void CAIPErrorHandler(const CAEndpoint_t *endpoint, const void *data,
@@ -216,7 +238,10 @@ static void CAInitializeIPGlobals()
     {
         flags |= caglobals.serverFlags;
     }
+//TODO Enable once TizenRT supports IPv6
+#ifndef __TIZENRT__
     caglobals.ip.ipv6enabled = flags & CA_IPV6;
+#endif
     caglobals.ip.ipv4enabled = flags & CA_IPV4;
     caglobals.ip.dualstack = caglobals.ip.ipv6enabled && caglobals.ip.ipv4enabled;
 }
@@ -245,14 +270,7 @@ CAResult_t CAInitializeIP(CARegisterConnectivityCallback registerCallback,
     CAIPSetPacketReceiveCallback(CAIPPacketReceivedCB);
 
 #ifdef __WITH_DTLS__
-    if (CA_STATUS_OK != CAinitSslAdapter())
-    {
-        OIC_LOG(ERROR, TAG, "Failed to init SSL adapter");
-    }
-    else
-    {
-        CAsetSslAdapterCallbacks(CAIPPacketReceivedCB, CAIPPacketSendCB, CA_ADAPTER_IP);
-    }
+    CAsetSslAdapterCallbacks(CAIPPacketReceivedCB, CAIPPacketSendCB, CA_ADAPTER_IP);
 #endif
 
     static const CAConnectivityHandler_t ipHandler =
@@ -302,7 +320,11 @@ CAResult_t CAStartIP()
     }
 
     // Start send queue thread
+#ifndef __TIZENRT__
     if (CA_STATUS_OK != CAQueueingThreadStart(g_sendQueueHandle))
+#else
+    if (CA_STATUS_OK != CAQueueingThreadStart(g_sendQueueHandle, "IoT_IPSendQueue"))
+#endif
     {
         OIC_LOG(ERROR, TAG, "Failed to Start Send Data Thread");
         return CA_STATUS_FAILED;
@@ -406,10 +428,6 @@ CAResult_t CAReadIPData()
 
 CAResult_t CAStopIP()
 {
-#ifdef __WITH_DTLS__
-    CAdeinitSslAdapter();
-#endif
-
 #ifndef SINGLE_THREAD
     if (g_sendQueueHandle && g_sendQueueHandle->threadMutex)
     {
@@ -434,7 +452,6 @@ void CATerminateIP()
     CAIPSetPacketReceiveCallback(NULL);
 
 #ifndef SINGLE_THREAD
-    CADeInitializeIPGlobals();
     CAIPDeinitializeQueueHandles();
 #endif
 }
@@ -462,13 +479,13 @@ void CAIPSendDataThread(void *threadData)
 #ifdef __WITH_DTLS__
         if (ipData->remoteEndpoint && ipData->remoteEndpoint->flags & CA_SECURE)
         {
-            OIC_LOG(DEBUG, TAG, "DTLS encrypt called");
+            OIC_LOG(INFO, TAG, "DTLS encrypt called");
             CAResult_t result = CAencryptSsl(ipData->remoteEndpoint, ipData->data, ipData->dataLen);
             if (CA_STATUS_OK != result)
             {
                 OIC_LOG(ERROR, TAG, "CAencryptSsl failed!");
             }
-            OIC_LOG_V(DEBUG, TAG, "CAencryptSsl returned with result[%d]", result);
+            OIC_LOG_V(INFO, TAG, "CAencryptSsl returned with result[%d]", result);
         }
         else
         {
index d1f5db3..d54de56 100644 (file)
 #define _GNU_SOURCE // for in6_pktinfo
 #endif
 
+#ifdef __TIZENRT__
+#include <tinyara/config.h>
+#include <uio.h>
+#endif
+
 #include "iotivity_config.h"
 #include <sys/types.h>
 #if !defined(_WIN32)
@@ -40,6 +45,7 @@
 #endif
 
 #include <stdio.h>
+#include <string.h>
 #if !defined(_MSC_VER)
 #include <unistd.h>
 #endif //!defined(_MSC_VER)
 #include <linux/rtnetlink.h>
 #endif
 
+#ifdef __TIZENRT__
+#include <uio.h>
+#include <mqueue.h>
+#endif
+
 #include <coap/pdu.h>
 #include "caipinterface.h"
 #include "caipnwmonitor.h"
@@ -64,7 +75,7 @@
 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
 #include "ca_adapter_net_ssl.h"
 #endif
-#include "camutex.h"
+#include "octhread.h"
 #include "oic_malloc.h"
 #include "oic_string.h"
 
 #undef USE_IP_MREQN
 #endif
 
+#ifdef __TIZEN__
+#include <pthread.h>
+#endif
+
 /*
  * Logging tag for module name
  */
-#define TAG "OIC_CA_IP_SERVER"
+//#define TAG "OIC_CA_IP_SERVER"
+#define TAG IP_SERVER_TAG
 
+#ifdef __TIZENRT__
+mqd_t g_nwevent_mqfd;
+#ifdef CONFIG_NET_LWIP
+#define SOCK_CLOEXEC 0
+#else
+#define SOCK_CLOEXEC 1
+#endif
+#endif
 #define SELECT_TIMEOUT 1     // select() seconds (and termination latency)
 
 #define IPv4_MULTICAST     "224.0.1.187"
 static struct in_addr IPv4MulticastAddress = { 0 };
 
 #define IPv6_DOMAINS       16
+#define MOBILE_INTERFACES  2
 #define IPv6_MULTICAST_INT "ff01::158"
 static struct in6_addr IPv6MulticastAddressInt;
 #define IPv6_MULTICAST_LNK "ff02::158"
@@ -118,6 +143,41 @@ static char *ipv6mcnames[IPv6_DOMAINS] = {
     NULL
 };
 
+// Samsung Mobile
+static char *mobileinferfaces[MOBILE_INTERFACES] = {
+    "rmnet", "pdp"
+};
+
+#ifdef __TIZENRT__
+struct in6_pktinfo {
+        struct in6_addr ipi6_addr;
+        int             ipi6_ifindex;
+};
+
+struct in_pktinfo
+{
+  unsigned int   ipi_ifindex;  /* Interface index */
+  struct in_addr ipi_spec_dst; /* Local address */
+  struct in_addr ipi_addr;     /* Header Destination
+                                    address */
+};
+
+
+#define RTMGRP_LINK 1
+#define IP_PKTINFO         8
+#define IPV6_PKTINFO            50
+#define IPV6_MULTICAST_IF 9
+#define IPV6_V6ONLY 27
+#define IPV6_RECVPKTINFO       50
+#define IPV6_JOIN_GROUP 12
+#endif
+
+/**
+ * By default, IP multicast datagrams are sent with a time-to-live (TTL) of 1.
+ * An application can choose an initial TTL.
+ */
+static size_t multicastTTL = 1;
+
 #if defined (_WIN32)
 #define IFF_UP_RUNNING_FLAGS  (IFF_UP)
 
@@ -147,15 +207,56 @@ static void CAEventReturned(CASocketFd_t socket);
 
 static CAResult_t CAReceiveMessage(CASocketFd_t fd, CATransportFlags_t flags);
 
+#ifdef __TIZEN__
+static int cleanup_pop_arg = 1;
+
+static void CAIPCleanupHandler(void *arg)
+{
+    OIC_LOG(DEBUG, TAG, "Called clean-up handler");
+
+    if (caglobals.ip.shutdownFds[0] != OC_INVALID_SOCKET)
+    {
+        close(caglobals.ip.shutdownFds[0]);
+        caglobals.ip.shutdownFds[0] = OC_INVALID_SOCKET;
+    }
+}
+
 static void CAReceiveHandler(void *data)
 {
     (void)data;
+    OIC_LOG(DEBUG, TAG, "IN - CAReceiveHandler");
+
+    pthread_cleanup_push(CAIPCleanupHandler, NULL);
 
     while (!caglobals.ip.terminate)
     {
         CAFindReadyMessage();
     }
+
+    pthread_cleanup_pop(cleanup_pop_arg);
+
+    OIC_LOG(DEBUG, TAG, "OUT - CAReceiveHandler");
 }
+#else
+static void CAReceiveHandler(void *data)
+{
+    (void)data;
+    OIC_LOG(DEBUG, TAG, "IN - CAReceiveHandler");
+
+    while (!caglobals.ip.terminate)
+    {
+        CAFindReadyMessage();
+    }
+#ifndef __TIZENRT__
+    if (caglobals.ip.shutdownFds[0] != OC_INVALID_SOCKET)
+    {
+        close(caglobals.ip.shutdownFds[0]);
+        caglobals.ip.shutdownFds[0] = OC_INVALID_SOCKET;
+    }
+#endif
+    OIC_LOG(DEBUG, TAG, "OUT - CAReceiveHandler");
+}
+#endif
 
 #if !defined(WSA_WAIT_EVENT_0)
 
@@ -198,11 +299,12 @@ static void CAFindReadyMessage()
     SET(m6s, &readFds)
     SET(m4,  &readFds)
     SET(m4s, &readFds)
-
+#ifndef __TIZENRT__
     if (caglobals.ip.shutdownFds[0] != -1)
     {
         FD_SET(caglobals.ip.shutdownFds[0], &readFds);
     }
+#endif
     if (caglobals.ip.netlinkFd != OC_INVALID_SOCKET)
     {
         FD_SET(caglobals.ip.netlinkFd, &readFds);
@@ -212,10 +314,25 @@ static void CAFindReadyMessage()
 
     if (caglobals.ip.terminate)
     {
-        OIC_LOG_V(DEBUG, TAG, "Packet receiver Stop request received.");
+        OIC_LOG_V(INFO, TAG, "Packet receiver Stop request received.");
         return;
     }
-
+#ifdef __TIZENRT__
+    u_arraylist_t *iflist = CAFindInterfaceChange();
+    if (iflist)
+    {
+        uint32_t listLength = u_arraylist_length(iflist);
+        for (uint32_t i = 0; i < listLength; i++)
+        {
+            CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i);
+            if (ifitem)
+            {
+                CAProcessNewInterface(ifitem);
+            }
+        }
+        u_arraylist_destroy(iflist);
+    }
+#endif
     if (0 < ret)
     {
         CASelectReturned(&readFds, ret);
@@ -244,6 +361,7 @@ static void CASelectReturned(fd_set *readFds, int ret)
         else ISSET(m4s, readFds, CA_MULTICAST | CA_IPV4 | CA_SECURE)
         else if ((caglobals.ip.netlinkFd != OC_INVALID_SOCKET) && FD_ISSET(caglobals.ip.netlinkFd, readFds))
         {
+#ifndef __TIZENRT__
             u_arraylist_t *iflist = CAFindInterfaceChange();
             if (iflist)
             {
@@ -259,7 +377,9 @@ static void CASelectReturned(fd_set *readFds, int ret)
                 u_arraylist_destroy(iflist);
             }
             break;
+#endif
         }
+#ifndef __TIZENRT__
         else if (FD_ISSET(caglobals.ip.shutdownFds[0], readFds))
         {
             char buf[10] = {0};
@@ -270,6 +390,7 @@ static void CASelectReturned(fd_set *readFds, int ret)
             }
             break;
         }
+#endif
         else
         {
             break;
@@ -468,14 +589,7 @@ static void CAEventReturned(CASocketFd_t socket)
 
 void CADeInitializeIPGlobals()
 {
-    CLOSE_SOCKET(u6);
-    CLOSE_SOCKET(u6s);
-    CLOSE_SOCKET(u4);
-    CLOSE_SOCKET(u4s);
-    CLOSE_SOCKET(m6);
-    CLOSE_SOCKET(m6s);
-    CLOSE_SOCKET(m4);
-    CLOSE_SOCKET(m4s);
+    CloseMulticastSocket();
 
     if (caglobals.ip.netlinkFd != OC_INVALID_SOCKET)
     {
@@ -490,6 +604,7 @@ void CADeInitializeIPGlobals()
 
 static CAResult_t CAReceiveMessage(CASocketFd_t fd, CATransportFlags_t flags)
 {
+    OIC_LOG(DEBUG, TAG, "IN - CAReceiveMessage");
     char recvBuffer[COAP_MAX_PDU_SIZE] = {0};
 
     size_t len = 0;
@@ -535,6 +650,7 @@ static CAResult_t CAReceiveMessage(CASocketFd_t fd, CATransportFlags_t flags)
         OIC_LOG_V(ERROR, TAG, "Recvfrom failed %s", strerror(errno));
         return CA_STATUS_FAILED;
     }
+    OIC_LOG_V(DEBUG, TAG, "recvd %u bytes from recvmsg", recvLen);
 
     if (flags & CA_MULTICAST)
     {
@@ -597,6 +713,7 @@ static CAResult_t CAReceiveMessage(CASocketFd_t fd, CATransportFlags_t flags)
 #endif // !defined(WSA_CMSG_DATA)
     CASecureEndpoint_t sep = {.endpoint = {.adapter = CA_ADAPTER_IP, .flags = flags}};
 
+#ifndef __TIZENRT__
     if (flags & CA_IPV6)
     {
         /** @todo figure out correct usage for ifindex, and sin6_scope_id.*/
@@ -611,6 +728,7 @@ static CAResult_t CAReceiveMessage(CASocketFd_t fd, CATransportFlags_t flags)
         }
     }
     else
+#endif
     {
         if ((flags & CA_MULTICAST) && pktinfo)
         {
@@ -630,7 +748,7 @@ static CAResult_t CAReceiveMessage(CASocketFd_t fd, CATransportFlags_t flags)
     {
 #ifdef __WITH_DTLS__
         int ret = CAdecryptSsl(&sep, (uint8_t *)recvBuffer, recvLen);
-        OIC_LOG_V(DEBUG, TAG, "CAdecryptSsl returns [%d]", ret);
+        OIC_LOG_V(INFO, TAG, "CAdecryptSsl returns [%d]", ret);
 #else
         OIC_LOG(ERROR, TAG, "Encrypted message but no DTLS");
 #endif
@@ -639,10 +757,12 @@ static CAResult_t CAReceiveMessage(CASocketFd_t fd, CATransportFlags_t flags)
     {
         if (g_packetReceivedCallback)
         {
+            OIC_LOG(DEBUG, TAG, "call receivedCB");
             g_packetReceivedCallback(&sep, recvBuffer, recvLen);
         }
     }
 
+    OIC_LOG(DEBUG, TAG, "OUT - CAReceiveMessage");
     return CA_STATUS_OK;
 
 }
@@ -767,13 +887,56 @@ static CASocketFd_t CACreateSocket(int family, uint16_t *port, bool isMulticast)
     if (FD > caglobals.ip.maxfd) \
         caglobals.ip.maxfd = FD;
 #define NEWSOCKET(FAMILY, NAME, MULTICAST) \
-    caglobals.ip.NAME.fd = CACreateSocket(FAMILY, &caglobals.ip.NAME.port, MULTICAST); \
     if (caglobals.ip.NAME.fd == OC_INVALID_SOCKET) \
     {   \
-        caglobals.ip.NAME.port = 0; \
         caglobals.ip.NAME.fd = CACreateSocket(FAMILY, &caglobals.ip.NAME.port, MULTICAST); \
+        if (caglobals.ip.NAME.fd == OC_INVALID_SOCKET) \
+        {   \
+            caglobals.ip.NAME.port = 0; \
+            caglobals.ip.NAME.fd = CACreateSocket(FAMILY, &caglobals.ip.NAME.port, MULTICAST); \
+        }   \
+        CHECKFD(caglobals.ip.NAME.fd)   \
     }   \
-    CHECKFD(caglobals.ip.NAME.fd)
+
+void CreateMulticastSocket()
+{
+    OIC_LOG_V(INFO, TAG, "In %s", __func__);
+
+    if (caglobals.ip.ipv6enabled)
+    {
+        NEWSOCKET(AF_INET6, u6, false)
+        NEWSOCKET(AF_INET6, u6s, false)
+        NEWSOCKET(AF_INET6, m6, true)
+        NEWSOCKET(AF_INET6, m6s, true)
+        OIC_LOG_V(INFO, TAG, "IPv6 unicast port: %u", caglobals.ip.u6.port);
+    }
+    if (caglobals.ip.ipv4enabled)
+    {
+        NEWSOCKET(AF_INET, u4, false)
+        NEWSOCKET(AF_INET, u4s, false)
+        NEWSOCKET(AF_INET, m4, true)
+        NEWSOCKET(AF_INET, m4s, true)
+        OIC_LOG_V(INFO, TAG, "IPv4 unicast port: %u", caglobals.ip.u4.port);
+    }
+
+    OIC_LOG_V(INFO, TAG, "Out %s", __func__);
+}
+
+void CloseMulticastSocket()
+{
+    OIC_LOG_V(INFO, TAG, "In %s", __func__);
+
+    CLOSE_SOCKET(u6);
+    CLOSE_SOCKET(u6s);
+    CLOSE_SOCKET(u4);
+    CLOSE_SOCKET(u4s);
+    CLOSE_SOCKET(m6);
+    CLOSE_SOCKET(m6s);
+    CLOSE_SOCKET(m4);
+    CLOSE_SOCKET(m4s);
+
+    OIC_LOG_V(INFO, TAG, "Out %s", __func__);
+}
 
 static void CAInitializeNetlink()
 {
@@ -802,6 +965,17 @@ static void CAInitializeNetlink()
             CHECKFD(caglobals.ip.netlinkFd);
         }
     }
+#elif defined (__TIZENRT__) // pkmsgq
+       struct mq_attr lq_attr;
+       lq_attr.mq_maxmsg = 10;
+       lq_attr.mq_msgsize = 4;
+       lq_attr.mq_flags = 0;
+       g_nwevent_mqfd = mq_open("netlink_evtq", O_RDWR | O_NONBLOCK | O_CREAT, 0666, &lq_attr);
+       if (g_nwevent_mqfd == (mqd_t) - 1)
+       {
+               OIC_LOG_V(ERROR, TAG,"RECV mq_open failed\n");
+               return ;
+       }
 #endif
 }
 
@@ -816,10 +990,13 @@ static void CAInitializeFastShutdownMechanism()
         ret = 0;
     }
 #elif defined(HAVE_PIPE2)
+#ifndef __TIZENRT__
     ret = pipe2(caglobals.ip.shutdownFds, O_CLOEXEC);
     CHECKFD(caglobals.ip.shutdownFds[0]);
     CHECKFD(caglobals.ip.shutdownFds[1]);
+#endif
 #else
+#ifndef __TIZENRT__
     ret = pipe(caglobals.ip.shutdownFds);
     if (-1 != ret)
     {
@@ -847,6 +1024,7 @@ static void CAInitializeFastShutdownMechanism()
     CHECKFD(caglobals.ip.shutdownFds[0]);
     CHECKFD(caglobals.ip.shutdownFds[1]);
 #endif
+#endif
     if (-1 == ret)
     {
         OIC_LOG_V(ERROR, TAG, "fast shutdown mechanism init failed: %s", CAIPS_GET_ERROR);
@@ -890,29 +1068,14 @@ CAResult_t CAIPStartServer(const ca_thread_pool_t threadPool)
         caglobals.ip.ipv4enabled = true;  // only needed to run CA tests
     }
 
-    if (caglobals.ip.ipv6enabled)
-    {
-        NEWSOCKET(AF_INET6, u6, false)
-        NEWSOCKET(AF_INET6, u6s, false)
-        NEWSOCKET(AF_INET6, m6, true)
-        NEWSOCKET(AF_INET6, m6s, true)
-        OIC_LOG_V(INFO, TAG, "IPv6 unicast port: %u", caglobals.ip.u6.port);
-    }
-    if (caglobals.ip.ipv4enabled)
-    {
-        NEWSOCKET(AF_INET, u4, false)
-        NEWSOCKET(AF_INET, u4s, false)
-        NEWSOCKET(AF_INET, m4, true)
-        NEWSOCKET(AF_INET, m4s, true)
-        OIC_LOG_V(INFO, TAG, "IPv4 unicast port: %u", caglobals.ip.u4.port);
-    }
+    CreateMulticastSocket();
 
-    OIC_LOG_V(DEBUG, TAG,
+    OIC_LOG_V(INFO, TAG,
               "socket summary: u6=%d, u6s=%d, u4=%d, u4s=%d, m6=%d, m6s=%d, m4=%d, m4s=%d",
               caglobals.ip.u6.fd, caglobals.ip.u6s.fd, caglobals.ip.u4.fd, caglobals.ip.u4s.fd,
               caglobals.ip.m6.fd, caglobals.ip.m6s.fd, caglobals.ip.m4.fd, caglobals.ip.m4s.fd);
 
-    OIC_LOG_V(DEBUG, TAG,
+    OIC_LOG_V(INFO, TAG,
               "port summary: u6 port=%d, u6s port=%d, u4 port=%d, u4s port=%d, m6 port=%d,"
               "m6s port=%d, m4 port=%d, m4s port=%d",
               caglobals.ip.u6.port, caglobals.ip.u6s.port, caglobals.ip.u4.port,
@@ -945,13 +1108,19 @@ CAResult_t CAIPStartServer(const ca_thread_pool_t threadPool)
     }
 
     caglobals.ip.terminate = false;
-    res = ca_thread_pool_add_task(threadPool, CAReceiveHandler, NULL);
+#ifndef __TIZENRT__
+    res = ca_thread_pool_add_task(threadPool, CAReceiveHandler, NULL, NULL);
+#else
+    res = ca_thread_pool_add_task(threadPool, CAReceiveHandler, NULL, NULL, "IoT_ReceiveHandler",
+                                  CONFIG_IOTIVITY_RECEIVEHANDLER_PTHREAD_STACKSIZE);
+#endif
     if (CA_STATUS_OK != res)
     {
         OIC_LOG(ERROR, TAG, "thread_pool_add_task failed");
+        CAIPStopServer();
         return res;
     }
-    OIC_LOG(DEBUG, TAG, "CAReceiveHandler thread started successfully.");
+    OIC_LOG(INFO, TAG, "CAReceiveHandler thread started successfully.");
 
     caglobals.ip.started = true;
     return CA_STATUS_OK;
@@ -962,7 +1131,10 @@ void CAIPStopServer()
     caglobals.ip.started = false;
     caglobals.ip.terminate = true;
 
+    CADeInitializeIPGlobals();
+
 #if !defined(WSA_WAIT_EVENT_0)
+#ifndef __TIZENRT__
     if (caglobals.ip.shutdownFds[1] != -1)
     {
         close(caglobals.ip.shutdownFds[1]);
@@ -972,6 +1144,7 @@ void CAIPStopServer()
     {
         // receive thread will stop in SELECT_TIMEOUT seconds.
     }
+#endif
 #else
     // receive thread will stop immediately.
     if (!WSASetEvent(caglobals.ip.shutdownEvent))
@@ -979,29 +1152,8 @@ void CAIPStopServer()
         OIC_LOG_V(DEBUG, TAG, "set shutdown event failed: %#08X", GetLastError());
     }
 #endif
-}
 
-void CAWakeUpForChange()
-{
-#if !defined(WSA_WAIT_EVENT_0)
-    if (caglobals.ip.shutdownFds[1] != -1)
-    {
-        ssize_t len = 0;
-        do
-        {
-            len = write(caglobals.ip.shutdownFds[1], "w", 1);
-        } while ((len == -1) && (errno == EINTR));
-        if ((len == -1) && (errno != EINTR) && (errno != EPIPE))
-        {
-            OIC_LOG_V(DEBUG, TAG, "write failed: %s", strerror(errno));
-        }
-    }
-#else
-    if (!WSASetEvent(caglobals.ip.shutdownEvent))
-    {
-        OIC_LOG_V(DEBUG, TAG, "set shutdown event failed: %#08X", GetLastError());
-    }
-#endif
+    OIC_LOG(INFO, TAG, "Adapter terminated successfully");
 }
 
 static void applyMulticastToInterface4(uint32_t ifindex)
@@ -1048,7 +1200,8 @@ static void applyMulticastToInterface4(uint32_t ifindex)
 
 static void applyMulticast6(int fd, struct in6_addr *addr, uint32_t ifindex)
 {
-    struct ipv6_mreq mreq = {.ipv6mr_multiaddr = {0},
+#ifndef __TIZENRT__
+    struct ipv6_mreq mreq = {.ipv6mr_multiaddr = {{{0}}},
                              .ipv6mr_interface = ifindex };
 
     // VS2013 has problems with struct copies inside struct initializers, so copy separately.
@@ -1066,6 +1219,7 @@ static void applyMulticast6(int fd, struct in6_addr *addr, uint32_t ifindex)
             OIC_LOG_V(ERROR, TAG, "IPv6 IPV6_JOIN_GROUP failed: %s", CAIPS_GET_ERROR);
         }
     }
+#endif
 }
 
 static void applyMulticastToInterface6(uint32_t ifindex)
@@ -1243,10 +1397,14 @@ static void sendData(int fd, const CAEndpoint_t *endpoint,
             g_ipErrorHandler(endpoint, data, dlen, CA_SEND_FAILED);
         }
         OIC_LOG_V(ERROR, TAG, "%s%s %s sendTo failed: %s", secure, cast, fam, strerror(errno));
+        CALogSendStateInfo(endpoint->adapter, endpoint->addr, endpoint->port,
+                           len, false, strerror(errno));
     }
     else
     {
         OIC_LOG_V(INFO, TAG, "%s%s %s sendTo is successful: %zd bytes", secure, cast, fam, len);
+        CALogSendStateInfo(endpoint->adapter, endpoint->addr, endpoint->port,
+                           len, true, NULL);
     }
 #else
     int err = 0;
@@ -1273,11 +1431,11 @@ static void sendData(int fd, const CAEndpoint_t *endpoint,
             sent += len;
             if (sent != len)
             {
-                OIC_LOG_V(DEBUG, TAG, "%s%s %s sendTo (Partial Send) is successful: "
-                                      "currently sent: %ld bytes, "
-                                      "total sent: %ld bytes, "
-                                      "remaining: %ld bytes",
-                                      secure, cast, fam, len, sent, dlen-sent);
+                OIC_LOG_V(INFO, TAG, "%s%s %s sendTo (Partial Send) is successful: "
+                          "currently sent: %ld bytes, "
+                          "total sent: %ld bytes, "
+                          "remaining: %ld bytes",
+                          secure, cast, fam, len, sent, dlen-sent);
             }
             else
             {
@@ -1326,12 +1484,34 @@ static void sendMulticastData6(const u_arraylist_t *iflist,
             continue;
         }
 
+        bool isMobile = false;
+        for (uint32_t j = 0; j < MOBILE_INTERFACES; j++)
+        {
+            if (strstr(ifitem->name, mobileinferfaces[j]))
+            {
+                isMobile = true;
+                break;
+            }
+        }
+        if (isMobile)
+        {
+            continue;
+        }
+
         int index = ifitem->index;
         if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, OPTVAL_T(&index), sizeof (index)))
         {
             OIC_LOG_V(ERROR, TAG, "setsockopt6 failed: %s", CAIPS_GET_ERROR);
             return;
         }
+
+#ifndef __TIZENRT__
+        // Set multicast packet TTL; default TTL is 1
+        if (setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &multicastTTL, sizeof(multicastTTL)))
+        {
+            OIC_LOG_V(ERROR, TAG, "IPV6_MULTICAST_HOPS failed: %s", CAIPS_GET_ERROR);
+        }
+#endif
         sendData(fd, endpoint, data, datalen, "multicast", "ipv6");
     }
 }
@@ -1370,6 +1550,21 @@ static void sendMulticastData4(const u_arraylist_t *iflist,
         {
             continue;
         }
+
+        bool isMobile = false;
+        for (uint32_t j = 0; j < MOBILE_INTERFACES; j++)
+        {
+            if (strstr(ifitem->name, mobileinferfaces[j]))
+            {
+                isMobile = true;
+                break;
+            }
+        }
+        if (isMobile)
+        {
+            continue;
+        }
+
 #if defined(USE_IP_MREQN)
         mreq.imr_ifindex = ifitem->index;
 #else
@@ -1380,6 +1575,12 @@ static void sendMulticastData4(const u_arraylist_t *iflist,
             OIC_LOG_V(ERROR, TAG, "send IP_MULTICAST_IF failed: %s (using defualt)",
                     CAIPS_GET_ERROR);
         }
+
+        // Set multicast packet TTL; default TTL is 1
+        if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &multicastTTL, sizeof(multicastTTL)))
+        {
+            OIC_LOG_V(ERROR, TAG, "IP_MULTICAST_TTL failed: %s", CAIPS_GET_ERROR);
+        }
         sendData(fd, endpoint, data, datalen, "multicast", "ipv4");
     }
 }
@@ -1525,3 +1726,17 @@ void CAIPSetErrorHandler(CAIPErrorHandleCallback errorHandleCallback)
 {
     g_ipErrorHandler = errorHandleCallback;
 }
+
+CAResult_t CAIPSetMulticastTTL(size_t ttl)
+{
+    multicastTTL = ttl;
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAIPGetMulticastTTL(size_t *ttl)
+{
+    VERIFY_NON_NULL(ttl, TAG, "ttl is NULL");
+
+    *ttl = multicastTTL;
+    return CA_STATUS_OK;
+}
diff --git a/resource/csdk/connectivity/src/ip_adapter/ios/caipnwmonitor.m b/resource/csdk/connectivity/src/ip_adapter/ios/caipnwmonitor.m
new file mode 100644 (file)
index 0000000..9101820
--- /dev/null
@@ -0,0 +1,580 @@
+/******************************************************************
+*
+* 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 "caipinterface.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <ifaddrs.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <net/if.h>
+#include <netdb.h>
+#include <errno.h>
+
+#include "octhread.h"
+#include "caipnwmonitor.h"
+#include "caadapterutils.h"
+#include "logger.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include <coap/utlist.h>
+
+#import <Foundation/Foundation.h>
+#import <SystemConfiguration/CaptiveNetwork.h>
+
+#define TAG "OIC_CA_IP_MONITOR"
+
+/**
+ * Mutex for synchronizing access to cached interface and IP address information.
+ */
+static oc_mutex g_networkMonitorContextMutex = NULL;
+
+/**
+ * Used to storing network interface.
+ */
+static u_arraylist_t *g_netInterfaceList = NULL;
+
+/**
+ * Used to storing initial AP Name.
+ */
+NSString *initialAPName = nil;
+
+/**
+ * Used to storing adapter changes callback interface.
+ */
+static struct CAIPCBData_t *g_adapterCallbackList = NULL;
+
+/**
+ * Initialize the network interface monitoring list.
+ */
+static CAResult_t CAIPInitializeNetworkMonitorList();
+
+/**
+ * Destroy the network interface monitoring list.
+ */
+static void CAIPDestroyNetworkMonitorList();
+
+/**
+ * Compare the interface with the already added interface in list.
+ */
+static bool CACmpNetworkList(size_t ifiindex);
+
+/**
+ * Add new network interface in list.
+ */
+static CAResult_t CAAddNetworkMonitorList(CAInterface_t *ifitem);
+
+/**
+ * Remove network interace from list.
+ */
+static void CARemoveNetworkMonitorList(int ifiindex);
+
+/**
+ * Pass the changed network status through the stored callback.
+ */
+static void CAIPPassNetworkChangesToAdapter(CANetworkStatus_t status);
+
+/**
+ * Create new interface item.
+ */
+static CAInterface_t *CANewInterfaceItem(int index, const char *name, int family,
+                                         const char *addr, int flags);
+
+/**
+  * Callback function invoked for each observer of a notification
+  * when the notification is posted.
+  * @param center The notification center handling the notification
+  * @param observer An arbitrary value, other than NULL, that identifies the observer
+  * @param name The name of the notification being posted
+  * @param object An arbitrary value that identifies the object posting the notification
+  * @param userInfo A dictionary containing additional information regarding
+  *        the notification
+  */
+static void onNotifyCallback(CFNotificationCenterRef center, void *observer,
+                    CFStringRef name, const void *object, CFDictionaryRef userInfo);
+
+/**
+ * Check whether Celluler data is On/Off
+ */
+bool isCellulerDataEnabled();
+
+static CAResult_t CAIPInitializeNetworkMonitorList()
+{
+    if (!g_networkMonitorContextMutex)
+    {
+        g_networkMonitorContextMutex = oc_mutex_new();
+        if (!g_networkMonitorContextMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (!g_netInterfaceList)
+    {
+        g_netInterfaceList = u_arraylist_create();
+        if (!g_netInterfaceList)
+        {
+            OIC_LOG(ERROR, TAG, "u_arraylist_create has failed");
+            CAIPDestroyNetworkMonitorList();
+            return CA_STATUS_FAILED;
+        }
+    }
+    return CA_STATUS_OK;
+}
+
+static void CAIPDestroyNetworkMonitorList()
+{
+    if (g_netInterfaceList)
+    {
+        u_arraylist_destroy(g_netInterfaceList);
+        g_netInterfaceList = NULL;
+    }
+
+    if (g_networkMonitorContextMutex)
+    {
+        oc_mutex_free(g_networkMonitorContextMutex);
+        g_networkMonitorContextMutex = NULL;
+    }
+}
+
+static bool CACmpNetworkList(size_t ifiindex)
+{
+    if (!g_netInterfaceList)
+    {
+        OIC_LOG(ERROR, TAG, "g_netInterfaceList is NULL");
+        return false;
+    }
+
+    oc_mutex_lock(g_networkMonitorContextMutex);
+
+    size_t list_length = u_arraylist_length(g_netInterfaceList);
+    for (size_t list_index = 0; list_index < list_length; list_index++)
+    {
+        CAInterface_t *currItem = (CAInterface_t *) u_arraylist_get(g_netInterfaceList,
+                                                                    list_index);
+        if (currItem->index == ifiindex)
+        {
+            oc_mutex_unlock(g_networkMonitorContextMutex);
+            return true;
+        }
+    }
+    oc_mutex_unlock(g_networkMonitorContextMutex);
+    return false;
+}
+
+static CAResult_t CAAddNetworkMonitorList(CAInterface_t *ifitem)
+{
+    VERIFY_NON_NULL(g_netInterfaceList, TAG, "g_netInterfaceList is NULL");
+    VERIFY_NON_NULL(ifitem, TAG, "ifitem is NULL");
+
+    oc_mutex_lock(g_networkMonitorContextMutex);
+    bool result = u_arraylist_add(g_netInterfaceList, (void *) ifitem);
+    if (!result)
+    {
+        OIC_LOG(ERROR, TAG, "u_arraylist_add failed.");
+        oc_mutex_unlock(g_networkMonitorContextMutex);
+        return CA_STATUS_FAILED;
+    }
+    oc_mutex_unlock(g_networkMonitorContextMutex);
+    return CA_STATUS_OK;
+}
+
+static void CARemoveNetworkMonitorList(int ifiindex)
+{
+    VERIFY_NON_NULL_VOID(g_netInterfaceList, TAG, "g_netInterfaceList is NULL");
+
+    oc_mutex_lock(g_networkMonitorContextMutex);
+
+    size_t list_length = u_arraylist_length(g_netInterfaceList);
+    for (size_t list_index = 0; list_index < list_length; list_index++)
+    {
+        CAInterface_t *removedifitem = (CAInterface_t *) u_arraylist_get(
+                g_netInterfaceList, list_index);
+        if (removedifitem && ((int)removedifitem->index) == ifiindex)
+        {
+            if (u_arraylist_remove(g_netInterfaceList, list_index))
+            {
+                OICFree(removedifitem);
+                oc_mutex_unlock(g_networkMonitorContextMutex);
+                return;
+            }
+            continue;
+        }
+    }
+    oc_mutex_unlock(g_networkMonitorContextMutex);
+    return;
+}
+
+CAResult_t CAIPStartNetworkMonitor(CAIPAdapterStateChangeCallback callback,
+                                   CATransportAdapter_t adapter)
+{
+    NSDictionary *connectionDetails = [NSDictionary dictionary];
+    NSArray *myArray = (id) CNCopySupportedInterfaces();
+    if (myArray) {
+        CFDictionaryRef myDict = CNCopyCurrentNetworkInfo((__bridge CFStringRef)myArray[0]);
+        connectionDetails = (NSDictionary*) myDict;
+    }
+
+    initialAPName = connectionDetails[@"SSID"];
+    OIC_LOG_V(INFO, TAG, "Initial AP Name = %s", [initialAPName UTF8String]);
+
+    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),
+                                    NULL,
+                                    onNotifyCallback,
+                                    CFSTR("com.apple.system.config.network_change"),
+                                    NULL,
+                                    CFNotificationSuspensionBehaviorDeliverImmediately);
+
+    OIC_LOG_V(INFO, TAG, "Celluler Data Enabled = %d", isCellulerDataEnabled());
+
+    CAResult_t res = CAIPInitializeNetworkMonitorList();
+    if (CA_STATUS_OK == res)
+    {
+        return CAIPSetNetworkMonitorCallback(callback, adapter);
+    }
+    return res;
+}
+
+CAResult_t CAIPStopNetworkMonitor(CATransportAdapter_t adapter)
+{
+    CFNotificationCenterRemoveObserver(CFNotificationCenterGetDarwinNotifyCenter(),
+            NULL, CFSTR("com.apple.system.config.network_change"), NULL);
+    CAIPDestroyNetworkMonitorList();
+    return CAIPUnSetNetworkMonitorCallback(adapter);
+}
+
+int CAGetPollingInterval(int interval)
+{
+    return interval;
+}
+
+static void CAIPPassNetworkChangesToAdapter(CANetworkStatus_t status)
+{
+    CAIPCBData_t *cbitem = NULL;
+    LL_FOREACH(g_adapterCallbackList, cbitem)
+    {
+        if (cbitem && cbitem->adapter)
+        {
+            cbitem->callback(cbitem->adapter, status);
+        }
+    }
+}
+
+CAResult_t CAIPSetNetworkMonitorCallback(CAIPAdapterStateChangeCallback callback,
+                                         CATransportAdapter_t adapter)
+{
+    if (!callback)
+    {
+        OIC_LOG(ERROR, TAG, "callback is null");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    CAIPCBData_t *cbitem = NULL;
+    LL_FOREACH(g_adapterCallbackList, cbitem)
+    {
+        if (cbitem && adapter == cbitem->adapter && callback == cbitem->callback)
+        {
+            OIC_LOG(DEBUG, TAG, "this callback is already added");
+            return CA_STATUS_OK;
+        }
+    }
+
+    cbitem = (CAIPCBData_t *)OICCalloc(1, sizeof(*cbitem));
+    if (!cbitem)
+    {
+        OIC_LOG(ERROR, TAG, "Malloc failed");
+        return CA_STATUS_FAILED;
+    }
+
+    cbitem->adapter = adapter;
+    cbitem->callback = callback;
+    LL_APPEND(g_adapterCallbackList, cbitem);
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAIPUnSetNetworkMonitorCallback(CATransportAdapter_t adapter)
+{
+    CAIPCBData_t *cbitem = NULL;
+    CAIPCBData_t *tmpCbitem = NULL;
+    LL_FOREACH_SAFE(g_adapterCallbackList, cbitem, tmpCbitem)
+    {
+        if (cbitem && adapter == cbitem->adapter)
+        {
+            OIC_LOG(DEBUG, TAG, "remove specific callback");
+            LL_DELETE(g_adapterCallbackList, cbitem);
+            OICFree(cbitem);
+            return CA_STATUS_OK;
+        }
+    }
+    return CA_STATUS_OK;
+}
+
+static CAInterface_t *CANewInterfaceItem(int index, const char *name, int family,
+                                         const char *addr, int flags)
+{
+    CAInterface_t *ifitem = (CAInterface_t *)OICCalloc(1, sizeof (CAInterface_t));
+    if (!ifitem)
+    {
+        OIC_LOG(ERROR, TAG, "Malloc failed");
+        return NULL;
+    }
+
+    OICStrcpy(ifitem->name, sizeof (ifitem->name), name);
+    ifitem->index = index;
+    ifitem->family = family;
+    OICStrcpy(ifitem->addr, sizeof (ifitem->addr), addr);
+    ifitem->flags = flags;
+
+    return ifitem;
+}
+
+u_arraylist_t *CAFindInterfaceChange()
+{
+    u_arraylist_t *iflist = NULL;
+    char buf[4096] = { 0 };
+    struct nlmsghdr *nh = NULL;
+    struct iovec iov = { .iov_base = buf,
+                         .iov_len = sizeof (buf) };
+    struct msghdr msg = { .msg_name = (void *)0,
+                          .msg_namelen = 0,
+                          .msg_iov = &iov,
+                          .msg_iovlen = 1 };
+
+    ssize_t len = recvmsg(caglobals.ip.netlinkFd, &msg, 0);
+    return iflist;
+}
+
+u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex)
+{
+    if (desiredIndex < 0)
+    {
+        OIC_LOG_V(ERROR, TAG, "invalid index : %d", desiredIndex);
+        return NULL;
+    }
+
+    u_arraylist_t *iflist = u_arraylist_create();
+    if (!iflist)
+    {
+        OIC_LOG_V(ERROR, TAG, "Failed to create iflist: %s", strerror(errno));
+        return NULL;
+    }
+
+    struct ifaddrs *ifp = NULL;
+    if (-1 == getifaddrs(&ifp))
+    {
+        OIC_LOG_V(ERROR, TAG, "Failed to get ifaddrs: %s", strerror(errno));
+        u_arraylist_destroy(iflist);
+        return NULL;
+    }
+
+    struct ifaddrs *ifa = NULL;
+    for (ifa = ifp; ifa; ifa = ifa->ifa_next)
+    {
+        if (!ifa->ifa_addr)
+        {
+            continue;
+        }
+        int family = ifa->ifa_addr->sa_family;
+        if ((ifa->ifa_flags & IFF_LOOPBACK) || (AF_INET != family && AF_INET6 != family))
+        {
+            continue;
+        }
+
+        int ifindex = if_nametoindex(ifa->ifa_name);
+        if (desiredIndex && (ifindex != desiredIndex))
+        {
+            continue;
+        }
+
+        int length = u_arraylist_length(iflist);
+        int already = false;
+        for (int i = length-1; i >= 0; i--)
+        {
+            CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i);
+
+            if (ifitem
+                && (int)ifitem->index == ifindex
+                && ifitem->family == (uint16_t)family)
+            {
+                already = true;
+                break;
+            }
+        }
+        if (already)
+        {
+            continue;
+        }
+
+        CAInterface_t *ifitem = (CAInterface_t *)OICCalloc(1, sizeof(CAInterface_t));
+        if (!ifitem)
+        {
+            OIC_LOG(ERROR, TAG, "Malloc failed");
+            goto exit;
+        }
+
+        OICStrcpy(ifitem->name, INTERFACE_NAME_MAX, ifa->ifa_name);
+        ifitem->index = ifindex;
+        ifitem->family = family;
+        ifitem->flags = ifa->ifa_flags;
+
+        if (ifitem->family == AF_INET6)
+        {
+            struct sockaddr_in6 *in6 = (struct sockaddr_in6*) ifa->ifa_addr;
+            inet_ntop(ifitem->family, (void *)&(in6->sin6_addr), ifitem->addr,
+                      sizeof(ifitem->addr));
+        }
+        else if (ifitem->family == AF_INET)
+        {
+            struct sockaddr_in *in = (struct sockaddr_in*) ifa->ifa_addr;
+            inet_ntop(ifitem->family, (void *)&(in->sin_addr), ifitem->addr,
+                      sizeof(ifitem->addr));
+        }
+
+        bool result = u_arraylist_add(iflist, ifitem);
+        if (!result)
+        {
+            OIC_LOG(ERROR, TAG, "u_arraylist_add failed.");
+            goto exit;
+        }
+
+        bool isFound = CACmpNetworkList(ifitem->index);
+        if (!isFound)
+        {
+            CAInterface_t *newifitem = CANewInterfaceItem(ifitem->index, ifitem->name,
+                                          ifitem->family, ifitem->addr, ifitem->flags);
+            CAResult_t ret = CAAddNetworkMonitorList(newifitem);
+            if (CA_STATUS_OK != ret)
+            {
+                OICFree(newifitem);
+                goto exit;
+            }
+            CAIPPassNetworkChangesToAdapter(CA_INTERFACE_UP);
+            OIC_LOG_V(DEBUG, TAG, "Added interface: %s (%d)", ifitem->name, ifitem->family);
+        }
+    }
+    freeifaddrs(ifp);
+    return iflist;
+
+exit:
+    freeifaddrs(ifp);
+    u_arraylist_destroy(iflist);
+    return NULL;
+}
+
+
+void CAIpStateEnabled()
+{
+    OIC_LOG(DEBUG, TAG, "Wifi is in Activated State");
+    CAIPPassNetworkChangesToAdapter(CA_INTERFACE_UP);
+
+    u_arraylist_t *iflist = CAIPGetInterfaceInformation(0);
+    if (!iflist)
+    {
+        OIC_LOG_V(ERROR, TAG, "get interface info failed: %s", strerror(errno));
+        return;
+    }
+
+    size_t listLength = u_arraylist_length(iflist);
+    for (size_t i = 0; i < listLength; i++)
+    {
+        CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i);
+        if (!ifitem)
+        {
+            continue;
+        }
+        CAProcessNewInterface(ifitem);
+    }
+    u_arraylist_destroy(iflist);
+}
+
+void CAIpStateDisabled()
+{
+    OIC_LOG(DEBUG, TAG, "Wifi or Celluler Data is in Deactivated State");
+    CAIPPassNetworkChangesToAdapter(CA_INTERFACE_DOWN);
+}
+
+bool isCellulerDataEnabled()
+{
+    struct ifaddrs* interfaces = NULL;
+    struct ifaddrs* temp_addr = NULL;
+    int success = 0;
+    bool isEnabled = false;
+
+    success = getifaddrs(&interfaces);
+
+    if (success == 0)
+    {
+        temp_addr = interfaces;
+
+        while (temp_addr != NULL)
+        {
+            if ((temp_addr->ifa_addr->sa_family == AF_INET) || (temp_addr->ifa_addr->sa_family == AF_INET6))
+            {
+                NSString* ifa_name = [NSString stringWithUTF8String: temp_addr->ifa_name];
+                if ([ifa_name isEqualToString:@"pdp_ip0"])
+                {
+                    isEnabled = true;
+                    break;
+                }
+            }
+            temp_addr = temp_addr->ifa_next;
+        }
+    }
+    freeifaddrs(interfaces);
+
+    return isEnabled;
+}
+
+static void onNotifyCallback(CFNotificationCenterRef center, void *observer, CFStringRef name,
+                                            const void *object, CFDictionaryRef userInfo)
+{
+    NSString* notifyName = (__bridge NSString*) name;
+    if ([notifyName isEqualToString:@"com.apple.system.config.network_change"]) {
+        NSDictionary *connectionDetails = [NSDictionary dictionary];
+        NSArray *myArray = (id) CNCopySupportedInterfaces();
+        if (myArray) {
+            CFDictionaryRef myDict = CNCopyCurrentNetworkInfo((__bridge CFStringRef)myArray[0]);
+            connectionDetails = (NSDictionary*)myDict;
+        }
+
+        NSString *apName = connectionDetails[@"SSID"];
+        if (apName == nil && !isCellulerDataEnabled())
+        {
+            OIC_LOG(INFO, TAG, "WiFi AP or Celluler Data is OFF!");
+            initialAPName = nil;
+            CAIpStateDisabled();
+        }
+        else if(![apName isEqualToString:initialAPName] || isCellulerDataEnabled())
+        {
+            initialAPName = apName;
+            OIC_LOG_V(INFO, TAG, "Current AP Name = %s", [initialAPName UTF8String]);
+            OIC_LOG_V(INFO, TAG, "Celluler Data Enabled = %d", isCellulerDataEnabled());
+            CAIpStateEnabled();
+        }
+    }
+}
index b4e840d..802e41a 100644 (file)
@@ -39,7 +39,7 @@
 #include <linux/rtnetlink.h>
 #endif
 
-#include "camutex.h"
+#include "octhread.h"
 #include "caipnwmonitor.h"
 #include "caadapterutils.h"
 #include "logger.h"
@@ -52,7 +52,7 @@
 /**
  * Mutex for synchronizing access to cached interface and IP address information.
  */
-static ca_mutex g_networkMonitorContextMutex = NULL;
+static oc_mutex g_networkMonitorContextMutex = NULL;
 
 /**
  * Used to storing network interface.
@@ -104,10 +104,10 @@ static CAResult_t CAIPInitializeNetworkMonitorList()
 {
     if (!g_networkMonitorContextMutex)
     {
-        g_networkMonitorContextMutex = ca_mutex_new();
+        g_networkMonitorContextMutex = oc_mutex_new();
         if (!g_networkMonitorContextMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
             return CA_STATUS_FAILED;
         }
     }
@@ -135,7 +135,7 @@ static void CAIPDestroyNetworkMonitorList()
 
     if (g_networkMonitorContextMutex)
     {
-        ca_mutex_free(g_networkMonitorContextMutex);
+        oc_mutex_free(g_networkMonitorContextMutex);
         g_networkMonitorContextMutex = NULL;
     }
 }
@@ -148,7 +148,7 @@ static bool CACmpNetworkList(uint32_t ifiindex)
         return false;
     }
 
-    ca_mutex_lock(g_networkMonitorContextMutex);
+    oc_mutex_lock(g_networkMonitorContextMutex);
 
     uint32_t list_length = u_arraylist_length(g_netInterfaceList);
     for (uint32_t list_index = 0; list_index < list_length; list_index++)
@@ -157,11 +157,11 @@ static bool CACmpNetworkList(uint32_t ifiindex)
                                                                     list_index);
         if (currItem->index == ifiindex)
         {
-            ca_mutex_unlock(g_networkMonitorContextMutex);
+            oc_mutex_unlock(g_networkMonitorContextMutex);
             return true;
         }
     }
-    ca_mutex_unlock(g_networkMonitorContextMutex);
+    oc_mutex_unlock(g_networkMonitorContextMutex);
     return false;
 }
 
@@ -170,15 +170,15 @@ static CAResult_t CAAddNetworkMonitorList(CAInterface_t *ifitem)
     VERIFY_NON_NULL(g_netInterfaceList, TAG, "g_netInterfaceList is NULL");
     VERIFY_NON_NULL(ifitem, TAG, "ifitem is NULL");
 
-    ca_mutex_lock(g_networkMonitorContextMutex);
+    oc_mutex_lock(g_networkMonitorContextMutex);
     bool result = u_arraylist_add(g_netInterfaceList, (void *) ifitem);
     if (!result)
     {
         OIC_LOG(ERROR, TAG, "u_arraylist_add failed.");
-        ca_mutex_unlock(g_networkMonitorContextMutex);
+        oc_mutex_unlock(g_networkMonitorContextMutex);
         return CA_STATUS_FAILED;
     }
-    ca_mutex_unlock(g_networkMonitorContextMutex);
+    oc_mutex_unlock(g_networkMonitorContextMutex);
     return CA_STATUS_OK;
 }
 
@@ -186,7 +186,7 @@ static void CARemoveNetworkMonitorList(int ifiindex)
 {
     VERIFY_NON_NULL_VOID(g_netInterfaceList, TAG, "g_netInterfaceList is NULL");
 
-    ca_mutex_lock(g_networkMonitorContextMutex);
+    oc_mutex_lock(g_networkMonitorContextMutex);
 
     uint32_t list_length = u_arraylist_length(g_netInterfaceList);
     for (uint32_t list_index = 0; list_index < list_length; list_index++)
@@ -198,13 +198,13 @@ static void CARemoveNetworkMonitorList(int ifiindex)
             if (u_arraylist_remove(g_netInterfaceList, list_index))
             {
                 OICFree(removedifitem);
-                ca_mutex_unlock(g_networkMonitorContextMutex);
+                oc_mutex_unlock(g_networkMonitorContextMutex);
                 return;
             }
             continue;
         }
     }
-    ca_mutex_unlock(g_networkMonitorContextMutex);
+    oc_mutex_unlock(g_networkMonitorContextMutex);
     return;
 }
 
@@ -238,6 +238,7 @@ static void CAIPPassNetworkChangesToAdapter(CANetworkStatus_t status)
         if (cbitem && cbitem->adapter)
         {
             cbitem->callback(cbitem->adapter, status);
+            CALogAdapterStateInfo(cbitem->adapter, status);
         }
     }
 }
@@ -470,11 +471,15 @@ u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex)
             OIC_LOG_V(DEBUG, TAG, "Added interface: %s (%d)", ifitem->name, ifitem->family);
         }
     }
+#ifndef __TIZENRT__
     freeifaddrs(ifp);
+#endif
     return iflist;
 
 exit:
+#ifndef __TIZENRT__
     freeifaddrs(ifp);
+#endif
     u_arraylist_destroy(iflist);
     return NULL;
 }
index 7d5d295..73f391c 100644 (file)
@@ -42,7 +42,7 @@
 #include <coap/utlist.h>
 
 #define TAG "OIC_CA_IP_MONITOR"
-
+#define MAX_INTERFACE_INFO_LENGTH (1024)
 #define NETLINK_MESSAGE_LENGTH  (4096)
 #define IFC_LABEL_LOOP          "lo"
 #define IFC_ADDR_LOOP_IPV4      "127.0.0.1"
@@ -167,20 +167,26 @@ u_arraylist_t *CAFindInterfaceChange()
         {
             continue;
         }
+
         struct ifinfomsg *ifi = (struct ifinfomsg *)NLMSG_DATA(nh);
         if (!ifi)
         {
             continue;
         }
 
-        int ifiIndex = ifi->ifi_index;
+        if (RTM_DELADDR == nh->nlmsg_type)
+        {
+            CloseMulticastSocket();
+        }
 
+        int ifiIndex = ifi->ifi_index;
         iflist = CAIPGetInterfaceInformation(ifiIndex);
         if (!iflist)
         {
             OIC_LOG_V(ERROR, TAG, "get interface info failed: %s", strerror(errno));
             return NULL;
         }
+        CreateMulticastSocket();
     }
     return iflist;
 }
index 0b06a1d..3fc370e 100644 (file)
@@ -20,7 +20,7 @@
 #include "canfcinterface.h"\r
 \r
 #include "caadapterutils.h"\r
-#include "camutex.h"\r
+#include "octhread.h"\r
 #include "oic_malloc.h"\r
 #include "oic_string.h"\r
 \r
index 4f8e57e..7f77e69 100644 (file)
@@ -19,7 +19,7 @@
 #include "canfcinterface.h"
 #include "caqueueingthread.h"
 #include "caadapterutils.h"
-#include "camutex.h"
+#include "octhread.h"
 #include "uarraylist.h"
 #include "caremotehandler.h"
 #include "logger.h"
@@ -67,8 +67,8 @@ static CAAdapterChangeCallback g_adapterStateCallback = NULL;
  */
 static CAErrorHandleCallback g_errorCallback = NULL;
 
-static void CANFCPacketReceivedCB(const CASecureEndpoint_t *endpoint, const void *data,
-                                  uint32_t dataLength);
+static CAResult_t CANFCPacketReceivedCB(const CASecureEndpoint_t *endpoint,
+                                        const void *data, uint32_t dataLength);
 #ifndef SINGLE_THREAD
 
 static CAResult_t CANFCInitializeQueueHandles();
@@ -137,17 +137,18 @@ void CANFCConnectionStateCB(const char *nfcAddress, CANetworkStatus_t status)
     (void)status;
 }
 
-void CANFCPacketReceivedCB(const CASecureEndpoint_t *sep, const void *data, uint32_t dataLength)
+CAResult_t CANFCPacketReceivedCB(const CASecureEndpoint_t *sep, const void *data,
+                                 uint32_t dataLength)
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
-    VERIFY_NON_NULL_VOID(sep, TAG, "endpoint is NULL");
-    VERIFY_NON_NULL_VOID(data, TAG, "data is NULL");
+    VERIFY_NON_NULL(sep, TAG, "endpoint is NULL");
+    VERIFY_NON_NULL(data, TAG, "data is NULL");
 
     if (0 == dataLength)
     {
         OIC_LOG(ERROR, TAG, "Invalid call, data length is 0");
-        return;
+        return CA_STATUS_FAILED;
     }
 
     OIC_LOG_V(DEBUG, TAG, "Address: %s, port:%d", sep->endpoint.addr, sep->endpoint.port);
@@ -158,6 +159,8 @@ void CANFCPacketReceivedCB(const CASecureEndpoint_t *sep, const void *data, uint
     }
 
     OIC_LOG(DEBUG, TAG, "OUT");
+
+    return CA_STATUS_OK;
 }
 
 void CANFCErrorHandler(const CAEndpoint_t *endpoint, const void *data, uint32_t dataLength,
index 905d2dd..11f56cb 100644 (file)
@@ -26,7 +26,7 @@
 #include <stdint.h>
 
 #include "caadapterutils.h"
-#include "camutex.h"
+#include "octhread.h"
 #include "uarraylist.h"
 #include "logger.h"
 #include "oic_malloc.h"
@@ -77,7 +77,7 @@ typedef struct
     CAJidBoundCallback jidBoundCallback;
 } CARAXmppData_t;
 
-static ca_mutex g_raadapterMutex = NULL;
+static oc_mutex g_raadapterMutex = NULL;
 
 static CARAXmppData_t g_xmppData = {.xmpp = NULL, .port = 5222, .hostName = {0},
     .password = {0}, .jid = {0}, .connectionStatus = CA_INTERFACE_DOWN,
@@ -451,14 +451,14 @@ CAResult_t CAStartRA()
         return CA_STATUS_FAILED;
     }
 
-    g_raadapterMutex = ca_mutex_new ();
+    g_raadapterMutex = oc_mutex_new ();
     if (!g_raadapterMutex)
     {
         OIC_LOG (ERROR, RA_ADAPTER_TAG, PCF("Memory allocation for mutex failed."));
         return CA_MEMORY_ALLOC_FAILED;
     }
 
-    ca_mutex_lock (g_raadapterMutex);
+    oc_mutex_lock (g_raadapterMutex);
 
     xmpphelper_connect(g_xmppData.xmpp, g_xmppData.hostName, g_xmppData.port,
                     g_xmppData.jid, g_xmppData.password);
@@ -471,7 +471,7 @@ CAResult_t CAStartRA()
 
     xmpphelper_run(g_xmppData.xmpp);
 
-    ca_mutex_unlock (g_raadapterMutex);
+    oc_mutex_unlock (g_raadapterMutex);
 
     OIC_LOG(DEBUG, RA_ADAPTER_TAG, "RA adapter started succesfully");
     return CA_STATUS_OK;
@@ -485,7 +485,7 @@ CAResult_t CAStopRA()
     xmpp_ibb_unregister(xmpphelper_get_conn(g_xmppData.xmpp));
     if (!g_raadapterMutex)
     {
-        ca_mutex_free (g_raadapterMutex);
+        oc_mutex_free (g_raadapterMutex);
         g_raadapterMutex = NULL;
     }
     OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Stopped RA adapter successfully"));
@@ -516,11 +516,11 @@ int32_t CASendRAUnicastData(const CAEndpoint_t *remoteEndpoint, const void *data
     int obsopt = CARAGetReqObsOption(pdu, remoteEndpoint);
     coap_delete_pdu(pdu);
 
-    ca_mutex_lock (g_raadapterMutex);
+    oc_mutex_lock (g_raadapterMutex);
     if (CA_INTERFACE_UP != g_xmppData.connectionStatus)
     {
         OIC_LOG(ERROR, RA_ADAPTER_TAG, "Unable to send XMPP message, RA not connected");
-        ca_mutex_unlock (g_raadapterMutex);
+        oc_mutex_unlock (g_raadapterMutex);
         return -1;
     }
 
@@ -531,7 +531,7 @@ int32_t CASendRAUnicastData(const CAEndpoint_t *remoteEndpoint, const void *data
         if (sess == NULL)
         {
             OIC_LOG(ERROR, RA_ADAPTER_TAG, "IBB session establish failed!");
-            ca_mutex_unlock (g_raadapterMutex);
+            oc_mutex_unlock (g_raadapterMutex);
             return -1;
         }
     }
@@ -544,7 +544,7 @@ int32_t CASendRAUnicastData(const CAEndpoint_t *remoteEndpoint, const void *data
     }
     xmppdata_t xdata = {.data = (char *) data, .size = dataLength};
     int rc = xmpp_ibb_send_data(sess, &xdata);
-    ca_mutex_unlock (g_raadapterMutex);
+    oc_mutex_unlock (g_raadapterMutex);
     if (rc < 0)
     {
         OIC_LOG(ERROR, RA_ADAPTER_TAG, "IBB send data failed!");
@@ -628,7 +628,7 @@ typedef struct
     char jabberID[CA_RAJABBERID_SIZE];
 } CARAXmppData_t;
 
-static ca_mutex g_raadapterMutex = NULL;
+static oc_mutex g_raadapterMutex = NULL;
 
 static CARAXmppData_t g_xmppData = {};
 
@@ -674,7 +674,7 @@ void CARAXmppConnectedCB(void * const param, xmpp_error_code_t result,
     {
         printf("\n\n\t\t===>your jid: %s\n\n", bound_jid);
 
-        ca_mutex_lock (g_raadapterMutex);
+        oc_mutex_lock (g_raadapterMutex);
         OICStrcpy (g_xmppData.jabberID, CA_RAJABBERID_SIZE, bound_jid);
 
         g_xmppData.connection_status = CA_INTERFACE_UP;
@@ -692,7 +692,7 @@ void CARAXmppConnectedCB(void * const param, xmpp_error_code_t result,
         OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "XMPP connected callback status: %d", result);
     }
 
-    ca_mutex_unlock (g_raadapterMutex);
+    oc_mutex_unlock (g_raadapterMutex);
     // Notify network change to CA
     CARANotifyNetworkChange(bound_jid, connection_status);
 
@@ -704,13 +704,13 @@ void CARAXmppDisonnectedCB(void * const param, xmpp_error_code_t result,
 {
     OIC_LOG(DEBUG, RA_ADAPTER_TAG, "CARAXmppDisonnectedCB IN");
     char jabberID[CA_RAJABBERID_SIZE];
-    ca_mutex_lock (g_raadapterMutex);
+    oc_mutex_lock (g_raadapterMutex);
 
     g_xmppData.connection_status = CA_INTERFACE_DOWN;
     xmpp_message_context_destroy(g_xmppData.message_context);
     OICStrcpy (jabberID, CA_RAJABBERID_SIZE, g_xmppData.jabberID);
 
-    ca_mutex_unlock (g_raadapterMutex);
+    oc_mutex_unlock (g_raadapterMutex);
 
     // Notify network change to CA
     CARANotifyNetworkChange(jabberID, CA_INTERFACE_DOWN);
@@ -824,14 +824,14 @@ CAResult_t CAStartRA()
 
     OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Starting RA adapter"));
 
-    g_raadapterMutex = ca_mutex_new ();
+    g_raadapterMutex = oc_mutex_new ();
     if (!g_raadapterMutex)
     {
         OIC_LOG (ERROR, RA_ADAPTER_TAG, PCF("Memory allocation for mutex failed."));
         return CA_MEMORY_ALLOC_FAILED;
     }
 
-    ca_mutex_lock (g_raadapterMutex);
+    oc_mutex_lock (g_raadapterMutex);
 
     xmpp_context_init(&g_xmppData.context);
     g_xmppData.handle = xmpp_startup(&g_xmppData.context);
@@ -848,7 +848,7 @@ CAResult_t CAStartRA()
     xmpp_identity_destroy(&g_xmppData.g_identity);
     xmpp_host_destroy(&g_xmppData.g_host);
 
-    ca_mutex_unlock (g_raadapterMutex);
+    oc_mutex_unlock (g_raadapterMutex);
 
     if (XMPP_ERR_OK != ret)
     {
@@ -875,7 +875,7 @@ CAResult_t CAStopRA()
 
     xmpp_shutdown_xmpp(g_xmppData.handle);
     xmpp_context_destroy(&g_xmppData.context);
-    ca_mutex_free (g_raadapterMutex);
+    oc_mutex_free (g_raadapterMutex);
     g_raadapterMutex = NULL;
 
     OIC_LOG(DEBUG, RA_ADAPTER_TAG, PCF("Stopped RA adapter successfully"));
@@ -899,12 +899,12 @@ int32_t CASendRAUnicastData(const CAEndpoint_t *remoteEndpoint, const void *data
     }
 
     OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "Sending unicast data to %s", remoteEndpoint->addr);
-    ca_mutex_lock (g_raadapterMutex);
+    oc_mutex_lock (g_raadapterMutex);
 
     if (CA_INTERFACE_UP != g_xmppData.connection_status)
     {
         OIC_LOG(ERROR, RA_ADAPTER_TAG, "Unable to send XMPP message, RA not connected");
-        ca_mutex_unlock (g_raadapterMutex);
+        oc_mutex_unlock (g_raadapterMutex);
         return -1;
     }
 
@@ -914,10 +914,10 @@ int32_t CASendRAUnicastData(const CAEndpoint_t *remoteEndpoint, const void *data
     if (XMPP_ERR_OK != res)
     {
         OIC_LOG_V(ERROR, RA_ADAPTER_TAG, "Unable to send XMPP message, status: %d", res);
-        ca_mutex_unlock (g_raadapterMutex);
+        oc_mutex_unlock (g_raadapterMutex);
         return -1;
     }
-    ca_mutex_unlock (g_raadapterMutex);
+    oc_mutex_unlock (g_raadapterMutex);
 
     OIC_LOG_V(INFO, RA_ADAPTER_TAG, "Successfully dispatched bytes[%d] to addr[%s]",
             dataLength, remoteEndpoint->addr);
@@ -930,16 +930,16 @@ CAResult_t CAGetRAInterfaceInformation(CAEndpoint_t **info, uint32_t *size)
     VERIFY_NON_NULL(info, RA_ADAPTER_TAG, "info is NULL");
     VERIFY_NON_NULL(size, RA_ADAPTER_TAG, "size is NULL");
 
-    ca_mutex_lock (g_raadapterMutex);
+    oc_mutex_lock (g_raadapterMutex);
 
     if (CA_INTERFACE_UP != g_xmppData.connection_status)
     {
         OIC_LOG(ERROR, RA_ADAPTER_TAG, "Failed to get interface info, RA not Connected");
-        ca_mutex_unlock (g_raadapterMutex);
+        oc_mutex_unlock (g_raadapterMutex);
         return CA_ADAPTER_NOT_ENABLED;
     }
 
-    ca_mutex_unlock (g_raadapterMutex);
+    oc_mutex_unlock (g_raadapterMutex);
 
     CAEndpoint_t *localEndpoint = CACreateEndpointObject(CA_DEFAULT_FLAGS,
                                  CA_ADAPTER_REMOTE_ACCESS,
index d031447..a1b8806 100644 (file)
@@ -15,7 +15,7 @@ src_dir = './tcp_adapter/'
 
 # Source files to build common for all platforms
 common_files = None
-if target_os in ['linux', 'tizen', 'android', 'ios']:
+if target_os in ['linux', 'tizen', 'android', 'ios', 'tizenrt']:
     common_files = [
         os.path.join(src_dir, 'catcpadapter.c'),
         os.path.join(src_dir, 'catcpserver.c') ]
index e86aabb..6e6404e 100644 (file)
@@ -31,7 +31,7 @@
 #include "catcpinterface.h"
 #include <coap/pdu.h>
 #include "caadapterutils.h"
-#include "camutex.h"
+#include "octhread.h"
 #include "oic_malloc.h"
 #include "oic_string.h"
 
old mode 100755 (executable)
new mode 100644 (file)
index b08d3c0..67905f6
@@ -34,7 +34,7 @@
 #include "catcpinterface.h"
 #include "caqueueingthread.h"
 #include "caadapterutils.h"
-#include "camutex.h"
+#include "octhread.h"
 #include "uarraylist.h"
 #include "caremotehandler.h"
 #include "logger.h"
@@ -88,17 +88,17 @@ static CAConnectionChangeCallback g_connectionChangeCallback = NULL;
  */
 static CAErrorHandleCallback g_errorCallback = NULL;
 
-static void CATCPPacketReceivedCB(const CASecureEndpoint_t *sep,
-                                  const void *data, uint32_t dataLength);
-
-static void CATCPErrorHandler(const CAEndpoint_t *endpoint, const void *data,
-                              size_t dataLength, CAResult_t result);
-
 /**
  * KeepAlive Connected or Disconnected Callback to CA adapter.
  */
 static CAKeepAliveConnectionCallback g_connKeepAliveCallback = NULL;
 
+static CAResult_t CATCPPacketReceivedCB(const CASecureEndpoint_t *sep,
+                                        const void *data, uint32_t dataLength);
+
+static void CATCPErrorHandler(const CAEndpoint_t *endpoint, const void *data,
+                              size_t dataLength, CAResult_t result);
+
 static CAResult_t CATCPInitializeQueueHandles();
 
 static void CATCPDeinitializeQueueHandles();
@@ -155,18 +155,23 @@ void CATCPConnectionStateCB(const char *ipAddress, CANetworkStatus_t status)
     (void)status;
 }
 
-void CATCPPacketReceivedCB(const CASecureEndpoint_t *sep, const void *data,
-                           uint32_t dataLength)
+CAResult_t CATCPPacketReceivedCB(const CASecureEndpoint_t *sep, const void *data,
+                                 uint32_t dataLength)
 {
-    VERIFY_NON_NULL_VOID(sep, TAG, "sep is NULL");
-    VERIFY_NON_NULL_VOID(data, TAG, "data is NULL");
+    VERIFY_NON_NULL(sep, TAG, "sep is NULL");
+    VERIFY_NON_NULL(data, TAG, "data is NULL");
 
     OIC_LOG_V(DEBUG, TAG, "Address: %s, port:%d", sep->endpoint.addr, sep->endpoint.port);
 
+    CAResult_t res = CA_STATUS_OK;
 #ifdef SINGLE_THREAD
     if (g_networkPacketCallback)
     {
-        g_networkPacketCallback(sep, data, dataLength);
+        res = g_networkPacketCallback(sep, data, dataLength);
+        if (CA_STATUS_OK != res)
+        {
+            OIC_LOG(ERROR, TAG, "Error parsing CoAP data");
+        }
     }
 #else
     unsigned char *buffer = (unsigned char*)data;
@@ -178,22 +183,22 @@ void CATCPPacketReceivedCB(const CASecureEndpoint_t *sep, const void *data,
     if (!svritem)
     {
         OIC_LOG(ERROR, TAG, "there is no connection information in list");
-        return;
+        return CA_STATUS_INVALID_PARAM;
     }
     if (UNKNOWN == svritem->protocol)
     {
         OIC_LOG(ERROR, TAG, "invalid protocol type");
-        return;
+        return CA_STATUS_INVALID_PARAM;
     }
 
     //totalLen filled only when header fully read and parsed
     while (0 != bufferLen)
     {
-        CAResult_t res = CAConstructCoAP(svritem, &buffer, &bufferLen);
+        res = CAConstructCoAP(svritem, &buffer, &bufferLen);
         if (CA_STATUS_OK != res)
         {
             OIC_LOG_V(ERROR, TAG, "CAConstructCoAP return error : %d", res);
-            return;
+            return res;
         }
 
         //when successfully read all required data - pass them to upper layer.
@@ -201,7 +206,12 @@ void CATCPPacketReceivedCB(const CASecureEndpoint_t *sep, const void *data,
         {
             if (g_networkPacketCallback)
             {
-                g_networkPacketCallback(sep, svritem->data, svritem->totalLen);
+                res = g_networkPacketCallback(sep, svritem->data, svritem->totalLen);
+                if (CA_STATUS_OK != res)
+                {
+                    OIC_LOG(ERROR, TAG, "Error parsing CoAP data");
+                    return res;
+                }
             }
             CACleanData(svritem);
         }
@@ -212,6 +222,7 @@ void CATCPPacketReceivedCB(const CASecureEndpoint_t *sep, const void *data,
         }
     }
 #endif
+    return res;
 }
 
 #ifdef __WITH_TLS__
@@ -242,12 +253,12 @@ static void CATCPErrorHandler(const CAEndpoint_t *endpoint, const void *data,
     }
 }
 
-static void CATCPConnectionHandler(const CAEndpoint_t *endpoint, bool isConnected)
+static void CATCPConnectionHandler(const CAEndpoint_t *endpoint, bool isConnected, bool isClient)
 {
     // Pass the changed connection status to RI Layer for keepalive.
     if (g_connKeepAliveCallback)
     {
-        g_connKeepAliveCallback(endpoint, isConnected);
+        g_connKeepAliveCallback(endpoint, isConnected, isClient);
     }
 
     // Pass the changed connection status to CAUtil.
@@ -271,12 +282,19 @@ void CATCPAdapterHandler(CATransportAdapter_t adapter, CANetworkStatus_t status)
 
     if (CA_INTERFACE_DOWN == status)
     {
-        OIC_LOG(DEBUG, TAG, "Network status is down, close all session");
+        OIC_LOG(INFO, TAG, "Network status is down, close all session");
+
+        CAResult_t res = CAQueueingThreadClearData(g_sendQueueHandle);
+        if (res != CA_STATUS_OK)
+        {
+            OIC_LOG_V(ERROR, TAG, "CAQueueingThreadClearData failed[%d]", res);
+        }
+
         CATCPStopServer();
     }
     else if (CA_INTERFACE_UP == status)
     {
-        OIC_LOG(DEBUG, TAG, "Network status is up, create new socket for listening");
+        OIC_LOG(INFO, TAG, "Network status is up, create new socket for listening");
 
         CAResult_t ret = CA_STATUS_FAILED;
 #ifndef SINGLE_THREAD
@@ -286,7 +304,7 @@ void CATCPAdapterHandler(CATransportAdapter_t adapter, CANetworkStatus_t status)
 #endif
         if (CA_STATUS_OK != ret)
         {
-            OIC_LOG_V(DEBUG, TAG, "CATCPStartServer failed[%d]", ret);
+            OIC_LOG_V(ERROR, TAG, "CATCPStartServer failed[%d]", ret);
         }
     }
 }
@@ -342,6 +360,20 @@ CAResult_t CAInitializeTCP(CARegisterConnectivityCallback registerCallback,
     g_errorCallback = errorCallback;
 
     CAInitializeTCPGlobals();
+
+    CAResult_t res = CATCPCreateMutex();
+    if (CA_STATUS_OK == res)
+    {
+        res = CATCPCreateCond();
+    }
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "failed to create mutex/cond");
+        CATCPDestroyMutex();
+        CATCPDestroyCond();
+        return res;
+    }
+
 #ifndef SINGLE_THREAD
     caglobals.tcp.threadpool = handle;
 #endif
@@ -351,14 +383,7 @@ CAResult_t CAInitializeTCP(CARegisterConnectivityCallback registerCallback,
     CATCPSetErrorHandler(CATCPErrorHandler);
 
 #ifdef __WITH_TLS__
-    if (CA_STATUS_OK != CAinitSslAdapter())
-    {
-        OIC_LOG(ERROR, TAG, "Failed to init SSL adapter");
-    }
-    else
-    {
-        CAsetSslAdapterCallbacks(CATCPPacketReceivedCB, CATCPPacketSendCB, CA_ADAPTER_TCP);
-    }
+    CAsetSslAdapterCallbacks(CATCPPacketReceivedCB, CATCPPacketSendCB, CA_ADAPTER_TCP);
 #endif
 
     CAConnectivityHandler_t tcpHandler = {
@@ -384,9 +409,6 @@ CAResult_t CAStartTCP()
 {
     OIC_LOG(DEBUG, TAG, "IN");
 
-    // Start network monitoring to receive adapter status changes.
-    CAIPStartNetworkMonitor(CATCPAdapterHandler, CA_ADAPTER_TCP);
-
 #ifndef SINGLE_THREAD
     if (CA_STATUS_OK != CATCPInitializeQueueHandles())
     {
@@ -396,7 +418,11 @@ CAResult_t CAStartTCP()
     }
 
     // Start send queue thread
+#ifndef __TIZENRT__
     if (CA_STATUS_OK != CAQueueingThreadStart(g_sendQueueHandle))
+#else
+    if (CA_STATUS_OK != CAQueueingThreadStart(g_sendQueueHandle, "IoT_TCPSendQueue"))
+#endif
     {
         OIC_LOG(ERROR, TAG, "Failed to Start Send Data Thread");
         return CA_STATUS_FAILED;
@@ -410,9 +436,55 @@ CAResult_t CAStartTCP()
     }
 #endif
 
+    // Start network monitoring to receive adapter status changes.
+    CAIPStartNetworkMonitor(CATCPAdapterHandler, CA_ADAPTER_TCP);
+
     return CA_STATUS_OK;
 }
 
+static bool CAClearQueueEndpointDataContext(void *data, uint32_t size, void *ctx)
+{
+    if (NULL == data || NULL == ctx)
+    {
+        return false;
+    }
+
+    CATCPData *tcpData = (CATCPData *)data;
+    CAEndpoint_t *endpoint = (CAEndpoint_t *)ctx;
+
+    if (NULL != tcpData && NULL != tcpData->remoteEndpoint)
+    {
+        if (strcmp(tcpData->remoteEndpoint->addr, endpoint->addr) == 0
+            && tcpData->remoteEndpoint->port == endpoint->port)
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
+CAResult_t CATCPDisconnectSession(const CAEndpoint_t *endpoint)
+{
+    CAResult_t res = CA_STATUS_OK;
+#ifdef __WITH_TLS__
+    res = CAcloseSslConnection(endpoint);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "failed to close TLS session");
+        return res;
+    }
+#endif
+    res = CASearchAndDeleteTCPSession(endpoint);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "failed to close TCP session");
+    }
+    res = CAQueueingThreadClearContextData(g_sendQueueHandle,
+                                           CAClearQueueEndpointDataContext,
+                                           endpoint);
+    return res;
+}
+
 CAResult_t CAStartTCPListeningServer()
 {
 #ifndef SINGLE_THREAD
@@ -528,17 +600,15 @@ CAResult_t CAStopTCP()
     //Re-initializing the Globals to start them again
     CAInitializeTCPGlobals();
 
-#ifdef __WITH_TLS__
-    CAdeinitSslAdapter();
-#endif
-
     return CA_STATUS_OK;
 }
 
 void CATerminateTCP()
 {
-    CAStopTCP();
     CATCPSetPacketReceiveCallback(NULL);
+
+    CATCPDestroyMutex();
+    CATCPDestroyCond();
 }
 
 void CATCPSendDataThread(void *threadData)
@@ -566,40 +636,24 @@ void CATCPSendDataThread(void *threadData)
     }
     else
     {
-        // Check payload length from CoAP over TCP format header.
-        CAResult_t result = CA_STATUS_OK;
-        size_t payloadLen = CACheckPayloadLengthFromHeader(tcpData->data, tcpData->dataLen);
-        if (!payloadLen)
-        {
-            // if payload length is zero, disconnect from remote device.
-            OIC_LOG(DEBUG, TAG, "payload length is zero, disconnect from remote device");
 #ifdef __WITH_TLS__
-            if (CA_STATUS_OK != CAcloseSslConnection(tcpData->remoteEndpoint))
+        if (tcpData->remoteEndpoint && tcpData->remoteEndpoint->flags & CA_SECURE)
+        {
+            CAResult_t result = CA_STATUS_OK;
+            OIC_LOG(DEBUG, TAG, "CAencryptSsl called!");
+            result = CAencryptSsl(tcpData->remoteEndpoint, tcpData->data, tcpData->dataLen);
+
+            if (CA_STATUS_OK != result)
             {
-                OIC_LOG(ERROR, TAG, "Failed to close TLS session");
+                OIC_LOG(ERROR, TAG, "CAAdapterNetDtlsEncrypt failed!");
+                CASearchAndDeleteTCPSession(tcpData->remoteEndpoint);
+                CATCPErrorHandler(tcpData->remoteEndpoint, tcpData->data, tcpData->dataLen,
+                                  CA_SEND_FAILED);
             }
-#endif
-            CASearchAndDeleteTCPSession(tcpData->remoteEndpoint);
+            OIC_LOG_V(DEBUG, TAG,
+                      "CAAdapterNetDtlsEncrypt returned with result[%d]", result);
             return;
         }
-
-#ifdef __WITH_TLS__
-         if (tcpData->remoteEndpoint && tcpData->remoteEndpoint->flags & CA_SECURE)
-         {
-             OIC_LOG(DEBUG, TAG, "CAencryptSsl called!");
-             result = CAencryptSsl(tcpData->remoteEndpoint, tcpData->data, tcpData->dataLen);
-
-             if (CA_STATUS_OK != result)
-             {
-                 OIC_LOG(ERROR, TAG, "CAAdapterNetDtlsEncrypt failed!");
-                 CASearchAndDeleteTCPSession(tcpData->remoteEndpoint);
-                 CATCPErrorHandler(tcpData->remoteEndpoint, tcpData->data, tcpData->dataLen,
-                                   CA_SEND_FAILED);
-             }
-             OIC_LOG_V(DEBUG, TAG,
-                       "CAAdapterNetDtlsEncrypt returned with result[%d]", result);
-            return;
-         }
 #endif
         //Processing for sending unicast
          ssize_t dlen = CATCPSendData(tcpData->remoteEndpoint, tcpData->data, tcpData->dataLen);
@@ -656,7 +710,9 @@ void CADataDestroyer(void *data, uint32_t size)
 {
     if (size < sizeof(CATCPData))
     {
+#ifndef __TIZENRT__
         OIC_LOG_V(ERROR, TAG, "Destroy data too small %p %" PRIu32, data, size);
+#endif
     }
     CATCPData *TCPData = (CATCPData *) data;
 
index e2f6461..16ed703 100644 (file)
 #include <sys/socket.h>
 #include <sys/select.h>
 #include <sys/ioctl.h>
+#ifdef __TIZENRT__
+#include <tinyara/config.h>
+#include <poll.h>
+#else
 #include <sys/poll.h>
+#endif
 #include <stdio.h>
 #include <unistd.h>
 #include <fcntl.h>
@@ -41,7 +46,7 @@
 #include "caipnwmonitor.h"
 #include <coap/pdu.h>
 #include "caadapterutils.h"
-#include "camutex.h"
+#include "octhread.h"
 #include "oic_malloc.h"
 
 #ifdef __WITH_TLS__
@@ -51,7 +56,8 @@
 /**
  * Logging tag for module name.
  */
-#define TAG "OIC_CA_TCP_SERVER"
+//#define TAG "OIC_CA_TCP_SERVER"
+#define TAG TCP_SERVER_TAG
 
 /**
  * Maximum CoAP over TCP header length
 #define TLS_HEADER_SIZE 5
 
 /**
+ * Max Connection Counts.
+ */
+#define MAX_CONNECTION_COUNTS   500
+
+/**
+ * Thread pool.
+ */
+static ca_thread_pool_t g_threadPool = NULL;
+
+/**
+ * An unique identifier of receive thread.
+ */
+static uint32_t g_recvThreadId = 0;
+
+/**
  * Mutex to synchronize device object list.
  */
-static ca_mutex g_mutexObjectList = NULL;
+static oc_mutex g_mutexObjectList = NULL;
 
 /**
  * Conditional mutex to synchronize.
  */
-static ca_cond g_condObjectList = NULL;
+static oc_cond g_condObjectList = NULL;
 
 /**
  * Maintains the callback to be notified when data received from remote device.
@@ -89,10 +110,6 @@ static CATCPErrorHandleCallback g_tcpErrorHandler = NULL;
  */
 static CATCPConnectionHandleCallback g_connectionCallback = NULL;
 
-static CAResult_t CATCPCreateMutex();
-static void CATCPDestroyMutex();
-static CAResult_t CATCPCreateCond();
-static void CATCPDestroyCond();
 static CASocketFd_t CACreateAcceptSocket(int family, CASocket_t *sock);
 static void CAAcceptConnection(CATransportFlags_t flag, CASocket_t *sock);
 static void CAFindReadyMessage();
@@ -100,6 +117,7 @@ static void CASelectReturned(fd_set *readFds);
 static void CAReceiveMessage(int fd);
 static void CAReceiveHandler(void *data);
 static CAResult_t CATCPCreateSocket(int family, CATCPSessionInfo_t *svritem);
+static void CATCPInitializeSocket();
 
 #define CHECKFD(FD) \
     if (FD > caglobals.tcp.maxfd) \
@@ -118,67 +136,20 @@ static CAResult_t CATCPCreateSocket(int family, CATCPSessionInfo_t *svritem);
         FD_SET(caglobals.tcp.TYPE.fd, FDS); \
     }
 
-/**
- * Read length amount of data from socket item->fd
- * Can read less data length then requested
- * Actual read length added to item->len variable
- *
- * @param[in/out] item - used socket, buffer and to update received message length
- * @param[in]  length  - length of data required to read
- * @param[in]  flags   - additional info about socket
- * @return             - CA_STATUS_OK or appropriate error code
- */
-static CAResult_t CARecv(CATCPSessionInfo_t *item, size_t length, int flags)
-{
-    if (NULL == item)
-    {
-        return CA_STATUS_INVALID_PARAM;
-    }
-
-    //skip read operation if requested zero length
-    if (0 == length)
-    {
-        return CA_STATUS_OK;
-    }
-
-    unsigned char *buffer = item->data + item->len;
-
-    int len = recv(item->fd, buffer, length, flags);
-
-    if (len < 0)
-    {
-        OIC_LOG_V(ERROR, TAG, "recv failed %s", strerror(errno));
-        return CA_RECEIVE_FAILED;
-    }
-    else if (0 == len)
-    {
-        OIC_LOG(INFO, TAG, "Received disconnect from peer. Close connection");
-        item->state = DISCONNECTED;
-        return CA_DESTINATION_DISCONNECTED;
-    }
-
-    OIC_LOG_V(DEBUG, TAG, "recv len = %d", len);
-    OIC_LOG_BUFFER(DEBUG, TAG, buffer, len);
-
-    item->len += len;
-
-    return CA_STATUS_OK;
-}
-
-static void CATCPDestroyMutex()
+void CATCPDestroyMutex()
 {
     if (g_mutexObjectList)
     {
-        ca_mutex_free(g_mutexObjectList);
+        oc_mutex_free(g_mutexObjectList);
         g_mutexObjectList = NULL;
     }
 }
 
-static CAResult_t CATCPCreateMutex()
+CAResult_t CATCPCreateMutex()
 {
     if (!g_mutexObjectList)
     {
-        g_mutexObjectList = ca_mutex_new();
+        g_mutexObjectList = oc_mutex_new();
         if (!g_mutexObjectList)
         {
             OIC_LOG(ERROR, TAG, "Failed to created mutex!");
@@ -189,20 +160,20 @@ static CAResult_t CATCPCreateMutex()
     return CA_STATUS_OK;
 }
 
-static void CATCPDestroyCond()
+void CATCPDestroyCond()
 {
     if (g_condObjectList)
     {
-        ca_cond_free(g_condObjectList);
+        oc_cond_free(g_condObjectList);
         g_condObjectList = NULL;
     }
 }
 
-static CAResult_t CATCPCreateCond()
+CAResult_t CATCPCreateCond()
 {
     if (!g_condObjectList)
     {
-        g_condObjectList = ca_cond_new();
+        g_condObjectList = oc_cond_new();
         if (!g_condObjectList)
         {
             OIC_LOG(ERROR, TAG, "Failed to created cond!");
@@ -222,9 +193,9 @@ static void CAReceiveHandler(void *data)
         CAFindReadyMessage();
     }
 
-    ca_mutex_lock(g_mutexObjectList);
-    ca_cond_signal(g_condObjectList);
-    ca_mutex_unlock(g_mutexObjectList);
+    oc_mutex_lock(g_mutexObjectList);
+    oc_cond_signal(g_condObjectList);
+    oc_mutex_unlock(g_mutexObjectList);
 
     OIC_LOG(DEBUG, TAG, "OUT - CAReceiveHandler");
 }
@@ -239,11 +210,12 @@ static void CAFindReadyMessage()
     CA_FD_SET(ipv4s, &readFds);
     CA_FD_SET(ipv6, &readFds);
     CA_FD_SET(ipv6s, &readFds);
-
+#ifndef __TIZENRT__
     if (OC_INVALID_SOCKET != caglobals.tcp.shutdownFds[0])
     {
         FD_SET(caglobals.tcp.shutdownFds[0], &readFds);
     }
+#endif
     if (OC_INVALID_SOCKET != caglobals.tcp.connectionFds[0])
     {
         FD_SET(caglobals.tcp.connectionFds[0], &readFds);
@@ -264,18 +236,19 @@ static void CAFindReadyMessage()
 
     if (caglobals.tcp.terminate)
     {
-        OIC_LOG_V(DEBUG, TAG, "Packet receiver Stop request received.");
+        OIC_LOG_V(INFO, TAG, "Packet receiver Stop request received.");
         return;
     }
-
-    if (0 < ret)
-    {
-        CASelectReturned(&readFds);
-    }
-    else if (0 > ret)
+    if (0 >= ret)
     {
-        OIC_LOG_V(FATAL, TAG, "select error %s", strerror(errno));
+        if (0 > ret)
+        {
+            OIC_LOG_V(FATAL, TAG, "select error %s", strerror(errno));
+        }
+        return;
     }
+
+    CASelectReturned(&readFds);
 }
 
 static void CASelectReturned(fd_set *readFds)
@@ -314,7 +287,6 @@ static void CASelectReturned(fd_set *readFds)
             return;
         }
         OIC_LOG_V(DEBUG, TAG, "Received new connection event with [%s]", buf);
-        FD_CLR(caglobals.tcp.connectionFds[0], readFds);
         return;
     }
     else
@@ -329,10 +301,6 @@ static void CASelectReturned(fd_set *readFds)
                 if (FD_ISSET(svritem->fd, readFds))
                 {
                     CAReceiveMessage(svritem->fd);
-                    if (-1 != svritem->fd)
-                    {
-                        FD_CLR(svritem->fd, readFds);
-                    }
                 }
             }
         }
@@ -341,8 +309,17 @@ static void CASelectReturned(fd_set *readFds)
 
 static void CAAcceptConnection(CATransportFlags_t flag, CASocket_t *sock)
 {
+    OIC_LOG_V(INFO, TAG, "In %s", __func__);
     VERIFY_NON_NULL_VOID(sock, TAG, "sock is NULL");
 
+    if (MAX_CONNECTION_COUNTS == u_arraylist_length(caglobals.tcp.svrlist))
+    {
+        OIC_LOG_V(INFO, TAG, "Exceeding the max connection counts limit, close listening port");
+        close(sock->fd);
+        sock->fd = OC_INVALID_SOCKET;
+        return;
+    }
+
     struct sockaddr_storage clientaddr;
     socklen_t clientlen = sizeof (struct sockaddr_in);
     if (flag & CA_IPV6)
@@ -366,58 +343,32 @@ static void CAAcceptConnection(CATransportFlags_t flag, CASocket_t *sock)
         svritem->sep.endpoint.flags = flag;
         svritem->sep.endpoint.adapter = CA_ADAPTER_TCP;
         svritem->state = CONNECTED;
+        svritem->isClient = false;
         CAConvertAddrToName((struct sockaddr_storage *)&clientaddr, clientlen,
                             svritem->sep.endpoint.addr, &svritem->sep.endpoint.port);
 
-        ca_mutex_lock(g_mutexObjectList);
+        oc_mutex_lock(g_mutexObjectList);
         bool result = u_arraylist_add(caglobals.tcp.svrlist, svritem);
         if (!result)
         {
             OIC_LOG(ERROR, TAG, "u_arraylist_add failed.");
             close(sockfd);
             OICFree(svritem);
-            ca_mutex_unlock(g_mutexObjectList);
+            oc_mutex_unlock(g_mutexObjectList);
             return;
         }
-        ca_mutex_unlock(g_mutexObjectList);
+        oc_mutex_unlock(g_mutexObjectList);
 
         CHECKFD(sockfd);
 
         // pass the connection information to CA Common Layer.
         if (g_connectionCallback)
         {
-            g_connectionCallback(&(svritem->sep.endpoint), true);
-        }
-    }
-}
-
-#ifdef __WITH_TLS__
-static bool CAIsTlsMessage(const unsigned char* data, size_t length)
-{
-    if (NULL == data || 0 == length)
-    {
-        OIC_LOG_V(ERROR, TAG, "%s: null input param", __func__);
-        return false;
-    }
-
-    unsigned char first_byte = data[0];
-
-    //TLS Plaintext has four types: change_cipher_spec = [14], alert = [15],
-    //handshake = [16], application_data = [17] in HEX
-    const uint8_t tls_head_type[] = {0x14, 0x15, 0x16, 0x17};
-    size_t i = 0;
-
-    for (i = 0; i < sizeof(tls_head_type); i++)
-    {
-        if(tls_head_type[i] == first_byte)
-        {
-            return true;
+            g_connectionCallback(&(svritem->sep.endpoint), true, svritem->isClient);
         }
     }
-
-    return false;
+    OIC_LOG_V(INFO, TAG, "Out %s", __func__);
 }
-#endif
 
 /**
  * Clean socket state data
@@ -431,7 +382,9 @@ void CACleanData(CATCPSessionInfo_t *svritem)
         OICFree(svritem->data);
         svritem->data = NULL;
         svritem->len = 0;
+#ifdef __WITH_TLS__
         svritem->tlsLen = 0;
+#endif
         svritem->totalLen = 0;
         svritem->protocol = UNKNOWN;
     }
@@ -553,161 +506,6 @@ CAResult_t CAConstructCoAP(CATCPSessionInfo_t *svritem, unsigned char **data,
     return CA_STATUS_OK;
 }
 
-/**
- * Read message header from socket item->fd
- *
- * @param[in/out] item - used socket, buffer, current received message length and protocol
- * @return             - CA_STATUS_OK or appropriate error code
- */
-static CAResult_t CAReadHeader(CATCPSessionInfo_t *svritem)
-{
-    CAResult_t res = CA_STATUS_OK;
-
-    if (NULL == svritem)
-    {
-        return CA_STATUS_INVALID_PARAM;
-    }
-
-    if (NULL == svritem->data)
-    {
-        // allocate memory for message header (CoAP header size because it is bigger)
-        svritem->data = (unsigned char *) OICCalloc(1, COAP_MAX_HEADER_SIZE);
-        if (NULL == svritem->data)
-        {
-            OIC_LOG(ERROR, TAG, "OICCalloc - out of memory");
-            return CA_MEMORY_ALLOC_FAILED;
-        }
-    }
-
-    //read data (assume TLS header) from remote device.
-    //use TLS_HEADER_SIZE - svritem->len because even header can be read partially
-    res = CARecv(svritem, TLS_HEADER_SIZE - svritem->len, 0);
-
-    //return if any error occurs
-    if (CA_STATUS_OK != res)
-    {
-        return res;
-    }
-
-    //if not enough data received - read them on next CAReceiveMessage() call
-    if (svritem->len < TLS_HEADER_SIZE)
-    {
-        OIC_LOG(DEBUG, TAG, "Header received partially. Wait for rest header data");
-        return CA_STATUS_OK;
-    }
-
-    //if enough data received - parse header
-#ifdef __WITH_TLS__
-    if (CAIsTlsMessage(svritem->data, svritem->len))
-    {
-        svritem->protocol = TLS;
-
-        //[3][4] bytes in tls header are tls payload length
-        unsigned int message_length = (unsigned int)((svritem->data[3] << 8) | svritem->data[4]);
-        OIC_LOG_V(DEBUG, TAG, "%s: message_length = %d", __func__, message_length);
-
-        svritem->totalLen = message_length + TLS_HEADER_SIZE;
-    }
-    else
-#endif
-    {
-        svritem->protocol = COAP;
-
-        //seems CoAP data received. read full coap header.
-        coap_transport_t transport = coap_get_tcp_header_type_from_initbyte(svritem->data[0] >> 4);
-
-        size_t headerLen = coap_get_tcp_header_length_for_transport(transport);
-
-        if (svritem->len < headerLen)
-        {
-            //read required bytes to have full CoAP header
-            //it should be 1 byte (COAP_MAX_HEADER_SIZE - TLS_HEADER_SIZE)
-            res = CARecv(svritem, headerLen - svritem->len, 0);
-
-            //return if any error occurs
-            if (CA_STATUS_OK != res)
-            {
-                return res;
-            }
-
-            //if not enough data received - read them on next CAReceiveMessage() call
-            if (svritem->len < headerLen)
-            {
-                OIC_LOG(DEBUG, TAG, "CoAP header received partially. Wait for rest header data");
-                return CA_STATUS_OK;
-            }
-        }
-
-        //calculate CoAP message length
-        svritem->totalLen = CAGetTotalLengthFromHeader(svritem->data);
-    }
-
-    unsigned char *buffer = OICRealloc(svritem->data, svritem->totalLen);
-    if (NULL == buffer)
-    {
-        OIC_LOG(ERROR, TAG, "OICRealloc - out of memory");
-        return CA_MEMORY_ALLOC_FAILED;
-    }
-    svritem->data = buffer;
-
-    return CA_STATUS_OK;
-}
-
-/**
- * Read message payload from socket item->fd
-
- *
- * @param[in/out] item - used socket, buffer and to update received message length
- * @return             - CA_STATUS_OK or appropriate error code
- */
-static CAResult_t CAReadPayload(CATCPSessionInfo_t *svritem)
-{
-    if (NULL == svritem)
-    {
-        return CA_STATUS_INVALID_PARAM;
-    }
-
-    return CARecv(svritem, svritem->totalLen - svritem->len, 0);
-}
-
-/**
- * Pass received data to app layer depending on protocol
- *
- * @param[in/out] item - used buffer, received message length and protocol
- */
-static void CAExecuteRequest(CATCPSessionInfo_t *svritem)
-{
-    if (NULL == svritem)
-    {
-        return;
-    }
-
-    switch(svritem->protocol)
-    {
-        case COAP:
-        {
-            if (g_packetReceivedCallback)
-            {
-                g_packetReceivedCallback(&svritem->sep, svritem->data, svritem->len);
-            }
-        }
-        break;
-        case TLS:
-#ifdef __WITH_TLS__
-        {
-            int ret = CAdecryptSsl(&svritem->sep, (uint8_t *)svritem->data, svritem->len);
-
-            OIC_LOG_V(DEBUG, TAG, "%s: CAdecryptSsl returned %d", __func__, ret);
-        }
-        break;
-#endif
-        case UNKNOWN: /* pass through */
-        default:
-            OIC_LOG(ERROR, TAG, "unknown application protocol. Ignore it");
-        break;
-    }
-}
-
 static void CAReceiveMessage(int fd)
 {
     CAResult_t res = CA_STATUS_OK;
@@ -741,11 +539,16 @@ static void CAReceiveMessage(int fd)
             //[3][4] bytes in tls header are tls payload length
             tlsLength = TLS_HEADER_SIZE +
                             (size_t)((svritem->tlsdata[3] << 8) | svritem->tlsdata[4]);
-            OIC_LOG_V(DEBUG, TAG, "toal tls length = %u", tlsLength);
+            OIC_LOG_V(DEBUG, TAG, "total tls length = %u", tlsLength);
             if (tlsLength > sizeof(svritem->tlsdata))
             {
-                OIC_LOG_V(ERROR, TAG, "toal tls length is too big (buffer size : %u)",
+                OIC_LOG_V(ERROR, TAG, "total tls length is too big (buffer size : %u)",
                                     sizeof(svritem->tlsdata));
+                if (CA_STATUS_OK != CAcloseSslConnection(&svritem->sep.endpoint))
+                {
+                    OIC_LOG(ERROR, TAG, "Failed to close TLS session");
+                }
+                CASearchAndDeleteTCPSession(&(svritem->sep.endpoint));
                 return;
             }
             nbRead = tlsLength - svritem->tlsLen;
@@ -760,6 +563,7 @@ static void CAReceiveMessage(int fd)
         else if (0 == len)
         {
             OIC_LOG(INFO, TAG, "Received disconnect from peer. Close connection");
+            svritem->state = DISCONNECTED;
             res = CA_DESTINATION_DISCONNECTED;
         }
         else
@@ -772,7 +576,7 @@ static void CAReceiveMessage(int fd)
                 //when successfully read data - pass them to callback.
                 res = CAdecryptSsl(&svritem->sep, (uint8_t *)svritem->tlsdata, svritem->tlsLen);
                 svritem->tlsLen = 0;
-                OIC_LOG_V(DEBUG, TAG, "%s: CAdecryptSsl returned %d", __func__, res);
+                OIC_LOG_V(INFO, TAG, "%s: CAdecryptSsl returned %d", __func__, res);
             }
         }
 #endif
@@ -780,10 +584,10 @@ static void CAReceiveMessage(int fd)
     }
     else
     {
-        unsigned char buffer[65535] = {0,}; // 65535 is the maximum size of ip packet
         svritem->protocol = COAP;
 
-        len = recv(fd, buffer, sizeof(buffer), 0);
+        // svritem->tlsdata can also be used as receiving buffer in case of raw tcp
+        len = recv(fd, svritem->tlsdata, sizeof(svritem->tlsdata), 0);
         if (len < 0)
         {
             OIC_LOG_V(ERROR, TAG, "recv failed %s", strerror(errno));
@@ -800,7 +604,7 @@ static void CAReceiveMessage(int fd)
             //when successfully read data - pass them to callback.
             if (g_packetReceivedCallback)
             {
-                g_packetReceivedCallback(&svritem->sep, buffer, len);
+                res = g_packetReceivedCallback(&svritem->sep, svritem->tlsdata, len);
             }
         }
     }
@@ -881,7 +685,7 @@ static CAResult_t CATCPCreateSocket(int family, CATCPSessionInfo_t *svritem)
 {
     VERIFY_NON_NULL(svritem, TAG, "svritem is NULL");
 
-    OIC_LOG_V(DEBUG, TAG, "try to connect with [%s:%u]",
+    OIC_LOG_V(INFO, TAG, "try to connect with [%s:%u]",
               svritem->sep.endpoint.addr, svritem->sep.endpoint.port);
 
     // #1. create tcp socket.
@@ -923,10 +727,12 @@ static CAResult_t CATCPCreateSocket(int family, CATCPSessionInfo_t *svritem)
     if (connect(fd, (struct sockaddr *)&sa, socklen) < 0)
     {
         OIC_LOG_V(ERROR, TAG, "failed to connect socket, %s", strerror(errno));
+        CALogSendStateInfo(svritem->sep.endpoint.adapter, svritem->sep.endpoint.addr,
+                           svritem->sep.endpoint.port, 0, false, strerror(errno));
         return CA_SOCKET_OPERATION_FAILED;
     }
 
-    OIC_LOG(DEBUG, TAG, "connect socket success");
+    OIC_LOG(INFO, TAG, "connect socket success");
     svritem->state = CONNECTED;
     CHECKFD(svritem->fd);
     ssize_t len = CAWakeUpForReadFdsUpdate(svritem->sep.endpoint.addr);
@@ -962,11 +768,14 @@ static CASocketFd_t CACreateAcceptSocket(int family, CASocket_t *sock)
     {
         // the socket is restricted to sending and receiving IPv6 packets only.
         int on = 1;
+//TODO: enable once IPv6 is supported
+#ifndef __TIZENRT__
         if (-1 == setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on)))
         {
             OIC_LOG_V(ERROR, TAG, "IPV6_V6ONLY failed: %s", strerror(errno));
             goto exit;
         }
+#endif
         ((struct sockaddr_in6 *)&server)->sin6_port = htons(sock->port);
         socklen = sizeof (struct sockaddr_in6);
     }
@@ -995,7 +804,17 @@ static CASocketFd_t CACreateAcceptSocket(int family, CASocket_t *sock)
         goto exit;
     }
 
-    if (!sock->port)  // return the assigned port
+    if (sock->port) // use the given port
+    {
+        int on = 1;
+        if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, OPTVAL_T(&on), sizeof (on)))
+        {
+            OIC_LOG_V(ERROR, TAG, "SO_REUSEADDR failed: %s", strerror(errno));
+            close(fd);
+            return OC_INVALID_SOCKET;
+        }
+    }
+    else  // return the assigned port
     {
         if (-1 == getsockname(fd, (struct sockaddr *)&server, &socklen))
         {
@@ -1020,6 +839,20 @@ exit:
 static void CAInitializePipe(int *fds)
 {
     int ret = pipe(fds);
+// TODO: Remove temporary workaround once F_GETFD / F_SETFD support is in TizenRT
+/* Temporary workaround: By pass F_GETFD / F_SETFD */
+#ifdef __TIZENRT__
+    if (-1 == ret)
+    {
+        close(fds[1]);
+        close(fds[0]);
+
+        fds[0] = -1;
+        fds[1] = -1;
+
+        OIC_LOG_V(ERROR, TAG, "pipe failed: %s", strerror(errno));
+    }
+#else
     if (-1 != ret)
     {
         ret = fcntl(fds[0], F_GETFD);
@@ -1046,6 +879,7 @@ static void CAInitializePipe(int *fds)
             OIC_LOG_V(ERROR, TAG, "pipe failed: %s", strerror(errno));
         }
     }
+#endif
 }
 
 #define NEWSOCKET(FAMILY, NAME) \
@@ -1057,14 +891,47 @@ static void CAInitializePipe(int *fds)
     } \
     CHECKFD(caglobals.tcp.NAME.fd);
 
+void CATCPInitializeSocket()
+{
+#ifndef __WITH_TLS__
+        NEWSOCKET(AF_INET, ipv4);
+#else
+        NEWSOCKET(AF_INET, ipv4s);
+#endif
+
+//TODO Enable once TizenRT supports IPv6
+#ifndef __TIZENRT__
+#ifndef __WITH_TLS__
+        NEWSOCKET(AF_INET6, ipv6);
+#else
+        NEWSOCKET(AF_INET6, ipv6s);
+#endif
+#endif
+#ifndef __WITH_TLS__
+        OIC_LOG_V(DEBUG, TAG, "IPv4 socket fd=%d, port=%d",
+                  caglobals.tcp.ipv4.fd, caglobals.tcp.ipv4.port);
+        OIC_LOG_V(DEBUG, TAG, "IPv6 socket fd=%d, port=%d",
+                  caglobals.tcp.ipv6.fd, caglobals.tcp.ipv6.port);
+#else
+        OIC_LOG_V(DEBUG, TAG, "IPv4 secure socket fd=%d, port=%d",
+                  caglobals.tcp.ipv4s.fd, caglobals.tcp.ipv4s.port);
+        OIC_LOG_V(DEBUG, TAG, "IPv6 secure socket fd=%d, port=%d",
+                  caglobals.tcp.ipv6s.fd, caglobals.tcp.ipv6s.port);
+#endif
+}
+
 CAResult_t CATCPStartServer(const ca_thread_pool_t threadPool)
 {
+    oc_mutex_lock(g_mutexObjectList);
     if (caglobals.tcp.started)
     {
-        OIC_LOG(DEBUG, TAG, "Adapter is started already");
+        oc_mutex_unlock(g_mutexObjectList);
+        OIC_LOG(INFO, TAG, "Adapter is started already");
         return CA_STATUS_OK;
     }
 
+    g_threadPool = threadPool;
+
     if (!caglobals.tcp.ipv4tcpenabled)
     {
         caglobals.tcp.ipv4tcpenabled = true;    // only needed to run CA tests
@@ -1074,109 +941,108 @@ CAResult_t CATCPStartServer(const ca_thread_pool_t threadPool)
         caglobals.tcp.ipv6tcpenabled = true;    // only needed to run CA tests
     }
 
-    CAResult_t res = CATCPCreateMutex();
-    if (CA_STATUS_OK == res)
-    {
-        res = CATCPCreateCond();
-    }
-    if (CA_STATUS_OK != res)
-    {
-        OIC_LOG(ERROR, TAG, "failed to create mutex/cond");
-        return res;
-    }
-
-    ca_mutex_lock(g_mutexObjectList);
+    caglobals.tcp.terminate = false;
     if (!caglobals.tcp.svrlist)
     {
         caglobals.tcp.svrlist = u_arraylist_create();
     }
-    ca_mutex_unlock(g_mutexObjectList);
 
     if (caglobals.server)
     {
-        NEWSOCKET(AF_INET, ipv4);
-        NEWSOCKET(AF_INET, ipv4s);
-        NEWSOCKET(AF_INET6, ipv6);
-        NEWSOCKET(AF_INET6, ipv6s);
-        OIC_LOG_V(DEBUG, TAG, "IPv4 socket fd=%d, port=%d",
-                  caglobals.tcp.ipv4.fd, caglobals.tcp.ipv4.port);
-        OIC_LOG_V(DEBUG, TAG, "IPv4 secure socket fd=%d, port=%d",
-                  caglobals.tcp.ipv4s.fd, caglobals.tcp.ipv4s.port);
-        OIC_LOG_V(DEBUG, TAG, "IPv6 socket fd=%d, port=%d",
-                  caglobals.tcp.ipv6.fd, caglobals.tcp.ipv6.port);
-        OIC_LOG_V(DEBUG, TAG, "IPv6 secure socket fd=%d, port=%d",
-                  caglobals.tcp.ipv6s.fd, caglobals.tcp.ipv6s.port);
+        CATCPInitializeSocket();
     }
-
+#ifndef __TIZENRT__
     // create pipe for fast shutdown
     CAInitializePipe(caglobals.tcp.shutdownFds);
     CHECKFD(caglobals.tcp.shutdownFds[0]);
     CHECKFD(caglobals.tcp.shutdownFds[1]);
-
+#endif
     // create pipe for connection event
     CAInitializePipe(caglobals.tcp.connectionFds);
     CHECKFD(caglobals.tcp.connectionFds[0]);
     CHECKFD(caglobals.tcp.connectionFds[1]);
 
-    caglobals.tcp.terminate = false;
-    res = ca_thread_pool_add_task(threadPool, CAReceiveHandler, NULL);
+    CAResult_t res = CA_STATUS_OK;
+#ifndef __TIZENRT__
+    res = ca_thread_pool_add_task(g_threadPool, CAReceiveHandler, NULL, &g_recvThreadId);
+#else
+    res = ca_thread_pool_add_task(g_threadPool, CAReceiveHandler, NULL, &g_recvThreadId,
+                                 "IoT_TCPReceive", CONFIG_IOTIVITY_TCPRECEIVE_PTHREAD_STACKSIZE);
+#endif
     if (CA_STATUS_OK != res)
     {
+        g_recvThreadId = 0;
+        oc_mutex_unlock(g_mutexObjectList);
         OIC_LOG(ERROR, TAG, "thread_pool_add_task failed");
+        CATCPStopServer();
         return res;
     }
-    OIC_LOG(DEBUG, TAG, "CAReceiveHandler thread started successfully.");
 
     caglobals.tcp.started = true;
+    oc_mutex_unlock(g_mutexObjectList);
+
+    OIC_LOG(INFO, TAG, "CAReceiveHandler thread started successfully.");
     return CA_STATUS_OK;
 }
 
 void CATCPStopServer()
 {
+    oc_mutex_lock(g_mutexObjectList);
     if (caglobals.tcp.terminate)
     {
-        OIC_LOG(DEBUG, TAG, "Adapter is not enabled");
+        oc_mutex_unlock(g_mutexObjectList);
+        OIC_LOG(INFO, TAG, "Adapter is not enabled");
         return;
     }
 
-    // mutex lock
-    ca_mutex_lock(g_mutexObjectList);
-
     // set terminate flag.
     caglobals.tcp.terminate = true;
 
-    if (caglobals.tcp.shutdownFds[1] != -1)
+    // close accept socket.
+#ifndef __WITH_TLS__
+    CLOSE_SOCKET(ipv4);
+    CLOSE_SOCKET(ipv6);
+#else
+    CLOSE_SOCKET(ipv4s);
+    CLOSE_SOCKET(ipv6s);
+#endif
+
+    close(caglobals.tcp.connectionFds[1]);
+    close(caglobals.tcp.connectionFds[0]);
+    caglobals.tcp.connectionFds[1] = OC_INVALID_SOCKET;
+    caglobals.tcp.connectionFds[0] = OC_INVALID_SOCKET;
+#ifndef __TIZENRT__
+    if (caglobals.tcp.shutdownFds[1] != OC_INVALID_SOCKET)
     {
         close(caglobals.tcp.shutdownFds[1]);
         caglobals.tcp.shutdownFds[1] = OC_INVALID_SOCKET;
         // receive thread will stop immediately
     }
-    if (caglobals.tcp.connectionFds[1] != -1)
+#endif
+    if (caglobals.tcp.started)
     {
-        close(caglobals.tcp.connectionFds[1]);
-        caglobals.tcp.connectionFds[1] = OC_INVALID_SOCKET;
+        oc_cond_wait(g_condObjectList, g_mutexObjectList);
+        caglobals.tcp.started = false;
     }
-
-    // close accept socket.
-    CLOSE_SOCKET(ipv4);
-    CLOSE_SOCKET(ipv4s);
-    CLOSE_SOCKET(ipv6);
-    CLOSE_SOCKET(ipv6s);
-
-    if (caglobals.tcp.started)
+#ifndef __TIZENRT__
+    if (caglobals.tcp.shutdownFds[0] != OC_INVALID_SOCKET)
     {
-        ca_cond_wait(g_condObjectList, g_mutexObjectList);
+        close(caglobals.tcp.shutdownFds[0]);
+        caglobals.tcp.shutdownFds[0] = OC_INVALID_SOCKET;
     }
-    caglobals.tcp.started = false;
-
-    // mutex unlock
-    ca_mutex_unlock(g_mutexObjectList);
+#endif
+    CAResult_t res = ca_thread_pool_remove_task(g_threadPool, g_recvThreadId);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "ca_thread_pool_remove_task failed");
+    }
+    g_recvThreadId = 0;
+    oc_mutex_unlock(g_mutexObjectList);
 
     CATCPDisconnectAll();
-    CATCPDestroyMutex();
-    CATCPDestroyCond();
+    sleep(1);
 
-    OIC_LOG(DEBUG, TAG, "Adapter terminated successfully");
+    OIC_LOG(INFO, TAG, "Adapter terminated successfully");
 }
 
 void CATCPSetPacketReceiveCallback(CATCPPacketReceivedCallback callback)
@@ -1247,12 +1113,18 @@ static ssize_t sendData(const CAEndpoint_t *endpoint, const void *data,
     ssize_t remainLen = dlen;
     do
     {
+#ifdef MSG_NOSIGNAL
+        ssize_t len = send(sockFd, data, remainLen, MSG_NOSIGNAL);
+#else
         ssize_t len = send(sockFd, data, remainLen, 0);
+#endif
         if (-1 == len)
         {
             if (EWOULDBLOCK != errno)
             {
                 OIC_LOG_V(ERROR, TAG, "unicast ipv4tcp sendTo failed: %s", strerror(errno));
+                CALogSendStateInfo(endpoint->adapter, endpoint->addr, endpoint->port,
+                                   len, false, strerror(errno));
                 return len;
             }
             continue;
@@ -1265,6 +1137,8 @@ static ssize_t sendData(const CAEndpoint_t *endpoint, const void *data,
     (void)fam;
 #endif
     OIC_LOG_V(INFO, TAG, "unicast %stcp sendTo is successful: %zu bytes", fam, dlen);
+    CALogSendStateInfo(endpoint->adapter, endpoint->addr, endpoint->port,
+                       dlen, true, NULL);
     return dlen;
 }
 
@@ -1311,9 +1185,10 @@ CASocketFd_t CAConnectTCPSession(const CAEndpoint_t *endpoint)
     svritem->sep.endpoint.flags = endpoint->flags;
     svritem->sep.endpoint.ifindex = endpoint->ifindex;
     svritem->state = CONNECTING;
+    svritem->isClient = true;
 
     // #2. add TCP connection info to list
-    ca_mutex_lock(g_mutexObjectList);
+    oc_mutex_lock(g_mutexObjectList);
     if (caglobals.tcp.svrlist)
     {
         bool res = u_arraylist_add(caglobals.tcp.svrlist, svritem);
@@ -1322,11 +1197,11 @@ CASocketFd_t CAConnectTCPSession(const CAEndpoint_t *endpoint)
             OIC_LOG(ERROR, TAG, "u_arraylist_add failed.");
             close(svritem->fd);
             OICFree(svritem);
-            ca_mutex_unlock(g_mutexObjectList);
+            oc_mutex_unlock(g_mutexObjectList);
             return OC_INVALID_SOCKET;
         }
     }
-    ca_mutex_unlock(g_mutexObjectList);
+    oc_mutex_unlock(g_mutexObjectList);
 
     // #3. create the socket and connect to TCP server
     int family = (svritem->sep.endpoint.flags & CA_IPV6) ? AF_INET6 : AF_INET;
@@ -1338,7 +1213,7 @@ CASocketFd_t CAConnectTCPSession(const CAEndpoint_t *endpoint)
     // #4. pass the connection information to CA Common Layer.
     if (g_connectionCallback)
     {
-        g_connectionCallback(&(svritem->sep.endpoint), true);
+        g_connectionCallback(&(svritem->sep.endpoint), true, svritem->isClient);
     }
 
     return svritem->fd;
@@ -1365,7 +1240,7 @@ CAResult_t CADisconnectTCPSession(size_t index)
         // pass the connection information to CA Common Layer.
         if (g_connectionCallback && DISCONNECTED == removedData->state)
         {
-            g_connectionCallback(&(removedData->sep.endpoint), false);
+            g_connectionCallback(&(removedData->sep.endpoint), false, removedData->isClient);
         }
     }
     OICFree(removedData->data);
@@ -1375,12 +1250,17 @@ CAResult_t CADisconnectTCPSession(size_t index)
     removedData = NULL;
 
     OIC_LOG(DEBUG, TAG, "data is removed from session list");
+
+    if (caglobals.server && MAX_CONNECTION_COUNTS == u_arraylist_length(caglobals.tcp.svrlist) + 1)
+    {
+        CATCPInitializeSocket();
+    }
     return CA_STATUS_OK;
 }
 
 void CATCPDisconnectAll()
 {
-    ca_mutex_lock(g_mutexObjectList);
+    oc_mutex_lock(g_mutexObjectList);
 
     uint32_t length = u_arraylist_length(caglobals.tcp.svrlist);
     for (ssize_t index = length; index > 0; index--)
@@ -1392,10 +1272,10 @@ void CATCPDisconnectAll()
     u_arraylist_destroy(caglobals.tcp.svrlist);
     caglobals.tcp.svrlist = NULL;
 
-    ca_mutex_unlock(g_mutexObjectList);
+    oc_mutex_unlock(g_mutexObjectList);
 
 #ifdef __WITH_TLS__
-    CAcloseSslConnectionAll();
+    CAcloseSslConnectionAll(CA_ADAPTER_TCP);
 #endif
 
 }
@@ -1440,7 +1320,7 @@ CASocketFd_t CAGetSocketFDFromEndpoint(const CAEndpoint_t *endpoint)
     OIC_LOG_V(DEBUG, TAG, "Looking for [%s:%d]", endpoint->addr, endpoint->port);
 
     // get connection info from list.
-    ca_mutex_lock(g_mutexObjectList);
+    oc_mutex_lock(g_mutexObjectList);
     uint32_t length = u_arraylist_length(caglobals.tcp.svrlist);
     for (size_t i = 0; i < length; i++)
     {
@@ -1456,20 +1336,20 @@ CASocketFd_t CAGetSocketFDFromEndpoint(const CAEndpoint_t *endpoint)
                 && (svritem->sep.endpoint.port == endpoint->port)
                 && (svritem->sep.endpoint.flags & endpoint->flags))
         {
-            ca_mutex_unlock(g_mutexObjectList);
+            oc_mutex_unlock(g_mutexObjectList);
             OIC_LOG(DEBUG, TAG, "Found in session list");
             return svritem->fd;
         }
     }
 
-    ca_mutex_unlock(g_mutexObjectList);
+    oc_mutex_unlock(g_mutexObjectList);
     OIC_LOG(DEBUG, TAG, "Session not found");
     return OC_INVALID_SOCKET;
 }
 
 CATCPSessionInfo_t *CAGetSessionInfoFromFD(int fd, size_t *index)
 {
-    ca_mutex_lock(g_mutexObjectList);
+    oc_mutex_lock(g_mutexObjectList);
 
     // check from the last item.
     CATCPSessionInfo_t *svritem = NULL;
@@ -1481,19 +1361,19 @@ CATCPSessionInfo_t *CAGetSessionInfoFromFD(int fd, size_t *index)
         if (svritem && svritem->fd == fd)
         {
             *index = i;
-            ca_mutex_unlock(g_mutexObjectList);
+            oc_mutex_unlock(g_mutexObjectList);
             return svritem;
         }
     }
 
-    ca_mutex_unlock(g_mutexObjectList);
+    oc_mutex_unlock(g_mutexObjectList);
 
     return NULL;
 }
 
 CAResult_t CASearchAndDeleteTCPSession(const CAEndpoint_t *endpoint)
 {
-    ca_mutex_lock(g_mutexObjectList);
+    oc_mutex_lock(g_mutexObjectList);
 
     CAResult_t result = CA_STATUS_OK;
     size_t index = 0;
@@ -1507,7 +1387,7 @@ CAResult_t CASearchAndDeleteTCPSession(const CAEndpoint_t *endpoint)
         }
     }
 
-    ca_mutex_unlock(g_mutexObjectList);
+    oc_mutex_unlock(g_mutexObjectList);
     return result;
 }
 
@@ -1533,4 +1413,3 @@ void CATCPSetErrorHandler(CATCPErrorHandleCallback errorHandleCallback)
 {
     g_tcpErrorHandler = errorHandleCallback;
 }
-
index 3ad6615..24a0df3 100644 (file)
@@ -69,7 +69,7 @@ tests_src = [
        'catests.cpp',
        'caprotocolmessagetest.cpp',
        'ca_api_unittest.cpp',
-       'camutex_tests.cpp',
+       'octhread_tests.cpp',
        'uarraylist_test.cpp',
        'ulinklist_test.cpp',
        'uqueue_test.cpp'
index 6435a56..100beac 100644 (file)
@@ -32,7 +32,7 @@ class CATests : public testing::Test {
     protected:
     virtual void SetUp()
     {
-        CAInitialize();
+        CAInitialize(CA_ADAPTER_IP);
     }
 
     virtual void TearDown()
@@ -164,7 +164,7 @@ int32_t CAGetDtlsPskCredentials( CADtlsPskCredType_t type,
 // CAInitialize TC
 TEST(InitializeTest, CAInitializeTest)
 {
-    EXPECT_EQ(CA_STATUS_OK, CAInitialize());
+    EXPECT_EQ(CA_STATUS_OK, CAInitialize(CA_ADAPTER_IP));
     CATerminate();
 }
 
@@ -176,7 +176,7 @@ TEST_F(CATests, TerminateTest)
     char* check = (char *) "terminate success";
     EXPECT_STREQ(check, "terminate success");
 
-    CAInitialize();
+    CAInitialize(CA_ADAPTER_IP);
 }
 
 // CAStartListeningServer TC
@@ -299,7 +299,7 @@ TEST(SendRequestTest, DISABLED_TC_16_Positive_01)
     requestData.token = tempToken;
     requestData.tokenLength = tokenLength;
 
-    int length = strlen(NORMAL_INFO_DATA) + strlen("a/light");
+    size_t length = strlen(NORMAL_INFO_DATA) + strlen("a/light");
     requestData.payload = (CAPayload_t) calloc(length, sizeof(char));
     if(!requestData.payload)
     {
index 040c7e0..9fdb526 100644 (file)
@@ -31,7 +31,7 @@ class CABlockTransferTests : public testing::Test {
     protected:
     virtual void SetUp()
     {
-        CAInitialize();
+        CAInitialize(CA_ADAPTER_IP);
     }
 
     virtual void TearDown()
@@ -36,7 +36,7 @@
 #include "iotivity_config.h"
 #include "gtest/gtest.h"
 
-#include <camutex.h>
+#include "octhread.h"
 #include <cathreadpool.h>
 
 #ifdef HAVE_TIME_H
@@ -102,18 +102,18 @@ uint64_t getAbsTime()
 
 TEST(MutexTests, TC_01_CREATE)
 {
-    ca_mutex mymutex = ca_mutex_new();
+    oc_mutex mymutex = oc_mutex_new();
 
     EXPECT_TRUE(mymutex != NULL);
     if (mymutex != NULL)
     {
-        ca_mutex_free(mymutex);
+        oc_mutex_free(mymutex);
     }
 }
 
 typedef struct _tagFunc1
 {
-    ca_mutex mutex;
+    oc_mutex mutex;
     volatile bool thread_up;
     volatile bool finished;
 } _func1_struct;
@@ -127,7 +127,7 @@ void mutexFunc(void *context)
     // setting the flag must be done before lock attempt, as the test
     // thread starts off with the mutex locked
     pData->thread_up = true;
-    ca_mutex_lock(pData->mutex);
+    oc_mutex_lock(pData->mutex);
 
     DBG_printf("Thread: got lock\n");
     usleep(MINIMAL_LOOP_SLEEP * USECS_PER_MSEC);
@@ -135,7 +135,7 @@ void mutexFunc(void *context)
 
     pData->finished = true; // assignment guarded by lock
 
-    ca_mutex_unlock(pData->mutex);
+    oc_mutex_unlock(pData->mutex);
 }
 
 TEST(MutexTests, TC_03_THREAD_LOCKING)
@@ -146,18 +146,18 @@ TEST(MutexTests, TC_03_THREAD_LOCKING)
 
     _func1_struct pData = {0, false, false};
 
-    pData.mutex = ca_mutex_new();
+    pData.mutex = oc_mutex_new();
 
     EXPECT_TRUE(pData.mutex != NULL);
     if (pData.mutex != NULL)
     {
         DBG_printf("test: Holding mutex in test\n");
-        ca_mutex_lock(pData.mutex);
+        oc_mutex_lock(pData.mutex);
 
         DBG_printf("test: starting thread\n");
         //start thread
         EXPECT_EQ(CA_STATUS_OK,
-                  ca_thread_pool_add_task(mythreadpool, mutexFunc, &pData));
+                  ca_thread_pool_add_task(mythreadpool, mutexFunc, &pData, NULL));
 
         DBG_printf("test: waiting for thread to be up.\n");
 
@@ -172,7 +172,7 @@ TEST(MutexTests, TC_03_THREAD_LOCKING)
 
         DBG_printf("test: unlocking\n");
 
-        ca_mutex_unlock(pData.mutex);
+        oc_mutex_unlock(pData.mutex);
 
         DBG_printf("test: waiting for thread to release\n");
         while (!pData.finished)
@@ -180,12 +180,12 @@ TEST(MutexTests, TC_03_THREAD_LOCKING)
             usleep(MINIMAL_LOOP_SLEEP * USECS_PER_MSEC);
         }
 
-        ca_mutex_lock(pData.mutex);
+        oc_mutex_lock(pData.mutex);
 
         // Cleanup Everything
 
-        ca_mutex_unlock(pData.mutex);
-        ca_mutex_free(pData.mutex);
+        oc_mutex_unlock(pData.mutex);
+        oc_mutex_free(pData.mutex);
     }
 
     ca_thread_pool_free(mythreadpool);
@@ -193,23 +193,23 @@ TEST(MutexTests, TC_03_THREAD_LOCKING)
 
 TEST(ConditionTests, TC_01_CREATE)
 {
-    ca_cond mycond = ca_cond_new();
+    oc_cond mycond = oc_cond_new();
 
     EXPECT_TRUE(mycond != NULL);
     if (mycond != NULL)
     {
-        ca_cond_free(mycond);
+        oc_cond_free(mycond);
     }
 }
 
 // Normally we would use one pair of mutex/cond-var communicating to the
 // worker threads and one pair back to the main thread. However since
-// testing the ca_cond itself is the point, only one pair is used here.
+// testing the oc_cond itself is the point, only one pair is used here.
 typedef struct _tagFunc2
 {
     int id;
-    ca_mutex mutex;
-    ca_cond condition;
+    oc_mutex mutex;
+    oc_cond condition;
     volatile bool thread_up;
     volatile bool finished;
 } _func2_struct;
@@ -220,15 +220,15 @@ void condFunc(void *context)
 
     DBG_printf("Thread_%d: waiting on condition\n", pData->id);
 
-    ca_mutex_lock(pData->mutex);
+    oc_mutex_lock(pData->mutex);
 
     pData->thread_up = true;
 
-    ca_cond_wait(pData->condition, pData->mutex);
+    oc_cond_wait(pData->condition, pData->mutex);
 
     pData->finished = true; // assignment guarded by lock
 
-    ca_mutex_unlock(pData->mutex);
+    oc_mutex_unlock(pData->mutex);
 
     DBG_printf("Thread_%d: completed.\n", pData->id);
 }
@@ -245,8 +245,8 @@ TEST(ConditionTests, TC_02_SIGNAL)
 
     EXPECT_EQ(CA_STATUS_OK, ca_thread_pool_init(3, &mythreadpool));
 
-    ca_mutex sharedMutex = ca_mutex_new();
-    ca_cond sharedCond = ca_cond_new();
+    oc_mutex sharedMutex = oc_mutex_new();
+    oc_cond sharedCond = oc_cond_new();
 
     _func2_struct pData1 =
     { 1, sharedMutex, sharedCond, false, false };
@@ -259,9 +259,9 @@ TEST(ConditionTests, TC_02_SIGNAL)
         DBG_printf("starting thread\n");
         // start threads
         EXPECT_EQ(CA_STATUS_OK,
-                  ca_thread_pool_add_task(mythreadpool, condFunc, &pData1));
+                  ca_thread_pool_add_task(mythreadpool, condFunc, &pData1, NULL));
         EXPECT_EQ(CA_STATUS_OK,
-                  ca_thread_pool_add_task(mythreadpool, condFunc, &pData2));
+                  ca_thread_pool_add_task(mythreadpool, condFunc, &pData2, NULL));
 
         DBG_printf("test    : sleeping\n");
 
@@ -275,11 +275,11 @@ TEST(ConditionTests, TC_02_SIGNAL)
         // has already started waiting on the condition and the other is at
         // least close.
 
-        ca_mutex_lock(sharedMutex);
+        oc_mutex_lock(sharedMutex);
         // once the lock is acquired it means both threads were waiting.
         DBG_printf("test    : signaling first thread\n");
-        ca_cond_signal(sharedCond);
-        ca_mutex_unlock(sharedMutex);
+        oc_cond_signal(sharedCond);
+        oc_mutex_unlock(sharedMutex);
 
         // At this point either of the child threads might lock the mutex in
         // their cond_wait call, or this test thread might lock it again if
@@ -303,15 +303,15 @@ TEST(ConditionTests, TC_02_SIGNAL)
         usleep(MINIMAL_EXTRA_SLEEP);
 
         // only one should be finished
-        ca_mutex_lock(sharedMutex);
+        oc_mutex_lock(sharedMutex);
         EXPECT_NE(pData1.finished, pData2.finished);
-        ca_mutex_unlock(sharedMutex);
+        oc_mutex_unlock(sharedMutex);
 
         DBG_printf("test    : signaling another thread\n");
 
-        ca_mutex_lock(sharedMutex);
-        ca_cond_signal(sharedCond);
-        ca_mutex_unlock(sharedMutex);
+        oc_mutex_lock(sharedMutex);
+        oc_cond_signal(sharedCond);
+        oc_mutex_unlock(sharedMutex);
 
         waitCount = 0;
         while ((!pData1.finished || !pData2.finished)
@@ -327,10 +327,10 @@ TEST(ConditionTests, TC_02_SIGNAL)
 
         // Cleanup Everything
 
-        ca_mutex_free(pData1.mutex);
+        oc_mutex_free(pData1.mutex);
     }
 
-    ca_cond_free(pData1.condition);
+    oc_cond_free(pData1.condition);
 
     ca_thread_pool_free(mythreadpool);
 }
@@ -342,8 +342,8 @@ TEST(ConditionTests, TC_03_BROADCAST)
 
     EXPECT_EQ(CA_STATUS_OK, ca_thread_pool_init(3, &mythreadpool));
 
-    ca_mutex sharedMutex = ca_mutex_new();
-    ca_cond sharedCond = ca_cond_new();
+    oc_mutex sharedMutex = oc_mutex_new();
+    oc_cond sharedCond = oc_cond_new();
 
     _func2_struct pData1 =
     { 1, sharedMutex, sharedCond, false, false };
@@ -356,9 +356,9 @@ TEST(ConditionTests, TC_03_BROADCAST)
         DBG_printf("starting thread\n");
         // start threads
         EXPECT_EQ(CA_STATUS_OK,
-                  ca_thread_pool_add_task(mythreadpool, condFunc, &pData1));
+                  ca_thread_pool_add_task(mythreadpool, condFunc, &pData1, NULL));
         EXPECT_EQ(CA_STATUS_OK,
-                  ca_thread_pool_add_task(mythreadpool, condFunc, &pData2));
+                  ca_thread_pool_add_task(mythreadpool, condFunc, &pData2, NULL));
 
         DBG_printf("test    : sleeping\n");
 
@@ -374,10 +374,10 @@ TEST(ConditionTests, TC_03_BROADCAST)
 
         DBG_printf("test    : signaling all threads\n");
 
-        ca_mutex_lock(sharedMutex);
+        oc_mutex_lock(sharedMutex);
         // once the lock is acquired it means both threads were waiting.
-        ca_cond_broadcast(sharedCond);
-        ca_mutex_unlock(sharedMutex);
+        oc_cond_broadcast(sharedCond);
+        oc_mutex_unlock(sharedMutex);
 
         int waitCount = 0;
         while ((!pData1.finished || !pData2.finished)
@@ -393,10 +393,10 @@ TEST(ConditionTests, TC_03_BROADCAST)
 
         // Cleanup Everything
 
-        ca_mutex_free(sharedMutex);
+        oc_mutex_free(sharedMutex);
     }
 
-    ca_cond_free(sharedCond);
+    oc_cond_free(sharedCond);
 
     ca_thread_pool_free(mythreadpool);
 }
@@ -423,14 +423,14 @@ void timedFunc(void *context)
 
     DBG_printf("Thread_%d: waiting for timeout \n", pData->id);
 
-    ca_mutex_lock(pData->mutex);
+    oc_mutex_lock(pData->mutex);
 
     uint64_t abs = USECS_PER_SEC / 2; // 1/2 seconds
 
     // test UTIMEDOUT
-    CAWaitResult_t ret = ca_cond_wait_for(pData->condition,
+    OCWaitResult_t ret = oc_cond_wait_for(pData->condition,
                                           pData->mutex, abs);
-    EXPECT_EQ(CA_WAIT_TIMEDOUT, ret);
+    EXPECT_EQ(OC_WAIT_TIMEDOUT, ret);
 
     pData->thread_up = true;
 
@@ -439,12 +439,12 @@ void timedFunc(void *context)
     abs = 5 * USECS_PER_SEC; // 5 seconds
 
     // test signal
-    ret = ca_cond_wait_for(pData->condition, pData->mutex, abs);
-    EXPECT_EQ(CA_WAIT_SUCCESS, ret);
+    ret = oc_cond_wait_for(pData->condition, pData->mutex, abs);
+    EXPECT_EQ(OC_WAIT_SUCCESS, ret);
 
     pData->finished = true; // assignment guarded by lock
 
-    ca_mutex_unlock(pData->mutex);
+    oc_mutex_unlock(pData->mutex);
 
     DBG_printf("Thread_%d: stopping\n", pData->id);
 }
@@ -456,8 +456,8 @@ TEST(ConditionTests, TC_05_WAIT)
 
     EXPECT_EQ(CA_STATUS_OK, ca_thread_pool_init(3, &mythreadpool));
 
-    ca_mutex sharedMutex = ca_mutex_new();
-    ca_cond sharedCond = ca_cond_new();
+    oc_mutex sharedMutex = oc_mutex_new();
+    oc_cond sharedCond = oc_cond_new();
 
     _func2_struct pData1 =
     { 1, sharedMutex, sharedCond, false, false };
@@ -468,7 +468,7 @@ TEST(ConditionTests, TC_05_WAIT)
         DBG_printf("test    : starting thread\n");
         //start thread
         EXPECT_EQ(CA_STATUS_OK,
-                  ca_thread_pool_add_task(mythreadpool, timedFunc, &pData1));
+                  ca_thread_pool_add_task(mythreadpool, timedFunc, &pData1, NULL));
 
         DBG_printf("test    : waiting for thread to timeout once.\n");
 
@@ -482,9 +482,9 @@ TEST(ConditionTests, TC_05_WAIT)
 
         DBG_printf("test    : signaling first thread\n");
 
-        ca_mutex_lock(sharedMutex);
-        ca_cond_signal(sharedCond);
-        ca_mutex_unlock(sharedMutex);
+        oc_mutex_lock(sharedMutex);
+        oc_cond_signal(sharedCond);
+        oc_mutex_unlock(sharedMutex);
 
         int waitCount = 0;
         while (!pData1.finished
@@ -498,10 +498,10 @@ TEST(ConditionTests, TC_05_WAIT)
 
         // Cleanup Everything
 
-        ca_mutex_free(sharedMutex);
+        oc_mutex_free(sharedMutex);
     }
 
-    ca_cond_free(sharedCond);
+    oc_cond_free(sharedCond);
 
     ca_thread_pool_free(mythreadpool);
 }
@@ -510,43 +510,43 @@ TEST(ConditionTests, TC_05_WAIT)
 TEST(ConditionTests, DISABLED_TC_06_INVALIDWAIT)
 {
 
-    ca_mutex sharedMutex = ca_mutex_new();
-    ca_cond sharedCond = ca_cond_new();
+    oc_mutex sharedMutex = oc_mutex_new();
+    oc_cond sharedCond = oc_cond_new();
 
-    ca_mutex_lock(sharedMutex);
+    oc_mutex_lock(sharedMutex);
 
-    int ret = ca_cond_wait_for(NULL, sharedMutex, 5000);
-    EXPECT_EQ(CA_WAIT_INVAL,ret);
+    int ret = oc_cond_wait_for(NULL, sharedMutex, 5000);
+    EXPECT_EQ(OC_WAIT_INVAL,ret);
 
-    ret = ca_cond_wait_for(sharedCond, NULL, 5000);
-    EXPECT_EQ(CA_WAIT_INVAL,ret);
+    ret = oc_cond_wait_for(sharedCond, NULL, 5000);
+    EXPECT_EQ(OC_WAIT_INVAL,ret);
 
-    ret = ca_cond_wait_for(NULL, NULL, 5000);
-    EXPECT_EQ(CA_WAIT_INVAL,ret);
+    ret = oc_cond_wait_for(NULL, NULL, 5000);
+    EXPECT_EQ(OC_WAIT_INVAL,ret);
 
-    ca_mutex_unlock(sharedMutex);
+    oc_mutex_unlock(sharedMutex);
 
     // Cleanup Everything
 
-    ca_mutex_free(sharedMutex);
+    oc_mutex_free(sharedMutex);
 
-    ca_cond_free(sharedCond);
+    oc_cond_free(sharedCond);
 }
 
 TEST(ConditionTests, TC_07_WAITDURATION)
 {
     const double TARGET_WAIT = 1.125;
 
-    ca_mutex sharedMutex = ca_mutex_new();
-    ca_cond sharedCond = ca_cond_new();
+    oc_mutex sharedMutex = oc_mutex_new();
+    oc_cond sharedCond = oc_cond_new();
 
-    ca_mutex_lock(sharedMutex);
+    oc_mutex_lock(sharedMutex);
 
     uint64_t beg = getAbsTime();
 
-    CAWaitResult_t ret = ca_cond_wait_for(sharedCond, sharedMutex,
+    OCWaitResult_t ret = oc_cond_wait_for(sharedCond, sharedMutex,
                                           TARGET_WAIT * USECS_PER_SEC);
-    EXPECT_EQ(CA_WAIT_TIMEDOUT,ret);
+    EXPECT_EQ(OC_WAIT_TIMEDOUT,ret);
 
     uint64_t end = getAbsTime();
 
@@ -561,11 +561,11 @@ TEST(ConditionTests, TC_07_WAITDURATION)
     EXPECT_NEAR(TARGET_WAIT, secondsDiff, 0.05);
 #endif
 
-    ca_mutex_unlock(sharedMutex);
+    oc_mutex_unlock(sharedMutex);
 
     // Cleanup Everything
 
-    ca_mutex_free(sharedMutex);
+    oc_mutex_free(sharedMutex);
 
-    ca_cond_free(sharedCond);
+    oc_cond_free(sharedCond);
 }
index 99d5546..b11fd35 100644 (file)
@@ -72,7 +72,7 @@
 
 #define MBED_TLS_DEBUG_LEVEL (4) // Verbose
 
-#define SEED "PREDICTED_SEED"
+#define UT_SSL_SEED "PREDICTED_SEED"
 #define dummyHandler 0xF123
 
 #define SERVER_PORT 4433
  *
  * *************************/
 
+// Data blob contains 10 certificates in PEM and DER encoding
+unsigned char certChain[] = {
+    // PEM encoded certificate
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49,
+    0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43,
+    0x6e, 0x44, 0x43, 0x43, 0x41, 0x6a, 0x2b, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x55,
+    0x44, 0x67, 0x45, 0x38, 0x4e, 0x50, 0x54, 0x4c, 0x46, 0x64, 0x6d, 0x68, 0x75, 0x72, 0x53, 0x69,
+    0x36, 0x33, 0x49, 0x31, 0x41, 0x77, 0x76, 0x37, 0x39, 0x49, 0x6b, 0x77, 0x44, 0x41, 0x59, 0x49,
+    0x4b, 0x6f, 0x5a, 0x49, 0x7a, 0x6a, 0x30, 0x45, 0x41, 0x77, 0x49, 0x46, 0x0a, 0x41, 0x44, 0x43,
+    0x42, 0x67, 0x7a, 0x45, 0x34, 0x4d, 0x44, 0x59, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d,
+    0x76, 0x55, 0x32, 0x46, 0x74, 0x63, 0x33, 0x56, 0x75, 0x5a, 0x79, 0x42, 0x46, 0x62, 0x47, 0x56,
+    0x6a, 0x64, 0x48, 0x4a, 0x76, 0x62, 0x6d, 0x6c, 0x6a, 0x63, 0x79, 0x42, 0x50, 0x51, 0x30, 0x59,
+    0x67, 0x54, 0x55, 0x4d, 0x67, 0x52, 0x47, 0x56, 0x32, 0x61, 0x57, 0x4e, 0x6c, 0x0a, 0x49, 0x46,
+    0x4e, 0x31, 0x59, 0x6b, 0x4e, 0x42, 0x49, 0x48, 0x59, 0x78, 0x49, 0x46, 0x52, 0x46, 0x55, 0x31,
+    0x51, 0x78, 0x48, 0x44, 0x41, 0x61, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x54, 0x45, 0x30,
+    0x39, 0x44, 0x52, 0x69, 0x42, 0x4e, 0x51, 0x79, 0x42, 0x45, 0x5a, 0x58, 0x5a, 0x70, 0x59, 0x32,
+    0x55, 0x67, 0x55, 0x33, 0x56, 0x69, 0x51, 0x30, 0x45, 0x78, 0x48, 0x44, 0x41, 0x61, 0x0a, 0x42,
+    0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x54, 0x45, 0x31, 0x4e, 0x68, 0x62, 0x58, 0x4e, 0x31, 0x62,
+    0x6d, 0x63, 0x67, 0x52, 0x57, 0x78, 0x6c, 0x59, 0x33, 0x52, 0x79, 0x62, 0x32, 0x35, 0x70, 0x59,
+    0x33, 0x4d, 0x78, 0x43, 0x7a, 0x41, 0x4a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41,
+    0x6b, 0x74, 0x53, 0x4d, 0x43, 0x41, 0x58, 0x44, 0x54, 0x45, 0x32, 0x4d, 0x54, 0x45, 0x79, 0x0a,
+    0x4e, 0x44, 0x41, 0x79, 0x4e, 0x44, 0x67, 0x78, 0x4d, 0x6c, 0x6f, 0x59, 0x44, 0x7a, 0x49, 0x77,
+    0x4e, 0x6a, 0x6b, 0x78, 0x4d, 0x6a, 0x4d, 0x78, 0x4d, 0x54, 0x51, 0x31, 0x4f, 0x54, 0x55, 0x35,
+    0x57, 0x6a, 0x43, 0x42, 0x6a, 0x54, 0x46, 0x49, 0x4d, 0x45, 0x59, 0x47, 0x41, 0x31, 0x55, 0x45,
+    0x41, 0x78, 0x4d, 0x2f, 0x54, 0x30, 0x4e, 0x47, 0x49, 0x45, 0x52, 0x6c, 0x64, 0x6d, 0x6c, 0x6a,
+    0x0a, 0x5a, 0x53, 0x42, 0x55, 0x52, 0x56, 0x4e, 0x55, 0x4f, 0x69, 0x42, 0x4f, 0x5a, 0x58, 0x52,
+    0x33, 0x62, 0x33, 0x4a, 0x72, 0x49, 0x43, 0x67, 0x77, 0x4e, 0x6a, 0x51, 0x79, 0x4e, 0x32, 0x45,
+    0x32, 0x4e, 0x53, 0x31, 0x69, 0x5a, 0x6a, 0x63, 0x30, 0x4c, 0x54, 0x51, 0x33, 0x4d, 0x7a, 0x63,
+    0x74, 0x4f, 0x54, 0x5a, 0x6d, 0x4d, 0x53, 0x30, 0x78, 0x59, 0x6d, 0x49, 0x78, 0x4f, 0x44, 0x5a,
+    0x6b, 0x0a, 0x4f, 0x47, 0x59, 0x33, 0x59, 0x6a, 0x4d, 0x70, 0x4d, 0x52, 0x59, 0x77, 0x46, 0x41,
+    0x59, 0x44, 0x56, 0x51, 0x51, 0x4c, 0x45, 0x77, 0x31, 0x50, 0x51, 0x30, 0x59, 0x67, 0x54, 0x55,
+    0x4d, 0x67, 0x52, 0x47, 0x56, 0x32, 0x61, 0x57, 0x4e, 0x6c, 0x4d, 0x52, 0x77, 0x77, 0x47, 0x67,
+    0x59, 0x44, 0x56, 0x51, 0x51, 0x4b, 0x45, 0x78, 0x4e, 0x54, 0x59, 0x57, 0x31, 0x7a, 0x64, 0x57,
+    0x35, 0x6e, 0x0a, 0x49, 0x45, 0x56, 0x73, 0x5a, 0x57, 0x4e, 0x30, 0x63, 0x6d, 0x39, 0x75, 0x61,
+    0x57, 0x4e, 0x7a, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45,
+    0x77, 0x4a, 0x4c, 0x55, 0x6a, 0x42, 0x5a, 0x4d, 0x42, 0x4d, 0x47, 0x42, 0x79, 0x71, 0x47, 0x53,
+    0x4d, 0x34, 0x39, 0x41, 0x67, 0x45, 0x47, 0x43, 0x43, 0x71, 0x47, 0x53, 0x4d, 0x34, 0x39, 0x41,
+    0x77, 0x45, 0x48, 0x0a, 0x41, 0x30, 0x49, 0x41, 0x42, 0x45, 0x45, 0x77, 0x51, 0x41, 0x52, 0x73,
+    0x62, 0x67, 0x43, 0x59, 0x2b, 0x43, 0x59, 0x6b, 0x49, 0x6a, 0x6b, 0x59, 0x6f, 0x47, 0x78, 0x6f,
+    0x52, 0x33, 0x75, 0x70, 0x33, 0x38, 0x59, 0x47, 0x54, 0x32, 0x63, 0x4b, 0x30, 0x31, 0x74, 0x6d,
+    0x32, 0x70, 0x38, 0x79, 0x4c, 0x4b, 0x4e, 0x73, 0x6d, 0x69, 0x53, 0x6f, 0x76, 0x46, 0x70, 0x4a,
+    0x32, 0x35, 0x63, 0x52, 0x0a, 0x74, 0x72, 0x57, 0x34, 0x41, 0x56, 0x7a, 0x76, 0x73, 0x64, 0x67,
+    0x62, 0x74, 0x72, 0x45, 0x62, 0x6b, 0x2b, 0x37, 0x73, 0x56, 0x61, 0x58, 0x50, 0x74, 0x78, 0x43,
+    0x6a, 0x67, 0x59, 0x41, 0x77, 0x66, 0x6a, 0x41, 0x4f, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x51, 0x38,
+    0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4d, 0x43, 0x41, 0x38, 0x67, 0x77, 0x4c, 0x67, 0x59,
+    0x44, 0x56, 0x52, 0x30, 0x66, 0x0a, 0x42, 0x43, 0x63, 0x77, 0x4a, 0x54, 0x41, 0x6a, 0x6f, 0x43,
+    0x47, 0x67, 0x48, 0x34, 0x59, 0x64, 0x61, 0x48, 0x52, 0x30, 0x63, 0x44, 0x6f, 0x76, 0x4c, 0x32,
+    0x4e, 0x68, 0x4c, 0x6e, 0x4e, 0x68, 0x62, 0x58, 0x4e, 0x31, 0x62, 0x6d, 0x64, 0x70, 0x62, 0x33,
+    0x52, 0x7a, 0x4c, 0x6d, 0x4e, 0x76, 0x62, 0x53, 0x39, 0x6a, 0x63, 0x6d, 0x77, 0x77, 0x50, 0x41,
+    0x59, 0x49, 0x4b, 0x77, 0x59, 0x42, 0x0a, 0x42, 0x51, 0x55, 0x48, 0x41, 0x51, 0x45, 0x45, 0x4d,
+    0x44, 0x41, 0x75, 0x4d, 0x43, 0x77, 0x47, 0x43, 0x43, 0x73, 0x47, 0x41, 0x51, 0x55, 0x46, 0x42,
+    0x7a, 0x41, 0x42, 0x68, 0x69, 0x42, 0x6f, 0x64, 0x48, 0x52, 0x77, 0x4f, 0x69, 0x38, 0x76, 0x62,
+    0x32, 0x4e, 0x7a, 0x63, 0x43, 0x31, 0x30, 0x5a, 0x58, 0x4e, 0x30, 0x4c, 0x6e, 0x4e, 0x68, 0x62,
+    0x58, 0x4e, 0x31, 0x62, 0x6d, 0x64, 0x70, 0x0a, 0x62, 0x33, 0x52, 0x7a, 0x4c, 0x6d, 0x4e, 0x76,
+    0x62, 0x54, 0x41, 0x4d, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6b, 0x6a, 0x4f, 0x50, 0x51, 0x51, 0x44,
+    0x41, 0x67, 0x55, 0x41, 0x41, 0x30, 0x6b, 0x41, 0x4d, 0x45, 0x59, 0x43, 0x49, 0x51, 0x43, 0x33,
+    0x58, 0x30, 0x42, 0x61, 0x4f, 0x49, 0x6f, 0x63, 0x4b, 0x4f, 0x45, 0x65, 0x44, 0x46, 0x52, 0x6b,
+    0x63, 0x66, 0x30, 0x48, 0x76, 0x68, 0x68, 0x67, 0x0a, 0x73, 0x6c, 0x65, 0x49, 0x52, 0x32, 0x49,
+    0x62, 0x6d, 0x66, 0x34, 0x6e, 0x69, 0x52, 0x52, 0x55, 0x38, 0x41, 0x49, 0x68, 0x41, 0x4f, 0x4d,
+    0x44, 0x31, 0x77, 0x45, 0x62, 0x50, 0x67, 0x34, 0x70, 0x47, 0x77, 0x49, 0x79, 0x65, 0x77, 0x63,
+    0x61, 0x6b, 0x76, 0x72, 0x4e, 0x4b, 0x66, 0x44, 0x79, 0x2b, 0x4f, 0x4e, 0x43, 0x6e, 0x4e, 0x6e,
+    0x43, 0x59, 0x57, 0x4a, 0x37, 0x39, 0x35, 0x4b, 0x49, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45,
+    0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d,
+    // NULL terminator
+    0x00,
+    // PEM encoded certificate
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49,
+    0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43,
+    0x6e, 0x44, 0x43, 0x43, 0x41, 0x6a, 0x2b, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x55,
+    0x44, 0x67, 0x45, 0x38, 0x4e, 0x50, 0x54, 0x4c, 0x46, 0x64, 0x6d, 0x68, 0x75, 0x72, 0x53, 0x69,
+    0x36, 0x33, 0x49, 0x31, 0x41, 0x77, 0x76, 0x37, 0x39, 0x49, 0x6b, 0x77, 0x44, 0x41, 0x59, 0x49,
+    0x4b, 0x6f, 0x5a, 0x49, 0x7a, 0x6a, 0x30, 0x45, 0x41, 0x77, 0x49, 0x46, 0x0a, 0x41, 0x44, 0x43,
+    0x42, 0x67, 0x7a, 0x45, 0x34, 0x4d, 0x44, 0x59, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d,
+    0x76, 0x55, 0x32, 0x46, 0x74, 0x63, 0x33, 0x56, 0x75, 0x5a, 0x79, 0x42, 0x46, 0x62, 0x47, 0x56,
+    0x6a, 0x64, 0x48, 0x4a, 0x76, 0x62, 0x6d, 0x6c, 0x6a, 0x63, 0x79, 0x42, 0x50, 0x51, 0x30, 0x59,
+    0x67, 0x54, 0x55, 0x4d, 0x67, 0x52, 0x47, 0x56, 0x32, 0x61, 0x57, 0x4e, 0x6c, 0x0a, 0x49, 0x46,
+    0x4e, 0x31, 0x59, 0x6b, 0x4e, 0x42, 0x49, 0x48, 0x59, 0x78, 0x49, 0x46, 0x52, 0x46, 0x55, 0x31,
+    0x51, 0x78, 0x48, 0x44, 0x41, 0x61, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x54, 0x45, 0x30,
+    0x39, 0x44, 0x52, 0x69, 0x42, 0x4e, 0x51, 0x79, 0x42, 0x45, 0x5a, 0x58, 0x5a, 0x70, 0x59, 0x32,
+    0x55, 0x67, 0x55, 0x33, 0x56, 0x69, 0x51, 0x30, 0x45, 0x78, 0x48, 0x44, 0x41, 0x61, 0x0a, 0x42,
+    0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x54, 0x45, 0x31, 0x4e, 0x68, 0x62, 0x58, 0x4e, 0x31, 0x62,
+    0x6d, 0x63, 0x67, 0x52, 0x57, 0x78, 0x6c, 0x59, 0x33, 0x52, 0x79, 0x62, 0x32, 0x35, 0x70, 0x59,
+    0x33, 0x4d, 0x78, 0x43, 0x7a, 0x41, 0x4a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41,
+    0x6b, 0x74, 0x53, 0x4d, 0x43, 0x41, 0x58, 0x44, 0x54, 0x45, 0x32, 0x4d, 0x54, 0x45, 0x79, 0x0a,
+    0x4e, 0x44, 0x41, 0x79, 0x4e, 0x44, 0x67, 0x78, 0x4d, 0x6c, 0x6f, 0x59, 0x44, 0x7a, 0x49, 0x77,
+    0x4e, 0x6a, 0x6b, 0x78, 0x4d, 0x6a, 0x4d, 0x78, 0x4d, 0x54, 0x51, 0x31, 0x4f, 0x54, 0x55, 0x35,
+    0x57, 0x6a, 0x43, 0x42, 0x6a, 0x54, 0x46, 0x49, 0x4d, 0x45, 0x59, 0x47, 0x41, 0x31, 0x55, 0x45,
+    0x41, 0x78, 0x4d, 0x2f, 0x54, 0x30, 0x4e, 0x47, 0x49, 0x45, 0x52, 0x6c, 0x64, 0x6d, 0x6c, 0x6a,
+    0x0a, 0x5a, 0x53, 0x42, 0x55, 0x52, 0x56, 0x4e, 0x55, 0x4f, 0x69, 0x42, 0x4f, 0x5a, 0x58, 0x52,
+    0x33, 0x62, 0x33, 0x4a, 0x72, 0x49, 0x43, 0x67, 0x77, 0x4e, 0x6a, 0x51, 0x79, 0x4e, 0x32, 0x45,
+    0x32, 0x4e, 0x53, 0x31, 0x69, 0x5a, 0x6a, 0x63, 0x30, 0x4c, 0x54, 0x51, 0x33, 0x4d, 0x7a, 0x63,
+    0x74, 0x4f, 0x54, 0x5a, 0x6d, 0x4d, 0x53, 0x30, 0x78, 0x59, 0x6d, 0x49, 0x78, 0x4f, 0x44, 0x5a,
+    0x6b, 0x0a, 0x4f, 0x47, 0x59, 0x33, 0x59, 0x6a, 0x4d, 0x70, 0x4d, 0x52, 0x59, 0x77, 0x46, 0x41,
+    0x59, 0x44, 0x56, 0x51, 0x51, 0x4c, 0x45, 0x77, 0x31, 0x50, 0x51, 0x30, 0x59, 0x67, 0x54, 0x55,
+    0x4d, 0x67, 0x52, 0x47, 0x56, 0x32, 0x61, 0x57, 0x4e, 0x6c, 0x4d, 0x52, 0x77, 0x77, 0x47, 0x67,
+    0x59, 0x44, 0x56, 0x51, 0x51, 0x4b, 0x45, 0x78, 0x4e, 0x54, 0x59, 0x57, 0x31, 0x7a, 0x64, 0x57,
+    0x35, 0x6e, 0x0a, 0x49, 0x45, 0x56, 0x73, 0x5a, 0x57, 0x4e, 0x30, 0x63, 0x6d, 0x39, 0x75, 0x61,
+    0x57, 0x4e, 0x7a, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45,
+    0x77, 0x4a, 0x4c, 0x55, 0x6a, 0x42, 0x5a, 0x4d, 0x42, 0x4d, 0x47, 0x42, 0x79, 0x71, 0x47, 0x53,
+    0x4d, 0x34, 0x39, 0x41, 0x67, 0x45, 0x47, 0x43, 0x43, 0x71, 0x47, 0x53, 0x4d, 0x34, 0x39, 0x41,
+    0x77, 0x45, 0x48, 0x0a, 0x41, 0x30, 0x49, 0x41, 0x42, 0x45, 0x45, 0x77, 0x51, 0x41, 0x52, 0x73,
+    0x62, 0x67, 0x43, 0x59, 0x2b, 0x43, 0x59, 0x6b, 0x49, 0x6a, 0x6b, 0x59, 0x6f, 0x47, 0x78, 0x6f,
+    0x52, 0x33, 0x75, 0x70, 0x33, 0x38, 0x59, 0x47, 0x54, 0x32, 0x63, 0x4b, 0x30, 0x31, 0x74, 0x6d,
+    0x32, 0x70, 0x38, 0x79, 0x4c, 0x4b, 0x4e, 0x73, 0x6d, 0x69, 0x53, 0x6f, 0x76, 0x46, 0x70, 0x4a,
+    0x32, 0x35, 0x63, 0x52, 0x0a, 0x74, 0x72, 0x57, 0x34, 0x41, 0x56, 0x7a, 0x76, 0x73, 0x64, 0x67,
+    0x62, 0x74, 0x72, 0x45, 0x62, 0x6b, 0x2b, 0x37, 0x73, 0x56, 0x61, 0x58, 0x50, 0x74, 0x78, 0x43,
+    0x6a, 0x67, 0x59, 0x41, 0x77, 0x66, 0x6a, 0x41, 0x4f, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x51, 0x38,
+    0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4d, 0x43, 0x41, 0x38, 0x67, 0x77, 0x4c, 0x67, 0x59,
+    0x44, 0x56, 0x52, 0x30, 0x66, 0x0a, 0x42, 0x43, 0x63, 0x77, 0x4a, 0x54, 0x41, 0x6a, 0x6f, 0x43,
+    0x47, 0x67, 0x48, 0x34, 0x59, 0x64, 0x61, 0x48, 0x52, 0x30, 0x63, 0x44, 0x6f, 0x76, 0x4c, 0x32,
+    0x4e, 0x68, 0x4c, 0x6e, 0x4e, 0x68, 0x62, 0x58, 0x4e, 0x31, 0x62, 0x6d, 0x64, 0x70, 0x62, 0x33,
+    0x52, 0x7a, 0x4c, 0x6d, 0x4e, 0x76, 0x62, 0x53, 0x39, 0x6a, 0x63, 0x6d, 0x77, 0x77, 0x50, 0x41,
+    0x59, 0x49, 0x4b, 0x77, 0x59, 0x42, 0x0a, 0x42, 0x51, 0x55, 0x48, 0x41, 0x51, 0x45, 0x45, 0x4d,
+    0x44, 0x41, 0x75, 0x4d, 0x43, 0x77, 0x47, 0x43, 0x43, 0x73, 0x47, 0x41, 0x51, 0x55, 0x46, 0x42,
+    0x7a, 0x41, 0x42, 0x68, 0x69, 0x42, 0x6f, 0x64, 0x48, 0x52, 0x77, 0x4f, 0x69, 0x38, 0x76, 0x62,
+    0x32, 0x4e, 0x7a, 0x63, 0x43, 0x31, 0x30, 0x5a, 0x58, 0x4e, 0x30, 0x4c, 0x6e, 0x4e, 0x68, 0x62,
+    0x58, 0x4e, 0x31, 0x62, 0x6d, 0x64, 0x70, 0x0a, 0x62, 0x33, 0x52, 0x7a, 0x4c, 0x6d, 0x4e, 0x76,
+    0x62, 0x54, 0x41, 0x4d, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6b, 0x6a, 0x4f, 0x50, 0x51, 0x51, 0x44,
+    0x41, 0x67, 0x55, 0x41, 0x41, 0x30, 0x6b, 0x41, 0x4d, 0x45, 0x59, 0x43, 0x49, 0x51, 0x43, 0x33,
+    0x58, 0x30, 0x42, 0x61, 0x4f, 0x49, 0x6f, 0x63, 0x4b, 0x4f, 0x45, 0x65, 0x44, 0x46, 0x52, 0x6b,
+    0x63, 0x66, 0x30, 0x48, 0x76, 0x68, 0x68, 0x67, 0x0a, 0x73, 0x6c, 0x65, 0x49, 0x52, 0x32, 0x49,
+    0x62, 0x6d, 0x66, 0x34, 0x6e, 0x69, 0x52, 0x52, 0x55, 0x38, 0x41, 0x49, 0x68, 0x41, 0x4f, 0x4d,
+    0x44, 0x31, 0x77, 0x45, 0x62, 0x50, 0x67, 0x34, 0x70, 0x47, 0x77, 0x49, 0x79, 0x65, 0x77, 0x63,
+    0x61, 0x6b, 0x76, 0x72, 0x4e, 0x4b, 0x66, 0x44, 0x79, 0x2b, 0x4f, 0x4e, 0x43, 0x6e, 0x4e, 0x6e,
+    0x43, 0x59, 0x57, 0x4a, 0x37, 0x39, 0x35, 0x4b, 0x49, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45,
+    0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d,
+    // garbage data
+    0x01, 0x02, 0x03, 0x04, 0x05,
+    // DER encoded certificate
+    0x30, 0x82, 0x02, 0x39, 0x30, 0x82, 0x01, 0xdf, 0x02, 0x01, 0x01, 0x30, 0x0a, 0x06, 0x08, 0x2a,
+    0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x7c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+    0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c,
+    0x09, 0x53, 0x6f, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
+    0x55, 0x04, 0x07, 0x0c, 0x08, 0x53, 0x6f, 0x6d, 0x65, 0x63, 0x69, 0x74, 0x79, 0x31, 0x0b, 0x30,
+    0x09, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x02, 0x42, 0x42, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03,
+    0x55, 0x04, 0x0b, 0x0c, 0x0d, 0x53, 0x65, 0x71, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x50, 0x61,
+    0x72, 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x02, 0x6f, 0x62, 0x31,
+    0x14, 0x30, 0x12, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x05,
+    0x6f, 0x62, 0x40, 0x62, 0x62, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x38, 0x31, 0x35, 0x31,
+    0x33, 0x31, 0x31, 0x31, 0x37, 0x5a, 0x17, 0x0d, 0x31, 0x39, 0x30, 0x35, 0x31, 0x32, 0x31, 0x33,
+    0x31, 0x31, 0x31, 0x37, 0x5a, 0x30, 0x81, 0xd4, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
+    0x06, 0x13, 0x02, 0x55, 0x41, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x03,
+    0x41, 0x73, 0x64, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x06, 0x47, 0x6f,
+    0x74, 0x68, 0x61, 0x6d, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x02, 0x5a,
+    0x5a, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x08, 0x42, 0x65, 0x61, 0x6d,
+    0x54, 0x65, 0x61, 0x6d, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+    0x01, 0x09, 0x01, 0x16, 0x0d, 0x72, 0x61, 0x69, 0x6c, 0x40, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x63,
+    0x6f, 0x6d, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x29, 0x75, 0x75, 0x69,
+    0x64, 0x3a, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x2d, 0x33, 0x32, 0x33, 0x32, 0x2d,
+    0x33, 0x32, 0x33, 0x32, 0x2d, 0x33, 0x32, 0x33, 0x32, 0x2d, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32,
+    0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x0c,
+    0x2b, 0x75, 0x73, 0x65, 0x72, 0x69, 0x64, 0x3a, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37,
+    0x2d, 0x36, 0x37, 0x36, 0x37, 0x2d, 0x36, 0x37, 0x36, 0x37, 0x2d, 0x36, 0x37, 0x36, 0x37, 0x2d,
+    0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x30, 0x59, 0x30, 0x13,
+    0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
+    0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xf7, 0x13, 0x5c, 0x73, 0x72, 0xce, 0x10, 0xe5, 0x09,
+    0x97, 0x9a, 0xf8, 0xf2, 0x70, 0xa6, 0x3d, 0x89, 0xf5, 0xc5, 0xe4, 0x44, 0xe2, 0x4a, 0xb6, 0x61,
+    0xa8, 0x12, 0x8d, 0xb4, 0xdc, 0x2b, 0x47, 0x84, 0x60, 0x0c, 0x25, 0x66, 0xe9, 0xe0, 0xe5, 0xac,
+    0x22, 0xbf, 0x15, 0xdc, 0x71, 0xb1, 0x88, 0x4f, 0x16, 0xbf, 0xc2, 0x77, 0x37, 0x76, 0x3f, 0xe0,
+    0x67, 0xc6, 0x1d, 0x23, 0xfe, 0x7c, 0x8b, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
+    0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x20, 0x47, 0xcc, 0x41, 0x8a, 0x27, 0xc7,
+    0xd0, 0xaa, 0xb4, 0xab, 0x85, 0xbf, 0x09, 0x4d, 0x06, 0xd7, 0x7e, 0x0d, 0x39, 0xf9, 0x36, 0xa1,
+    0x3d, 0x96, 0x23, 0xe2, 0x24, 0x64, 0x98, 0x63, 0x21, 0xba, 0x02, 0x21, 0x00, 0xe5, 0x8f, 0x7f,
+    0xf1, 0xa6, 0x82, 0x03, 0x6a, 0x18, 0x7a, 0x54, 0xe7, 0x0e, 0x25, 0x77, 0xd8, 0x46, 0xfa, 0x96,
+    0x8a, 0x7e, 0x14, 0xc4, 0xcb, 0x21, 0x32, 0x3e, 0x89, 0xd9, 0xba, 0x8c, 0x3f,
+    // PEM encoded certificate
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49,
+    0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0d, 0x0a, 0x4d, 0x49, 0x49,
+    0x45, 0x67, 0x44, 0x43, 0x43, 0x41, 0x32, 0x69, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49,
+    0x49, 0x58, 0x32, 0x37, 0x50, 0x44, 0x4d, 0x55, 0x38, 0x2b, 0x66, 0x6f, 0x77, 0x44, 0x51, 0x59,
+    0x4a, 0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x4c, 0x42, 0x51, 0x41,
+    0x77, 0x53, 0x54, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x0d, 0x0a, 0x42,
+    0x68, 0x4d, 0x43, 0x56, 0x56, 0x4d, 0x78, 0x45, 0x7a, 0x41, 0x52, 0x42, 0x67, 0x4e, 0x56, 0x42,
+    0x41, 0x6f, 0x54, 0x43, 0x6b, 0x64, 0x76, 0x62, 0x32, 0x64, 0x73, 0x5a, 0x53, 0x42, 0x4a, 0x62,
+    0x6d, 0x4d, 0x78, 0x4a, 0x54, 0x41, 0x6a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x4d, 0x54, 0x48,
+    0x45, 0x64, 0x76, 0x62, 0x32, 0x64, 0x73, 0x5a, 0x53, 0x42, 0x4a, 0x62, 0x6e, 0x52, 0x6c, 0x0d,
+    0x0a, 0x63, 0x6d, 0x35, 0x6c, 0x64, 0x43, 0x42, 0x42, 0x64, 0x58, 0x52, 0x6f, 0x62, 0x33, 0x4a,
+    0x70, 0x64, 0x48, 0x6b, 0x67, 0x52, 0x7a, 0x49, 0x77, 0x48, 0x68, 0x63, 0x4e, 0x4d, 0x54, 0x59,
+    0x78, 0x4d, 0x6a, 0x41, 0x78, 0x4d, 0x54, 0x51, 0x78, 0x4f, 0x44, 0x55, 0x32, 0x57, 0x68, 0x63,
+    0x4e, 0x4d, 0x54, 0x63, 0x77, 0x4d, 0x6a, 0x49, 0x7a, 0x4d, 0x54, 0x51, 0x78, 0x4e, 0x6a, 0x41,
+    0x77, 0x0d, 0x0a, 0x57, 0x6a, 0x42, 0x6f, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56,
+    0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x56, 0x55, 0x7a, 0x45, 0x54, 0x4d, 0x42, 0x45, 0x47, 0x41,
+    0x31, 0x55, 0x45, 0x43, 0x41, 0x77, 0x4b, 0x51, 0x32, 0x46, 0x73, 0x61, 0x57, 0x5a, 0x76, 0x63,
+    0x6d, 0x35, 0x70, 0x59, 0x54, 0x45, 0x57, 0x4d, 0x42, 0x51, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42,
+    0x77, 0x77, 0x4e, 0x0d, 0x0a, 0x54, 0x57, 0x39, 0x31, 0x62, 0x6e, 0x52, 0x68, 0x61, 0x57, 0x34,
+    0x67, 0x56, 0x6d, 0x6c, 0x6c, 0x64, 0x7a, 0x45, 0x54, 0x4d, 0x42, 0x45, 0x47, 0x41, 0x31, 0x55,
+    0x45, 0x43, 0x67, 0x77, 0x4b, 0x52, 0x32, 0x39, 0x76, 0x5a, 0x32, 0x78, 0x6c, 0x49, 0x45, 0x6c,
+    0x75, 0x59, 0x7a, 0x45, 0x58, 0x4d, 0x42, 0x55, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x77, 0x77,
+    0x4f, 0x61, 0x57, 0x31, 0x68, 0x0d, 0x0a, 0x63, 0x43, 0x35, 0x6e, 0x62, 0x57, 0x46, 0x70, 0x62,
+    0x43, 0x35, 0x6a, 0x62, 0x32, 0x30, 0x77, 0x67, 0x67, 0x45, 0x69, 0x4d, 0x41, 0x30, 0x47, 0x43,
+    0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, 0x51, 0x55, 0x41, 0x41,
+    0x34, 0x49, 0x42, 0x44, 0x77, 0x41, 0x77, 0x67, 0x67, 0x45, 0x4b, 0x41, 0x6f, 0x49, 0x42, 0x41,
+    0x51, 0x43, 0x61, 0x57, 0x66, 0x7a, 0x79, 0x0d, 0x0a, 0x75, 0x59, 0x6e, 0x66, 0x4e, 0x69, 0x54,
+    0x54, 0x61, 0x50, 0x69, 0x33, 0x6b, 0x57, 0x63, 0x6b, 0x65, 0x44, 0x4e, 0x48, 0x78, 0x6f, 0x6f,
+    0x5a, 0x71, 0x4d, 0x31, 0x36, 0x5a, 0x37, 0x5a, 0x38, 0x38, 0x5a, 0x63, 0x48, 0x69, 0x78, 0x79,
+    0x74, 0x68, 0x63, 0x38, 0x4e, 0x6c, 0x31, 0x32, 0x59, 0x45, 0x66, 0x46, 0x78, 0x66, 0x51, 0x4e,
+    0x77, 0x73, 0x2f, 0x65, 0x41, 0x4b, 0x31, 0x66, 0x6a, 0x0d, 0x0a, 0x41, 0x43, 0x59, 0x54, 0x57,
+    0x39, 0x39, 0x63, 0x45, 0x36, 0x31, 0x4e, 0x51, 0x68, 0x59, 0x48, 0x6c, 0x51, 0x67, 0x78, 0x6f,
+    0x62, 0x49, 0x39, 0x50, 0x44, 0x66, 0x61, 0x4f, 0x7a, 0x36, 0x4e, 0x6b, 0x72, 0x66, 0x62, 0x61,
+    0x79, 0x61, 0x53, 0x7a, 0x77, 0x4a, 0x39, 0x44, 0x76, 0x4b, 0x64, 0x49, 0x52, 0x4f, 0x64, 0x58,
+    0x36, 0x6d, 0x70, 0x72, 0x53, 0x2b, 0x79, 0x4c, 0x56, 0x47, 0x32, 0x0d, 0x0a, 0x2f, 0x4f, 0x49,
+    0x51, 0x37, 0x72, 0x37, 0x48, 0x32, 0x65, 0x62, 0x77, 0x48, 0x6d, 0x69, 0x58, 0x6f, 0x33, 0x5a,
+    0x30, 0x50, 0x4b, 0x62, 0x6c, 0x66, 0x4b, 0x44, 0x4b, 0x6b, 0x63, 0x67, 0x4b, 0x4c, 0x31, 0x73,
+    0x6b, 0x33, 0x42, 0x51, 0x65, 0x78, 0x49, 0x78, 0x32, 0x4a, 0x31, 0x53, 0x51, 0x4a, 0x61, 0x32,
+    0x53, 0x66, 0x55, 0x6e, 0x46, 0x6e, 0x61, 0x70, 0x62, 0x4f, 0x6a, 0x4a, 0x2b, 0x0d, 0x0a, 0x4a,
+    0x42, 0x68, 0x77, 0x4f, 0x71, 0x68, 0x67, 0x36, 0x6b, 0x43, 0x4b, 0x70, 0x2b, 0x4a, 0x4e, 0x4e,
+    0x59, 0x44, 0x53, 0x44, 0x47, 0x4b, 0x57, 0x47, 0x76, 0x49, 0x45, 0x44, 0x7a, 0x6f, 0x55, 0x7a,
+    0x66, 0x37, 0x35, 0x36, 0x2f, 0x63, 0x58, 0x57, 0x34, 0x6d, 0x36, 0x34, 0x74, 0x44, 0x78, 0x39,
+    0x54, 0x33, 0x4d, 0x66, 0x4b, 0x65, 0x55, 0x6a, 0x77, 0x31, 0x30, 0x68, 0x41, 0x72, 0x6f, 0x0d,
+    0x0a, 0x63, 0x33, 0x37, 0x62, 0x4a, 0x64, 0x69, 0x2f, 0x46, 0x66, 0x6c, 0x34, 0x7a, 0x38, 0x2f,
+    0x43, 0x75, 0x56, 0x55, 0x4f, 0x4c, 0x36, 0x76, 0x55, 0x6e, 0x75, 0x55, 0x35, 0x75, 0x6e, 0x46,
+    0x6a, 0x67, 0x6d, 0x52, 0x6a, 0x36, 0x6e, 0x65, 0x47, 0x53, 0x63, 0x33, 0x57, 0x4a, 0x31, 0x79,
+    0x76, 0x76, 0x56, 0x32, 0x6e, 0x4f, 0x37, 0x41, 0x50, 0x4b, 0x6e, 0x43, 0x4f, 0x68, 0x6c, 0x4e,
+    0x7a, 0x0d, 0x0a, 0x6e, 0x7a, 0x45, 0x6f, 0x69, 0x73, 0x73, 0x68, 0x6d, 0x6c, 0x7a, 0x78, 0x43,
+    0x62, 0x4d, 0x76, 0x41, 0x67, 0x4d, 0x42, 0x41, 0x41, 0x47, 0x6a, 0x67, 0x67, 0x46, 0x4c, 0x4d,
+    0x49, 0x49, 0x42, 0x52, 0x7a, 0x41, 0x64, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x53, 0x55, 0x45, 0x46,
+    0x6a, 0x41, 0x55, 0x42, 0x67, 0x67, 0x72, 0x42, 0x67, 0x45, 0x46, 0x42, 0x51, 0x63, 0x44, 0x41,
+    0x51, 0x59, 0x49, 0x0d, 0x0a, 0x4b, 0x77, 0x59, 0x42, 0x42, 0x51, 0x55, 0x48, 0x41, 0x77, 0x49,
+    0x77, 0x47, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x52, 0x42, 0x42, 0x49, 0x77, 0x45, 0x49, 0x49,
+    0x4f, 0x61, 0x57, 0x31, 0x68, 0x63, 0x43, 0x35, 0x6e, 0x62, 0x57, 0x46, 0x70, 0x62, 0x43, 0x35,
+    0x6a, 0x62, 0x32, 0x30, 0x77, 0x61, 0x41, 0x59, 0x49, 0x4b, 0x77, 0x59, 0x42, 0x42, 0x51, 0x55,
+    0x48, 0x41, 0x51, 0x45, 0x45, 0x0d, 0x0a, 0x58, 0x44, 0x42, 0x61, 0x4d, 0x43, 0x73, 0x47, 0x43,
+    0x43, 0x73, 0x47, 0x41, 0x51, 0x55, 0x46, 0x42, 0x7a, 0x41, 0x43, 0x68, 0x68, 0x39, 0x6f, 0x64,
+    0x48, 0x52, 0x77, 0x4f, 0x69, 0x38, 0x76, 0x63, 0x47, 0x74, 0x70, 0x4c, 0x6d, 0x64, 0x76, 0x62,
+    0x32, 0x64, 0x73, 0x5a, 0x53, 0x35, 0x6a, 0x62, 0x32, 0x30, 0x76, 0x52, 0x30, 0x6c, 0x42, 0x52,
+    0x7a, 0x49, 0x75, 0x59, 0x33, 0x4a, 0x30, 0x0d, 0x0a, 0x4d, 0x43, 0x73, 0x47, 0x43, 0x43, 0x73,
+    0x47, 0x41, 0x51, 0x55, 0x46, 0x42, 0x7a, 0x41, 0x42, 0x68, 0x68, 0x39, 0x6f, 0x64, 0x48, 0x52,
+    0x77, 0x4f, 0x69, 0x38, 0x76, 0x59, 0x32, 0x78, 0x70, 0x5a, 0x57, 0x35, 0x30, 0x63, 0x7a, 0x45,
+    0x75, 0x5a, 0x32, 0x39, 0x76, 0x5a, 0x32, 0x78, 0x6c, 0x4c, 0x6d, 0x4e, 0x76, 0x62, 0x53, 0x39,
+    0x76, 0x59, 0x33, 0x4e, 0x77, 0x4d, 0x42, 0x30, 0x47, 0x0d, 0x0a, 0x41, 0x31, 0x55, 0x64, 0x44,
+    0x67, 0x51, 0x57, 0x42, 0x42, 0x52, 0x75, 0x74, 0x41, 0x41, 0x45, 0x4b, 0x70, 0x75, 0x65, 0x4c,
+    0x4f, 0x4c, 0x4b, 0x33, 0x64, 0x6e, 0x56, 0x2b, 0x75, 0x59, 0x47, 0x68, 0x77, 0x68, 0x58, 0x6d,
+    0x6a, 0x41, 0x4d, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x52, 0x4d, 0x42, 0x41, 0x66, 0x38, 0x45, 0x41,
+    0x6a, 0x41, 0x41, 0x4d, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55, 0x64, 0x0d, 0x0a, 0x49, 0x77, 0x51,
+    0x59, 0x4d, 0x42, 0x61, 0x41, 0x46, 0x45, 0x72, 0x64, 0x42, 0x68, 0x59, 0x62, 0x76, 0x50, 0x5a,
+    0x6f, 0x74, 0x58, 0x62, 0x31, 0x67, 0x62, 0x61, 0x37, 0x59, 0x68, 0x71, 0x36, 0x57, 0x6f, 0x45,
+    0x76, 0x4d, 0x43, 0x45, 0x47, 0x41, 0x31, 0x55, 0x64, 0x49, 0x41, 0x51, 0x61, 0x4d, 0x42, 0x67,
+    0x77, 0x44, 0x41, 0x59, 0x4b, 0x4b, 0x77, 0x59, 0x42, 0x42, 0x41, 0x48, 0x57, 0x0d, 0x0a, 0x65,
+    0x51, 0x49, 0x46, 0x41, 0x54, 0x41, 0x49, 0x42, 0x67, 0x5a, 0x6e, 0x67, 0x51, 0x77, 0x42, 0x41,
+    0x67, 0x49, 0x77, 0x4d, 0x41, 0x59, 0x44, 0x56, 0x52, 0x30, 0x66, 0x42, 0x43, 0x6b, 0x77, 0x4a,
+    0x7a, 0x41, 0x6c, 0x6f, 0x43, 0x4f, 0x67, 0x49, 0x59, 0x59, 0x66, 0x61, 0x48, 0x52, 0x30, 0x63,
+    0x44, 0x6f, 0x76, 0x4c, 0x33, 0x42, 0x72, 0x61, 0x53, 0x35, 0x6e, 0x62, 0x32, 0x39, 0x6e, 0x0d,
+    0x0a, 0x62, 0x47, 0x55, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4c, 0x30, 0x64, 0x4a, 0x51, 0x55, 0x63,
+    0x79, 0x4c, 0x6d, 0x4e, 0x79, 0x62, 0x44, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69,
+    0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x41, 0x4f, 0x43, 0x41, 0x51, 0x45,
+    0x41, 0x58, 0x31, 0x7a, 0x42, 0x4a, 0x45, 0x2b, 0x6b, 0x4e, 0x2f, 0x39, 0x50, 0x42, 0x4a, 0x48,
+    0x59, 0x0d, 0x0a, 0x35, 0x74, 0x57, 0x62, 0x44, 0x57, 0x62, 0x75, 0x44, 0x63, 0x66, 0x32, 0x72,
+    0x31, 0x49, 0x35, 0x6f, 0x6e, 0x62, 0x38, 0x5a, 0x4e, 0x35, 0x44, 0x50, 0x61, 0x69, 0x32, 0x43,
+    0x75, 0x71, 0x43, 0x66, 0x49, 0x7a, 0x46, 0x50, 0x4c, 0x75, 0x37, 0x65, 0x6a, 0x61, 0x73, 0x31,
+    0x41, 0x74, 0x67, 0x33, 0x31, 0x6e, 0x38, 0x45, 0x35, 0x38, 0x55, 0x4d, 0x31, 0x51, 0x44, 0x45,
+    0x74, 0x71, 0x54, 0x0d, 0x0a, 0x58, 0x45, 0x47, 0x48, 0x61, 0x68, 0x6d, 0x74, 0x6e, 0x52, 0x30,
+    0x6e, 0x4f, 0x71, 0x61, 0x6e, 0x35, 0x63, 0x43, 0x6c, 0x54, 0x5a, 0x46, 0x6b, 0x61, 0x59, 0x46,
+    0x47, 0x79, 0x65, 0x54, 0x75, 0x76, 0x4f, 0x33, 0x69, 0x4e, 0x54, 0x47, 0x4d, 0x50, 0x69, 0x64,
+    0x4c, 0x48, 0x47, 0x51, 0x68, 0x55, 0x4b, 0x2f, 0x63, 0x4b, 0x6b, 0x67, 0x79, 0x52, 0x54, 0x68,
+    0x75, 0x38, 0x4f, 0x78, 0x6e, 0x0d, 0x0a, 0x2b, 0x67, 0x6d, 0x65, 0x33, 0x70, 0x66, 0x76, 0x49,
+    0x58, 0x74, 0x73, 0x61, 0x42, 0x4c, 0x71, 0x4e, 0x47, 0x69, 0x42, 0x38, 0x76, 0x69, 0x59, 0x2b,
+    0x6b, 0x48, 0x75, 0x72, 0x50, 0x64, 0x53, 0x4c, 0x36, 0x53, 0x72, 0x4a, 0x57, 0x65, 0x34, 0x76,
+    0x30, 0x39, 0x79, 0x62, 0x45, 0x6f, 0x74, 0x72, 0x30, 0x72, 0x34, 0x32, 0x30, 0x51, 0x74, 0x32,
+    0x33, 0x52, 0x69, 0x4a, 0x44, 0x69, 0x41, 0x0d, 0x0a, 0x54, 0x77, 0x48, 0x53, 0x78, 0x57, 0x6a,
+    0x64, 0x2f, 0x68, 0x64, 0x64, 0x43, 0x52, 0x75, 0x4b, 0x55, 0x4f, 0x6c, 0x36, 0x52, 0x56, 0x66,
+    0x4f, 0x4a, 0x56, 0x68, 0x4a, 0x75, 0x31, 0x4b, 0x65, 0x71, 0x6b, 0x70, 0x76, 0x78, 0x44, 0x37,
+    0x4d, 0x75, 0x6f, 0x39, 0x30, 0x6a, 0x41, 0x42, 0x4e, 0x44, 0x74, 0x4f, 0x4f, 0x43, 0x79, 0x5a,
+    0x61, 0x56, 0x6a, 0x7a, 0x36, 0x2f, 0x77, 0x75, 0x42, 0x0d, 0x0a, 0x53, 0x50, 0x64, 0x54, 0x34,
+    0x64, 0x2f, 0x4d, 0x49, 0x68, 0x51, 0x78, 0x49, 0x31, 0x76, 0x6a, 0x77, 0x48, 0x59, 0x51, 0x4d,
+    0x70, 0x54, 0x76, 0x4f, 0x38, 0x68, 0x34, 0x68, 0x46, 0x36, 0x45, 0x71, 0x73, 0x58, 0x31, 0x36,
+    0x70, 0x52, 0x41, 0x4a, 0x6b, 0x6e, 0x47, 0x6e, 0x63, 0x38, 0x4a, 0x59, 0x4d, 0x76, 0x62, 0x70,
+    0x56, 0x6e, 0x79, 0x63, 0x6e, 0x4a, 0x73, 0x43, 0x68, 0x65, 0x73, 0x0d, 0x0a, 0x46, 0x4c, 0x78,
+    0x6f, 0x6c, 0x77, 0x3d, 0x3d, 0x0d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20,
+    0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+    // \n NULL terminator
+    0x0a, 0x00,
+    // PEM encoded certificate
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49,
+    0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x44,
+    0x38, 0x44, 0x43, 0x43, 0x41, 0x74, 0x69, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x44,
+    0x41, 0x6a, 0x71, 0x53, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33,
+    0x44, 0x51, 0x45, 0x42, 0x43, 0x77, 0x55, 0x41, 0x4d, 0x45, 0x49, 0x78, 0x43, 0x7a, 0x41, 0x4a,
+    0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6c, 0x56, 0x54, 0x0a, 0x4d, 0x52, 0x59,
+    0x77, 0x46, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4b, 0x45, 0x77, 0x31, 0x48, 0x5a, 0x57, 0x39,
+    0x55, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x42, 0x4a, 0x62, 0x6d, 0x4d, 0x75, 0x4d, 0x52, 0x73,
+    0x77, 0x47, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x4a, 0x48, 0x5a, 0x57, 0x39,
+    0x55, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x42, 0x48, 0x62, 0x47, 0x39, 0x69, 0x0a, 0x59, 0x57,
+    0x77, 0x67, 0x51, 0x30, 0x45, 0x77, 0x48, 0x68, 0x63, 0x4e, 0x4d, 0x54, 0x55, 0x77, 0x4e, 0x44,
+    0x41, 0x78, 0x4d, 0x44, 0x41, 0x77, 0x4d, 0x44, 0x41, 0x77, 0x57, 0x68, 0x63, 0x4e, 0x4d, 0x54,
+    0x63, 0x78, 0x4d, 0x6a, 0x4d, 0x78, 0x4d, 0x6a, 0x4d, 0x31, 0x4f, 0x54, 0x55, 0x35, 0x57, 0x6a,
+    0x42, 0x4a, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0a, 0x45,
+    0x77, 0x4a, 0x56, 0x55, 0x7a, 0x45, 0x54, 0x4d, 0x42, 0x45, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43,
+    0x68, 0x4d, 0x4b, 0x52, 0x32, 0x39, 0x76, 0x5a, 0x32, 0x78, 0x6c, 0x49, 0x45, 0x6c, 0x75, 0x59,
+    0x7a, 0x45, 0x6c, 0x4d, 0x43, 0x4d, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d, 0x63, 0x52,
+    0x32, 0x39, 0x76, 0x5a, 0x32, 0x78, 0x6c, 0x49, 0x45, 0x6c, 0x75, 0x64, 0x47, 0x56, 0x79, 0x0a,
+    0x62, 0x6d, 0x56, 0x30, 0x49, 0x45, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6d, 0x6c, 0x30,
+    0x65, 0x53, 0x42, 0x48, 0x4d, 0x6a, 0x43, 0x43, 0x41, 0x53, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4a,
+    0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44,
+    0x67, 0x67, 0x45, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x51, 0x6f, 0x43, 0x67, 0x67, 0x45, 0x42,
+    0x0a, 0x41, 0x4a, 0x77, 0x71, 0x42, 0x48, 0x64, 0x63, 0x32, 0x46, 0x43, 0x52, 0x4f, 0x67, 0x61,
+    0x6a, 0x67, 0x75, 0x44, 0x59, 0x55, 0x45, 0x69, 0x38, 0x69, 0x54, 0x2f, 0x78, 0x47, 0x58, 0x41,
+    0x61, 0x69, 0x45, 0x5a, 0x2b, 0x34, 0x49, 0x2f, 0x46, 0x38, 0x59, 0x6e, 0x4f, 0x49, 0x65, 0x35,
+    0x61, 0x2f, 0x6d, 0x45, 0x4e, 0x74, 0x7a, 0x4a, 0x45, 0x69, 0x61, 0x42, 0x30, 0x43, 0x31, 0x4e,
+    0x50, 0x0a, 0x56, 0x61, 0x54, 0x4f, 0x67, 0x6d, 0x4b, 0x56, 0x37, 0x75, 0x74, 0x5a, 0x58, 0x38,
+    0x62, 0x68, 0x42, 0x59, 0x41, 0x53, 0x78, 0x46, 0x36, 0x55, 0x50, 0x37, 0x78, 0x62, 0x53, 0x44,
+    0x6a, 0x30, 0x55, 0x2f, 0x63, 0x6b, 0x35, 0x76, 0x75, 0x52, 0x36, 0x52, 0x58, 0x45, 0x7a, 0x2f,
+    0x52, 0x54, 0x44, 0x66, 0x52, 0x4b, 0x2f, 0x4a, 0x39, 0x55, 0x33, 0x6e, 0x32, 0x2b, 0x6f, 0x47,
+    0x74, 0x76, 0x0a, 0x68, 0x38, 0x44, 0x51, 0x55, 0x42, 0x38, 0x6f, 0x4d, 0x41, 0x4e, 0x41, 0x32,
+    0x67, 0x68, 0x7a, 0x55, 0x57, 0x78, 0x2f, 0x2f, 0x7a, 0x6f, 0x38, 0x70, 0x7a, 0x63, 0x47, 0x6a,
+    0x72, 0x31, 0x4c, 0x45, 0x51, 0x54, 0x72, 0x66, 0x53, 0x54, 0x65, 0x35, 0x76, 0x6e, 0x38, 0x4d,
+    0x58, 0x48, 0x37, 0x6c, 0x4e, 0x56, 0x67, 0x38, 0x79, 0x35, 0x4b, 0x72, 0x30, 0x4c, 0x53, 0x79,
+    0x2b, 0x72, 0x45, 0x0a, 0x61, 0x68, 0x71, 0x79, 0x7a, 0x46, 0x50, 0x64, 0x46, 0x55, 0x75, 0x4c,
+    0x48, 0x38, 0x67, 0x5a, 0x59, 0x52, 0x2f, 0x4e, 0x6e, 0x61, 0x67, 0x2b, 0x59, 0x79, 0x75, 0x45,
+    0x4e, 0x57, 0x6c, 0x6c, 0x68, 0x4d, 0x67, 0x5a, 0x78, 0x55, 0x59, 0x69, 0x2b, 0x46, 0x4f, 0x56,
+    0x76, 0x75, 0x4f, 0x41, 0x53, 0x68, 0x44, 0x47, 0x4b, 0x75, 0x79, 0x36, 0x6c, 0x79, 0x41, 0x52,
+    0x78, 0x7a, 0x6d, 0x5a, 0x0a, 0x45, 0x41, 0x53, 0x67, 0x38, 0x47, 0x46, 0x36, 0x6c, 0x53, 0x57,
+    0x4d, 0x54, 0x6c, 0x4a, 0x31, 0x34, 0x72, 0x62, 0x74, 0x43, 0x4d, 0x6f, 0x55, 0x2f, 0x4d, 0x34,
+    0x69, 0x61, 0x72, 0x4e, 0x4f, 0x7a, 0x30, 0x59, 0x44, 0x6c, 0x35, 0x63, 0x44, 0x66, 0x73, 0x43,
+    0x78, 0x33, 0x6e, 0x75, 0x76, 0x52, 0x54, 0x50, 0x50, 0x75, 0x6a, 0x35, 0x78, 0x74, 0x39, 0x37,
+    0x30, 0x4a, 0x53, 0x58, 0x43, 0x0a, 0x44, 0x54, 0x57, 0x4a, 0x6e, 0x5a, 0x33, 0x37, 0x44, 0x68,
+    0x46, 0x35, 0x69, 0x52, 0x34, 0x33, 0x78, 0x61, 0x2b, 0x4f, 0x63, 0x6d, 0x6b, 0x43, 0x41, 0x77,
+    0x45, 0x41, 0x41, 0x61, 0x4f, 0x42, 0x35, 0x7a, 0x43, 0x42, 0x35, 0x44, 0x41, 0x66, 0x42, 0x67,
+    0x4e, 0x56, 0x48, 0x53, 0x4d, 0x45, 0x47, 0x44, 0x41, 0x57, 0x67, 0x42, 0x54, 0x41, 0x65, 0x70,
+    0x68, 0x6f, 0x6a, 0x59, 0x6e, 0x37, 0x0a, 0x71, 0x77, 0x56, 0x6b, 0x44, 0x42, 0x46, 0x39, 0x71,
+    0x6e, 0x31, 0x6c, 0x75, 0x4d, 0x72, 0x4d, 0x54, 0x6a, 0x41, 0x64, 0x42, 0x67, 0x4e, 0x56, 0x48,
+    0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x53, 0x74, 0x30, 0x47, 0x46, 0x68, 0x75, 0x38, 0x39,
+    0x6d, 0x69, 0x31, 0x64, 0x76, 0x57, 0x42, 0x74, 0x72, 0x74, 0x69, 0x47, 0x72, 0x70, 0x61, 0x67,
+    0x53, 0x38, 0x77, 0x44, 0x67, 0x59, 0x44, 0x0a, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2f,
+    0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4d, 0x43, 0x34, 0x47, 0x43, 0x43, 0x73, 0x47,
+    0x41, 0x51, 0x55, 0x46, 0x42, 0x77, 0x45, 0x42, 0x42, 0x43, 0x49, 0x77, 0x49, 0x44, 0x41, 0x65,
+    0x42, 0x67, 0x67, 0x72, 0x42, 0x67, 0x45, 0x46, 0x42, 0x51, 0x63, 0x77, 0x41, 0x59, 0x59, 0x53,
+    0x61, 0x48, 0x52, 0x30, 0x63, 0x44, 0x6f, 0x76, 0x0a, 0x4c, 0x32, 0x63, 0x75, 0x63, 0x33, 0x6c,
+    0x74, 0x59, 0x32, 0x51, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4d, 0x42, 0x49, 0x47, 0x41, 0x31, 0x55,
+    0x64, 0x45, 0x77, 0x45, 0x42, 0x2f, 0x77, 0x51, 0x49, 0x4d, 0x41, 0x59, 0x42, 0x41, 0x66, 0x38,
+    0x43, 0x41, 0x51, 0x41, 0x77, 0x4e, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x66, 0x42, 0x43, 0x34,
+    0x77, 0x4c, 0x44, 0x41, 0x71, 0x6f, 0x43, 0x69, 0x67, 0x0a, 0x4a, 0x6f, 0x59, 0x6b, 0x61, 0x48,
+    0x52, 0x30, 0x63, 0x44, 0x6f, 0x76, 0x4c, 0x32, 0x63, 0x75, 0x63, 0x33, 0x6c, 0x74, 0x59, 0x32,
+    0x49, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4c, 0x32, 0x4e, 0x79, 0x62, 0x48, 0x4d, 0x76, 0x5a, 0x33,
+    0x52, 0x6e, 0x62, 0x47, 0x39, 0x69, 0x59, 0x57, 0x77, 0x75, 0x59, 0x33, 0x4a, 0x73, 0x4d, 0x42,
+    0x63, 0x47, 0x41, 0x31, 0x55, 0x64, 0x49, 0x41, 0x51, 0x51, 0x0a, 0x4d, 0x41, 0x34, 0x77, 0x44,
+    0x41, 0x59, 0x4b, 0x4b, 0x77, 0x59, 0x42, 0x42, 0x41, 0x48, 0x57, 0x65, 0x51, 0x49, 0x46, 0x41,
+    0x54, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41,
+    0x51, 0x73, 0x46, 0x41, 0x41, 0x4f, 0x43, 0x41, 0x51, 0x45, 0x41, 0x43, 0x45, 0x34, 0x45, 0x70,
+    0x34, 0x42, 0x2f, 0x45, 0x42, 0x5a, 0x44, 0x58, 0x67, 0x4b, 0x74, 0x0a, 0x31, 0x30, 0x4b, 0x41,
+    0x39, 0x4c, 0x43, 0x4f, 0x30, 0x71, 0x36, 0x7a, 0x36, 0x78, 0x46, 0x39, 0x6b, 0x49, 0x51, 0x59,
+    0x66, 0x65, 0x65, 0x51, 0x46, 0x66, 0x74, 0x4a, 0x66, 0x36, 0x69, 0x5a, 0x42, 0x5a, 0x47, 0x37,
+    0x65, 0x73, 0x6e, 0x57, 0x50, 0x44, 0x63, 0x59, 0x43, 0x5a, 0x71, 0x32, 0x78, 0x35, 0x49, 0x67,
+    0x42, 0x7a, 0x55, 0x7a, 0x43, 0x65, 0x51, 0x6f, 0x59, 0x33, 0x49, 0x4e, 0x0a, 0x74, 0x4f, 0x41,
+    0x79, 0x6e, 0x49, 0x65, 0x59, 0x78, 0x42, 0x74, 0x32, 0x69, 0x57, 0x66, 0x42, 0x55, 0x46, 0x69,
+    0x77, 0x45, 0x36, 0x6f, 0x54, 0x47, 0x68, 0x73, 0x79, 0x70, 0x62, 0x37, 0x71, 0x45, 0x5a, 0x56,
+    0x4d, 0x53, 0x47, 0x4e, 0x4a, 0x36, 0x5a, 0x6c, 0x64, 0x49, 0x44, 0x66, 0x4d, 0x2f, 0x69, 0x70,
+    0x70, 0x55, 0x52, 0x61, 0x56, 0x53, 0x36, 0x6e, 0x65, 0x53, 0x59, 0x4c, 0x41, 0x0a, 0x45, 0x48,
+    0x44, 0x30, 0x4c, 0x50, 0x50, 0x73, 0x76, 0x43, 0x51, 0x6b, 0x30, 0x45, 0x36, 0x73, 0x70, 0x64,
+    0x6c, 0x65, 0x48, 0x6d, 0x32, 0x53, 0x77, 0x61, 0x65, 0x73, 0x53, 0x44, 0x57, 0x42, 0x2b, 0x65,
+    0x58, 0x6b, 0x6e, 0x47, 0x56, 0x70, 0x7a, 0x59, 0x65, 0x6b, 0x51, 0x56, 0x41, 0x2f, 0x4c, 0x6c,
+    0x65, 0x6c, 0x6b, 0x56, 0x45, 0x53, 0x57, 0x41, 0x36, 0x4d, 0x43, 0x61, 0x47, 0x73, 0x0a, 0x65,
+    0x71, 0x51, 0x53, 0x70, 0x53, 0x66, 0x7a, 0x6d, 0x68, 0x43, 0x58, 0x66, 0x56, 0x55, 0x44, 0x42,
+    0x76, 0x64, 0x6d, 0x57, 0x46, 0x39, 0x66, 0x5a, 0x4f, 0x47, 0x72, 0x58, 0x57, 0x32, 0x6c, 0x4f,
+    0x55, 0x68, 0x31, 0x6d, 0x45, 0x77, 0x70, 0x57, 0x6a, 0x71, 0x4e, 0x30, 0x79, 0x76, 0x4b, 0x6e,
+    0x46, 0x55, 0x45, 0x76, 0x2f, 0x54, 0x6d, 0x46, 0x4e, 0x57, 0x41, 0x72, 0x43, 0x62, 0x74, 0x0a,
+    0x46, 0x34, 0x6d, 0x6d, 0x6b, 0x32, 0x78, 0x63, 0x70, 0x4d, 0x79, 0x34, 0x38, 0x47, 0x61, 0x4f,
+    0x5a, 0x4f, 0x4e, 0x39, 0x6d, 0x75, 0x49, 0x41, 0x73, 0x30, 0x6e, 0x48, 0x35, 0x41, 0x71, 0x71,
+    0x33, 0x56, 0x75, 0x44, 0x78, 0x33, 0x43, 0x51, 0x52, 0x6b, 0x36, 0x2b, 0x30, 0x4e, 0x74, 0x5a,
+    0x6c, 0x6d, 0x77, 0x75, 0x39, 0x52, 0x59, 0x32, 0x33, 0x6e, 0x48, 0x4d, 0x41, 0x63, 0x49, 0x53,
+    0x0a, 0x77, 0x53, 0x48, 0x47, 0x46, 0x67, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45,
+    0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d,
+    // \r \n NULL terminator
+    0x0d, 0x0a, 0x00,
+    // DER encoded certificate
+    0x30, 0x82, 0x02, 0x39, 0x30, 0x82, 0x01, 0xdf, 0x02, 0x01, 0x01, 0x30, 0x0a, 0x06, 0x08, 0x2a,
+    0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x7c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+    0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c,
+    0x09, 0x53, 0x6f, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
+    0x55, 0x04, 0x07, 0x0c, 0x08, 0x53, 0x6f, 0x6d, 0x65, 0x63, 0x69, 0x74, 0x79, 0x31, 0x0b, 0x30,
+    0x09, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x02, 0x42, 0x42, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03,
+    0x55, 0x04, 0x0b, 0x0c, 0x0d, 0x53, 0x65, 0x71, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x50, 0x61,
+    0x72, 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x02, 0x6f, 0x62, 0x31,
+    0x14, 0x30, 0x12, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x05,
+    0x6f, 0x62, 0x40, 0x62, 0x62, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x38, 0x31, 0x35, 0x31,
+    0x33, 0x31, 0x31, 0x31, 0x37, 0x5a, 0x17, 0x0d, 0x31, 0x39, 0x30, 0x35, 0x31, 0x32, 0x31, 0x33,
+    0x31, 0x31, 0x31, 0x37, 0x5a, 0x30, 0x81, 0xd4, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
+    0x06, 0x13, 0x02, 0x55, 0x41, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x03,
+    0x41, 0x73, 0x64, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x06, 0x47, 0x6f,
+    0x74, 0x68, 0x61, 0x6d, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x02, 0x5a,
+    0x5a, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x08, 0x42, 0x65, 0x61, 0x6d,
+    0x54, 0x65, 0x61, 0x6d, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+    0x01, 0x09, 0x01, 0x16, 0x0d, 0x72, 0x61, 0x69, 0x6c, 0x40, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x63,
+    0x6f, 0x6d, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x29, 0x75, 0x75, 0x69,
+    0x64, 0x3a, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x2d, 0x33, 0x32, 0x33, 0x32, 0x2d,
+    0x33, 0x32, 0x33, 0x32, 0x2d, 0x33, 0x32, 0x33, 0x32, 0x2d, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32,
+    0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x0c,
+    0x2b, 0x75, 0x73, 0x65, 0x72, 0x69, 0x64, 0x3a, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37,
+    0x2d, 0x36, 0x37, 0x36, 0x37, 0x2d, 0x36, 0x37, 0x36, 0x37, 0x2d, 0x36, 0x37, 0x36, 0x37, 0x2d,
+    0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x30, 0x59, 0x30, 0x13,
+    0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
+    0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xf7, 0x13, 0x5c, 0x73, 0x72, 0xce, 0x10, 0xe5, 0x09,
+    0x97, 0x9a, 0xf8, 0xf2, 0x70, 0xa6, 0x3d, 0x89, 0xf5, 0xc5, 0xe4, 0x44, 0xe2, 0x4a, 0xb6, 0x61,
+    0xa8, 0x12, 0x8d, 0xb4, 0xdc, 0x2b, 0x47, 0x84, 0x60, 0x0c, 0x25, 0x66, 0xe9, 0xe0, 0xe5, 0xac,
+    0x22, 0xbf, 0x15, 0xdc, 0x71, 0xb1, 0x88, 0x4f, 0x16, 0xbf, 0xc2, 0x77, 0x37, 0x76, 0x3f, 0xe0,
+    0x67, 0xc6, 0x1d, 0x23, 0xfe, 0x7c, 0x8b, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
+    0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x20, 0x47, 0xcc, 0x41, 0x8a, 0x27, 0xc7,
+    0xd0, 0xaa, 0xb4, 0xab, 0x85, 0xbf, 0x09, 0x4d, 0x06, 0xd7, 0x7e, 0x0d, 0x39, 0xf9, 0x36, 0xa1,
+    0x3d, 0x96, 0x23, 0xe2, 0x24, 0x64, 0x98, 0x63, 0x21, 0xba, 0x02, 0x21, 0x00, 0xe5, 0x8f, 0x7f,
+    0xf1, 0xa6, 0x82, 0x03, 0x6a, 0x18, 0x7a, 0x54, 0xe7, 0x0e, 0x25, 0x77, 0xd8, 0x46, 0xfa, 0x96,
+    0x8a, 0x7e, 0x14, 0xc4, 0xcb, 0x21, 0x32, 0x3e, 0x89, 0xd9, 0xba, 0x8c, 0x3f,
+    // DER encoded certificate
+    0x30, 0x82, 0x02, 0x39, 0x30, 0x82, 0x01, 0xdf, 0x02, 0x01, 0x01, 0x30, 0x0a, 0x06, 0x08, 0x2a,
+    0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x7c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+    0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c,
+    0x09, 0x53, 0x6f, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
+    0x55, 0x04, 0x07, 0x0c, 0x08, 0x53, 0x6f, 0x6d, 0x65, 0x63, 0x69, 0x74, 0x79, 0x31, 0x0b, 0x30,
+    0x09, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x02, 0x42, 0x42, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03,
+    0x55, 0x04, 0x0b, 0x0c, 0x0d, 0x53, 0x65, 0x71, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x50, 0x61,
+    0x72, 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x02, 0x6f, 0x62, 0x31,
+    0x14, 0x30, 0x12, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x05,
+    0x6f, 0x62, 0x40, 0x62, 0x62, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x38, 0x31, 0x35, 0x31,
+    0x33, 0x31, 0x31, 0x31, 0x37, 0x5a, 0x17, 0x0d, 0x31, 0x39, 0x30, 0x35, 0x31, 0x32, 0x31, 0x33,
+    0x31, 0x31, 0x31, 0x37, 0x5a, 0x30, 0x81, 0xd4, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
+    0x06, 0x13, 0x02, 0x55, 0x41, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x03,
+    0x41, 0x73, 0x64, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x06, 0x47, 0x6f,
+    0x74, 0x68, 0x61, 0x6d, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x02, 0x5a,
+    0x5a, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x08, 0x42, 0x65, 0x61, 0x6d,
+    0x54, 0x65, 0x61, 0x6d, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+    0x01, 0x09, 0x01, 0x16, 0x0d, 0x72, 0x61, 0x69, 0x6c, 0x40, 0x6d, 0x61, 0x69, 0x6c, 0x2e, 0x63,
+    0x6f, 0x6d, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x29, 0x75, 0x75, 0x69,
+    0x64, 0x3a, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x2d, 0x33, 0x32, 0x33, 0x32, 0x2d,
+    0x33, 0x32, 0x33, 0x32, 0x2d, 0x33, 0x32, 0x33, 0x32, 0x2d, 0x33, 0x32, 0x33, 0x32, 0x33, 0x32,
+    0x33, 0x32, 0x33, 0x32, 0x33, 0x32, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x0c,
+    0x2b, 0x75, 0x73, 0x65, 0x72, 0x69, 0x64, 0x3a, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37,
+    0x2d, 0x36, 0x37, 0x36, 0x37, 0x2d, 0x36, 0x37, 0x36, 0x37, 0x2d, 0x36, 0x37, 0x36, 0x37, 0x2d,
+    0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x30, 0x59, 0x30, 0x13,
+    0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
+    0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xf7, 0x13, 0x5c, 0x73, 0x72, 0xce, 0x10, 0xe5, 0x09,
+    0x97, 0x9a, 0xf8, 0xf2, 0x70, 0xa6, 0x3d, 0x89, 0xf5, 0xc5, 0xe4, 0x44, 0xe2, 0x4a, 0xb6, 0x61,
+    0xa8, 0x12, 0x8d, 0xb4, 0xdc, 0x2b, 0x47, 0x84, 0x60, 0x0c, 0x25, 0x66, 0xe9, 0xe0, 0xe5, 0xac,
+    0x22, 0xbf, 0x15, 0xdc, 0x71, 0xb1, 0x88, 0x4f, 0x16, 0xbf, 0xc2, 0x77, 0x37, 0x76, 0x3f, 0xe0,
+    0x67, 0xc6, 0x1d, 0x23, 0xfe, 0x7c, 0x8b, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d,
+    0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x20, 0x47, 0xcc, 0x41, 0x8a, 0x27, 0xc7,
+    0xd0, 0xaa, 0xb4, 0xab, 0x85, 0xbf, 0x09, 0x4d, 0x06, 0xd7, 0x7e, 0x0d, 0x39, 0xf9, 0x36, 0xa1,
+    0x3d, 0x96, 0x23, 0xe2, 0x24, 0x64, 0x98, 0x63, 0x21, 0xba, 0x02, 0x21, 0x00, 0xe5, 0x8f, 0x7f,
+    0xf1, 0xa6, 0x82, 0x03, 0x6a, 0x18, 0x7a, 0x54, 0xe7, 0x0e, 0x25, 0x77, 0xd8, 0x46, 0xfa, 0x96,
+    0x8a, 0x7e, 0x14, 0xc4, 0xcb, 0x21, 0x32, 0x3e, 0x89, 0xd9, 0xba, 0x8c, 0x3f,
+    // NULL \n terminator
+    0x00, 0x0a,
+    // PEM encoded certificate
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49,
+    0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43,
+    0x6e, 0x44, 0x43, 0x43, 0x41, 0x6a, 0x2b, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x55,
+    0x44, 0x67, 0x45, 0x38, 0x4e, 0x50, 0x54, 0x4c, 0x46, 0x64, 0x6d, 0x68, 0x75, 0x72, 0x53, 0x69,
+    0x36, 0x33, 0x49, 0x31, 0x41, 0x77, 0x76, 0x37, 0x39, 0x49, 0x6b, 0x77, 0x44, 0x41, 0x59, 0x49,
+    0x4b, 0x6f, 0x5a, 0x49, 0x7a, 0x6a, 0x30, 0x45, 0x41, 0x77, 0x49, 0x46, 0x0a, 0x41, 0x44, 0x43,
+    0x42, 0x67, 0x7a, 0x45, 0x34, 0x4d, 0x44, 0x59, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d,
+    0x76, 0x55, 0x32, 0x46, 0x74, 0x63, 0x33, 0x56, 0x75, 0x5a, 0x79, 0x42, 0x46, 0x62, 0x47, 0x56,
+    0x6a, 0x64, 0x48, 0x4a, 0x76, 0x62, 0x6d, 0x6c, 0x6a, 0x63, 0x79, 0x42, 0x50, 0x51, 0x30, 0x59,
+    0x67, 0x54, 0x55, 0x4d, 0x67, 0x52, 0x47, 0x56, 0x32, 0x61, 0x57, 0x4e, 0x6c, 0x0a, 0x49, 0x46,
+    0x4e, 0x31, 0x59, 0x6b, 0x4e, 0x42, 0x49, 0x48, 0x59, 0x78, 0x49, 0x46, 0x52, 0x46, 0x55, 0x31,
+    0x51, 0x78, 0x48, 0x44, 0x41, 0x61, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x54, 0x45, 0x30,
+    0x39, 0x44, 0x52, 0x69, 0x42, 0x4e, 0x51, 0x79, 0x42, 0x45, 0x5a, 0x58, 0x5a, 0x70, 0x59, 0x32,
+    0x55, 0x67, 0x55, 0x33, 0x56, 0x69, 0x51, 0x30, 0x45, 0x78, 0x48, 0x44, 0x41, 0x61, 0x0a, 0x42,
+    0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x54, 0x45, 0x31, 0x4e, 0x68, 0x62, 0x58, 0x4e, 0x31, 0x62,
+    0x6d, 0x63, 0x67, 0x52, 0x57, 0x78, 0x6c, 0x59, 0x33, 0x52, 0x79, 0x62, 0x32, 0x35, 0x70, 0x59,
+    0x33, 0x4d, 0x78, 0x43, 0x7a, 0x41, 0x4a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41,
+    0x6b, 0x74, 0x53, 0x4d, 0x43, 0x41, 0x58, 0x44, 0x54, 0x45, 0x32, 0x4d, 0x54, 0x45, 0x79, 0x0a,
+    0x4e, 0x44, 0x41, 0x79, 0x4e, 0x44, 0x67, 0x78, 0x4d, 0x6c, 0x6f, 0x59, 0x44, 0x7a, 0x49, 0x77,
+    0x4e, 0x6a, 0x6b, 0x78, 0x4d, 0x6a, 0x4d, 0x78, 0x4d, 0x54, 0x51, 0x31, 0x4f, 0x54, 0x55, 0x35,
+    0x57, 0x6a, 0x43, 0x42, 0x6a, 0x54, 0x46, 0x49, 0x4d, 0x45, 0x59, 0x47, 0x41, 0x31, 0x55, 0x45,
+    0x41, 0x78, 0x4d, 0x2f, 0x54, 0x30, 0x4e, 0x47, 0x49, 0x45, 0x52, 0x6c, 0x64, 0x6d, 0x6c, 0x6a,
+    0x0a, 0x5a, 0x53, 0x42, 0x55, 0x52, 0x56, 0x4e, 0x55, 0x4f, 0x69, 0x42, 0x4f, 0x5a, 0x58, 0x52,
+    0x33, 0x62, 0x33, 0x4a, 0x72, 0x49, 0x43, 0x67, 0x77, 0x4e, 0x6a, 0x51, 0x79, 0x4e, 0x32, 0x45,
+    0x32, 0x4e, 0x53, 0x31, 0x69, 0x5a, 0x6a, 0x63, 0x30, 0x4c, 0x54, 0x51, 0x33, 0x4d, 0x7a, 0x63,
+    0x74, 0x4f, 0x54, 0x5a, 0x6d, 0x4d, 0x53, 0x30, 0x78, 0x59, 0x6d, 0x49, 0x78, 0x4f, 0x44, 0x5a,
+    0x6b, 0x0a, 0x4f, 0x47, 0x59, 0x33, 0x59, 0x6a, 0x4d, 0x70, 0x4d, 0x52, 0x59, 0x77, 0x46, 0x41,
+    0x59, 0x44, 0x56, 0x51, 0x51, 0x4c, 0x45, 0x77, 0x31, 0x50, 0x51, 0x30, 0x59, 0x67, 0x54, 0x55,
+    0x4d, 0x67, 0x52, 0x47, 0x56, 0x32, 0x61, 0x57, 0x4e, 0x6c, 0x4d, 0x52, 0x77, 0x77, 0x47, 0x67,
+    0x59, 0x44, 0x56, 0x51, 0x51, 0x4b, 0x45, 0x78, 0x4e, 0x54, 0x59, 0x57, 0x31, 0x7a, 0x64, 0x57,
+    0x35, 0x6e, 0x0a, 0x49, 0x45, 0x56, 0x73, 0x5a, 0x57, 0x4e, 0x30, 0x63, 0x6d, 0x39, 0x75, 0x61,
+    0x57, 0x4e, 0x7a, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45,
+    0x77, 0x4a, 0x4c, 0x55, 0x6a, 0x42, 0x5a, 0x4d, 0x42, 0x4d, 0x47, 0x42, 0x79, 0x71, 0x47, 0x53,
+    0x4d, 0x34, 0x39, 0x41, 0x67, 0x45, 0x47, 0x43, 0x43, 0x71, 0x47, 0x53, 0x4d, 0x34, 0x39, 0x41,
+    0x77, 0x45, 0x48, 0x0a, 0x41, 0x30, 0x49, 0x41, 0x42, 0x45, 0x45, 0x77, 0x51, 0x41, 0x52, 0x73,
+    0x62, 0x67, 0x43, 0x59, 0x2b, 0x43, 0x59, 0x6b, 0x49, 0x6a, 0x6b, 0x59, 0x6f, 0x47, 0x78, 0x6f,
+    0x52, 0x33, 0x75, 0x70, 0x33, 0x38, 0x59, 0x47, 0x54, 0x32, 0x63, 0x4b, 0x30, 0x31, 0x74, 0x6d,
+    0x32, 0x70, 0x38, 0x79, 0x4c, 0x4b, 0x4e, 0x73, 0x6d, 0x69, 0x53, 0x6f, 0x76, 0x46, 0x70, 0x4a,
+    0x32, 0x35, 0x63, 0x52, 0x0a, 0x74, 0x72, 0x57, 0x34, 0x41, 0x56, 0x7a, 0x76, 0x73, 0x64, 0x67,
+    0x62, 0x74, 0x72, 0x45, 0x62, 0x6b, 0x2b, 0x37, 0x73, 0x56, 0x61, 0x58, 0x50, 0x74, 0x78, 0x43,
+    0x6a, 0x67, 0x59, 0x41, 0x77, 0x66, 0x6a, 0x41, 0x4f, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x51, 0x38,
+    0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4d, 0x43, 0x41, 0x38, 0x67, 0x77, 0x4c, 0x67, 0x59,
+    0x44, 0x56, 0x52, 0x30, 0x66, 0x0a, 0x42, 0x43, 0x63, 0x77, 0x4a, 0x54, 0x41, 0x6a, 0x6f, 0x43,
+    0x47, 0x67, 0x48, 0x34, 0x59, 0x64, 0x61, 0x48, 0x52, 0x30, 0x63, 0x44, 0x6f, 0x76, 0x4c, 0x32,
+    0x4e, 0x68, 0x4c, 0x6e, 0x4e, 0x68, 0x62, 0x58, 0x4e, 0x31, 0x62, 0x6d, 0x64, 0x70, 0x62, 0x33,
+    0x52, 0x7a, 0x4c, 0x6d, 0x4e, 0x76, 0x62, 0x53, 0x39, 0x6a, 0x63, 0x6d, 0x77, 0x77, 0x50, 0x41,
+    0x59, 0x49, 0x4b, 0x77, 0x59, 0x42, 0x0a, 0x42, 0x51, 0x55, 0x48, 0x41, 0x51, 0x45, 0x45, 0x4d,
+    0x44, 0x41, 0x75, 0x4d, 0x43, 0x77, 0x47, 0x43, 0x43, 0x73, 0x47, 0x41, 0x51, 0x55, 0x46, 0x42,
+    0x7a, 0x41, 0x42, 0x68, 0x69, 0x42, 0x6f, 0x64, 0x48, 0x52, 0x77, 0x4f, 0x69, 0x38, 0x76, 0x62,
+    0x32, 0x4e, 0x7a, 0x63, 0x43, 0x31, 0x30, 0x5a, 0x58, 0x4e, 0x30, 0x4c, 0x6e, 0x4e, 0x68, 0x62,
+    0x58, 0x4e, 0x31, 0x62, 0x6d, 0x64, 0x70, 0x0a, 0x62, 0x33, 0x52, 0x7a, 0x4c, 0x6d, 0x4e, 0x76,
+    0x62, 0x54, 0x41, 0x4d, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6b, 0x6a, 0x4f, 0x50, 0x51, 0x51, 0x44,
+    0x41, 0x67, 0x55, 0x41, 0x41, 0x30, 0x6b, 0x41, 0x4d, 0x45, 0x59, 0x43, 0x49, 0x51, 0x43, 0x33,
+    0x58, 0x30, 0x42, 0x61, 0x4f, 0x49, 0x6f, 0x63, 0x4b, 0x4f, 0x45, 0x65, 0x44, 0x46, 0x52, 0x6b,
+    0x63, 0x66, 0x30, 0x48, 0x76, 0x68, 0x68, 0x67, 0x0a, 0x73, 0x6c, 0x65, 0x49, 0x52, 0x32, 0x49,
+    0x62, 0x6d, 0x66, 0x34, 0x6e, 0x69, 0x52, 0x52, 0x55, 0x38, 0x41, 0x49, 0x68, 0x41, 0x4f, 0x4d,
+    0x44, 0x31, 0x77, 0x45, 0x62, 0x50, 0x67, 0x34, 0x70, 0x47, 0x77, 0x49, 0x79, 0x65, 0x77, 0x63,
+    0x61, 0x6b, 0x76, 0x72, 0x4e, 0x4b, 0x66, 0x44, 0x79, 0x2b, 0x4f, 0x4e, 0x43, 0x6e, 0x4e, 0x6e,
+    0x43, 0x59, 0x57, 0x4a, 0x37, 0x39, 0x35, 0x4b, 0x49, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45,
+    0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d,
+    // \r terminator
+    0x0d,
+    // PEM encoded certificate
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49,
+    0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x44,
+    0x38, 0x44, 0x43, 0x43, 0x41, 0x74, 0x69, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x44,
+    0x41, 0x6a, 0x71, 0x53, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33,
+    0x44, 0x51, 0x45, 0x42, 0x43, 0x77, 0x55, 0x41, 0x4d, 0x45, 0x49, 0x78, 0x43, 0x7a, 0x41, 0x4a,
+    0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6c, 0x56, 0x54, 0x0a, 0x4d, 0x52, 0x59,
+    0x77, 0x46, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4b, 0x45, 0x77, 0x31, 0x48, 0x5a, 0x57, 0x39,
+    0x55, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x42, 0x4a, 0x62, 0x6d, 0x4d, 0x75, 0x4d, 0x52, 0x73,
+    0x77, 0x47, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x78, 0x4a, 0x48, 0x5a, 0x57, 0x39,
+    0x55, 0x63, 0x6e, 0x56, 0x7a, 0x64, 0x43, 0x42, 0x48, 0x62, 0x47, 0x39, 0x69, 0x0a, 0x59, 0x57,
+    0x77, 0x67, 0x51, 0x30, 0x45, 0x77, 0x48, 0x68, 0x63, 0x4e, 0x4d, 0x54, 0x55, 0x77, 0x4e, 0x44,
+    0x41, 0x78, 0x4d, 0x44, 0x41, 0x77, 0x4d, 0x44, 0x41, 0x77, 0x57, 0x68, 0x63, 0x4e, 0x4d, 0x54,
+    0x63, 0x78, 0x4d, 0x6a, 0x4d, 0x78, 0x4d, 0x6a, 0x4d, 0x31, 0x4f, 0x54, 0x55, 0x35, 0x57, 0x6a,
+    0x42, 0x4a, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x0a, 0x45,
+    0x77, 0x4a, 0x56, 0x55, 0x7a, 0x45, 0x54, 0x4d, 0x42, 0x45, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43,
+    0x68, 0x4d, 0x4b, 0x52, 0x32, 0x39, 0x76, 0x5a, 0x32, 0x78, 0x6c, 0x49, 0x45, 0x6c, 0x75, 0x59,
+    0x7a, 0x45, 0x6c, 0x4d, 0x43, 0x4d, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d, 0x63, 0x52,
+    0x32, 0x39, 0x76, 0x5a, 0x32, 0x78, 0x6c, 0x49, 0x45, 0x6c, 0x75, 0x64, 0x47, 0x56, 0x79, 0x0a,
+    0x62, 0x6d, 0x56, 0x30, 0x49, 0x45, 0x46, 0x31, 0x64, 0x47, 0x68, 0x76, 0x63, 0x6d, 0x6c, 0x30,
+    0x65, 0x53, 0x42, 0x48, 0x4d, 0x6a, 0x43, 0x43, 0x41, 0x53, 0x49, 0x77, 0x44, 0x51, 0x59, 0x4a,
+    0x4b, 0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41, 0x44,
+    0x67, 0x67, 0x45, 0x50, 0x41, 0x44, 0x43, 0x43, 0x41, 0x51, 0x6f, 0x43, 0x67, 0x67, 0x45, 0x42,
+    0x0a, 0x41, 0x4a, 0x77, 0x71, 0x42, 0x48, 0x64, 0x63, 0x32, 0x46, 0x43, 0x52, 0x4f, 0x67, 0x61,
+    0x6a, 0x67, 0x75, 0x44, 0x59, 0x55, 0x45, 0x69, 0x38, 0x69, 0x54, 0x2f, 0x78, 0x47, 0x58, 0x41,
+    0x61, 0x69, 0x45, 0x5a, 0x2b, 0x34, 0x49, 0x2f, 0x46, 0x38, 0x59, 0x6e, 0x4f, 0x49, 0x65, 0x35,
+    0x61, 0x2f, 0x6d, 0x45, 0x4e, 0x74, 0x7a, 0x4a, 0x45, 0x69, 0x61, 0x42, 0x30, 0x43, 0x31, 0x4e,
+    0x50, 0x0a, 0x56, 0x61, 0x54, 0x4f, 0x67, 0x6d, 0x4b, 0x56, 0x37, 0x75, 0x74, 0x5a, 0x58, 0x38,
+    0x62, 0x68, 0x42, 0x59, 0x41, 0x53, 0x78, 0x46, 0x36, 0x55, 0x50, 0x37, 0x78, 0x62, 0x53, 0x44,
+    0x6a, 0x30, 0x55, 0x2f, 0x63, 0x6b, 0x35, 0x76, 0x75, 0x52, 0x36, 0x52, 0x58, 0x45, 0x7a, 0x2f,
+    0x52, 0x54, 0x44, 0x66, 0x52, 0x4b, 0x2f, 0x4a, 0x39, 0x55, 0x33, 0x6e, 0x32, 0x2b, 0x6f, 0x47,
+    0x74, 0x76, 0x0a, 0x68, 0x38, 0x44, 0x51, 0x55, 0x42, 0x38, 0x6f, 0x4d, 0x41, 0x4e, 0x41, 0x32,
+    0x67, 0x68, 0x7a, 0x55, 0x57, 0x78, 0x2f, 0x2f, 0x7a, 0x6f, 0x38, 0x70, 0x7a, 0x63, 0x47, 0x6a,
+    0x72, 0x31, 0x4c, 0x45, 0x51, 0x54, 0x72, 0x66, 0x53, 0x54, 0x65, 0x35, 0x76, 0x6e, 0x38, 0x4d,
+    0x58, 0x48, 0x37, 0x6c, 0x4e, 0x56, 0x67, 0x38, 0x79, 0x35, 0x4b, 0x72, 0x30, 0x4c, 0x53, 0x79,
+    0x2b, 0x72, 0x45, 0x0a, 0x61, 0x68, 0x71, 0x79, 0x7a, 0x46, 0x50, 0x64, 0x46, 0x55, 0x75, 0x4c,
+    0x48, 0x38, 0x67, 0x5a, 0x59, 0x52, 0x2f, 0x4e, 0x6e, 0x61, 0x67, 0x2b, 0x59, 0x79, 0x75, 0x45,
+    0x4e, 0x57, 0x6c, 0x6c, 0x68, 0x4d, 0x67, 0x5a, 0x78, 0x55, 0x59, 0x69, 0x2b, 0x46, 0x4f, 0x56,
+    0x76, 0x75, 0x4f, 0x41, 0x53, 0x68, 0x44, 0x47, 0x4b, 0x75, 0x79, 0x36, 0x6c, 0x79, 0x41, 0x52,
+    0x78, 0x7a, 0x6d, 0x5a, 0x0a, 0x45, 0x41, 0x53, 0x67, 0x38, 0x47, 0x46, 0x36, 0x6c, 0x53, 0x57,
+    0x4d, 0x54, 0x6c, 0x4a, 0x31, 0x34, 0x72, 0x62, 0x74, 0x43, 0x4d, 0x6f, 0x55, 0x2f, 0x4d, 0x34,
+    0x69, 0x61, 0x72, 0x4e, 0x4f, 0x7a, 0x30, 0x59, 0x44, 0x6c, 0x35, 0x63, 0x44, 0x66, 0x73, 0x43,
+    0x78, 0x33, 0x6e, 0x75, 0x76, 0x52, 0x54, 0x50, 0x50, 0x75, 0x6a, 0x35, 0x78, 0x74, 0x39, 0x37,
+    0x30, 0x4a, 0x53, 0x58, 0x43, 0x0a, 0x44, 0x54, 0x57, 0x4a, 0x6e, 0x5a, 0x33, 0x37, 0x44, 0x68,
+    0x46, 0x35, 0x69, 0x52, 0x34, 0x33, 0x78, 0x61, 0x2b, 0x4f, 0x63, 0x6d, 0x6b, 0x43, 0x41, 0x77,
+    0x45, 0x41, 0x41, 0x61, 0x4f, 0x42, 0x35, 0x7a, 0x43, 0x42, 0x35, 0x44, 0x41, 0x66, 0x42, 0x67,
+    0x4e, 0x56, 0x48, 0x53, 0x4d, 0x45, 0x47, 0x44, 0x41, 0x57, 0x67, 0x42, 0x54, 0x41, 0x65, 0x70,
+    0x68, 0x6f, 0x6a, 0x59, 0x6e, 0x37, 0x0a, 0x71, 0x77, 0x56, 0x6b, 0x44, 0x42, 0x46, 0x39, 0x71,
+    0x6e, 0x31, 0x6c, 0x75, 0x4d, 0x72, 0x4d, 0x54, 0x6a, 0x41, 0x64, 0x42, 0x67, 0x4e, 0x56, 0x48,
+    0x51, 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x53, 0x74, 0x30, 0x47, 0x46, 0x68, 0x75, 0x38, 0x39,
+    0x6d, 0x69, 0x31, 0x64, 0x76, 0x57, 0x42, 0x74, 0x72, 0x74, 0x69, 0x47, 0x72, 0x70, 0x61, 0x67,
+    0x53, 0x38, 0x77, 0x44, 0x67, 0x59, 0x44, 0x0a, 0x56, 0x52, 0x30, 0x50, 0x41, 0x51, 0x48, 0x2f,
+    0x42, 0x41, 0x51, 0x44, 0x41, 0x67, 0x45, 0x47, 0x4d, 0x43, 0x34, 0x47, 0x43, 0x43, 0x73, 0x47,
+    0x41, 0x51, 0x55, 0x46, 0x42, 0x77, 0x45, 0x42, 0x42, 0x43, 0x49, 0x77, 0x49, 0x44, 0x41, 0x65,
+    0x42, 0x67, 0x67, 0x72, 0x42, 0x67, 0x45, 0x46, 0x42, 0x51, 0x63, 0x77, 0x41, 0x59, 0x59, 0x53,
+    0x61, 0x48, 0x52, 0x30, 0x63, 0x44, 0x6f, 0x76, 0x0a, 0x4c, 0x32, 0x63, 0x75, 0x63, 0x33, 0x6c,
+    0x74, 0x59, 0x32, 0x51, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4d, 0x42, 0x49, 0x47, 0x41, 0x31, 0x55,
+    0x64, 0x45, 0x77, 0x45, 0x42, 0x2f, 0x77, 0x51, 0x49, 0x4d, 0x41, 0x59, 0x42, 0x41, 0x66, 0x38,
+    0x43, 0x41, 0x51, 0x41, 0x77, 0x4e, 0x51, 0x59, 0x44, 0x56, 0x52, 0x30, 0x66, 0x42, 0x43, 0x34,
+    0x77, 0x4c, 0x44, 0x41, 0x71, 0x6f, 0x43, 0x69, 0x67, 0x0a, 0x4a, 0x6f, 0x59, 0x6b, 0x61, 0x48,
+    0x52, 0x30, 0x63, 0x44, 0x6f, 0x76, 0x4c, 0x32, 0x63, 0x75, 0x63, 0x33, 0x6c, 0x74, 0x59, 0x32,
+    0x49, 0x75, 0x59, 0x32, 0x39, 0x74, 0x4c, 0x32, 0x4e, 0x79, 0x62, 0x48, 0x4d, 0x76, 0x5a, 0x33,
+    0x52, 0x6e, 0x62, 0x47, 0x39, 0x69, 0x59, 0x57, 0x77, 0x75, 0x59, 0x33, 0x4a, 0x73, 0x4d, 0x42,
+    0x63, 0x47, 0x41, 0x31, 0x55, 0x64, 0x49, 0x41, 0x51, 0x51, 0x0a, 0x4d, 0x41, 0x34, 0x77, 0x44,
+    0x41, 0x59, 0x4b, 0x4b, 0x77, 0x59, 0x42, 0x42, 0x41, 0x48, 0x57, 0x65, 0x51, 0x49, 0x46, 0x41,
+    0x54, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41,
+    0x51, 0x73, 0x46, 0x41, 0x41, 0x4f, 0x43, 0x41, 0x51, 0x45, 0x41, 0x43, 0x45, 0x34, 0x45, 0x70,
+    0x34, 0x42, 0x2f, 0x45, 0x42, 0x5a, 0x44, 0x58, 0x67, 0x4b, 0x74, 0x0a, 0x31, 0x30, 0x4b, 0x41,
+    0x39, 0x4c, 0x43, 0x4f, 0x30, 0x71, 0x36, 0x7a, 0x36, 0x78, 0x46, 0x39, 0x6b, 0x49, 0x51, 0x59,
+    0x66, 0x65, 0x65, 0x51, 0x46, 0x66, 0x74, 0x4a, 0x66, 0x36, 0x69, 0x5a, 0x42, 0x5a, 0x47, 0x37,
+    0x65, 0x73, 0x6e, 0x57, 0x50, 0x44, 0x63, 0x59, 0x43, 0x5a, 0x71, 0x32, 0x78, 0x35, 0x49, 0x67,
+    0x42, 0x7a, 0x55, 0x7a, 0x43, 0x65, 0x51, 0x6f, 0x59, 0x33, 0x49, 0x4e, 0x0a, 0x74, 0x4f, 0x41,
+    0x79, 0x6e, 0x49, 0x65, 0x59, 0x78, 0x42, 0x74, 0x32, 0x69, 0x57, 0x66, 0x42, 0x55, 0x46, 0x69,
+    0x77, 0x45, 0x36, 0x6f, 0x54, 0x47, 0x68, 0x73, 0x79, 0x70, 0x62, 0x37, 0x71, 0x45, 0x5a, 0x56,
+    0x4d, 0x53, 0x47, 0x4e, 0x4a, 0x36, 0x5a, 0x6c, 0x64, 0x49, 0x44, 0x66, 0x4d, 0x2f, 0x69, 0x70,
+    0x70, 0x55, 0x52, 0x61, 0x56, 0x53, 0x36, 0x6e, 0x65, 0x53, 0x59, 0x4c, 0x41, 0x0a, 0x45, 0x48,
+    0x44, 0x30, 0x4c, 0x50, 0x50, 0x73, 0x76, 0x43, 0x51, 0x6b, 0x30, 0x45, 0x36, 0x73, 0x70, 0x64,
+    0x6c, 0x65, 0x48, 0x6d, 0x32, 0x53, 0x77, 0x61, 0x65, 0x73, 0x53, 0x44, 0x57, 0x42, 0x2b, 0x65,
+    0x58, 0x6b, 0x6e, 0x47, 0x56, 0x70, 0x7a, 0x59, 0x65, 0x6b, 0x51, 0x56, 0x41, 0x2f, 0x4c, 0x6c,
+    0x65, 0x6c, 0x6b, 0x56, 0x45, 0x53, 0x57, 0x41, 0x36, 0x4d, 0x43, 0x61, 0x47, 0x73, 0x0a, 0x65,
+    0x71, 0x51, 0x53, 0x70, 0x53, 0x66, 0x7a, 0x6d, 0x68, 0x43, 0x58, 0x66, 0x56, 0x55, 0x44, 0x42,
+    0x76, 0x64, 0x6d, 0x57, 0x46, 0x39, 0x66, 0x5a, 0x4f, 0x47, 0x72, 0x58, 0x57, 0x32, 0x6c, 0x4f,
+    0x55, 0x68, 0x31, 0x6d, 0x45, 0x77, 0x70, 0x57, 0x6a, 0x71, 0x4e, 0x30, 0x79, 0x76, 0x4b, 0x6e,
+    0x46, 0x55, 0x45, 0x76, 0x2f, 0x54, 0x6d, 0x46, 0x4e, 0x57, 0x41, 0x72, 0x43, 0x62, 0x74, 0x0a,
+    0x46, 0x34, 0x6d, 0x6d, 0x6b, 0x32, 0x78, 0x63, 0x70, 0x4d, 0x79, 0x34, 0x38, 0x47, 0x61, 0x4f,
+    0x5a, 0x4f, 0x4e, 0x39, 0x6d, 0x75, 0x49, 0x41, 0x73, 0x30, 0x6e, 0x48, 0x35, 0x41, 0x71, 0x71,
+    0x33, 0x56, 0x75, 0x44, 0x78, 0x33, 0x43, 0x51, 0x52, 0x6b, 0x36, 0x2b, 0x30, 0x4e, 0x74, 0x5a,
+    0x6c, 0x6d, 0x77, 0x75, 0x39, 0x52, 0x59, 0x32, 0x33, 0x6e, 0x48, 0x4d, 0x41, 0x63, 0x49, 0x53,
+    0x0a, 0x77, 0x53, 0x48, 0x47, 0x46, 0x67, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45,
+    0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d,
+    // PEM encoded certificate
+    0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49,
+    0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43,
+    0x6e, 0x44, 0x43, 0x43, 0x41, 0x6a, 0x2b, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x55,
+    0x44, 0x67, 0x45, 0x38, 0x4e, 0x50, 0x54, 0x4c, 0x46, 0x64, 0x6d, 0x68, 0x75, 0x72, 0x53, 0x69,
+    0x36, 0x33, 0x49, 0x31, 0x41, 0x77, 0x76, 0x37, 0x39, 0x49, 0x6b, 0x77, 0x44, 0x41, 0x59, 0x49,
+    0x4b, 0x6f, 0x5a, 0x49, 0x7a, 0x6a, 0x30, 0x45, 0x41, 0x77, 0x49, 0x46, 0x0a, 0x41, 0x44, 0x43,
+    0x42, 0x67, 0x7a, 0x45, 0x34, 0x4d, 0x44, 0x59, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x4d,
+    0x76, 0x55, 0x32, 0x46, 0x74, 0x63, 0x33, 0x56, 0x75, 0x5a, 0x79, 0x42, 0x46, 0x62, 0x47, 0x56,
+    0x6a, 0x64, 0x48, 0x4a, 0x76, 0x62, 0x6d, 0x6c, 0x6a, 0x63, 0x79, 0x42, 0x50, 0x51, 0x30, 0x59,
+    0x67, 0x54, 0x55, 0x4d, 0x67, 0x52, 0x47, 0x56, 0x32, 0x61, 0x57, 0x4e, 0x6c, 0x0a, 0x49, 0x46,
+    0x4e, 0x31, 0x59, 0x6b, 0x4e, 0x42, 0x49, 0x48, 0x59, 0x78, 0x49, 0x46, 0x52, 0x46, 0x55, 0x31,
+    0x51, 0x78, 0x48, 0x44, 0x41, 0x61, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x54, 0x45, 0x30,
+    0x39, 0x44, 0x52, 0x69, 0x42, 0x4e, 0x51, 0x79, 0x42, 0x45, 0x5a, 0x58, 0x5a, 0x70, 0x59, 0x32,
+    0x55, 0x67, 0x55, 0x33, 0x56, 0x69, 0x51, 0x30, 0x45, 0x78, 0x48, 0x44, 0x41, 0x61, 0x0a, 0x42,
+    0x67, 0x4e, 0x56, 0x42, 0x41, 0x6f, 0x54, 0x45, 0x31, 0x4e, 0x68, 0x62, 0x58, 0x4e, 0x31, 0x62,
+    0x6d, 0x63, 0x67, 0x52, 0x57, 0x78, 0x6c, 0x59, 0x33, 0x52, 0x79, 0x62, 0x32, 0x35, 0x70, 0x59,
+    0x33, 0x4d, 0x78, 0x43, 0x7a, 0x41, 0x4a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41,
+    0x6b, 0x74, 0x53, 0x4d, 0x43, 0x41, 0x58, 0x44, 0x54, 0x45, 0x32, 0x4d, 0x54, 0x45, 0x79, 0x0a,
+    0x4e, 0x44, 0x41, 0x79, 0x4e, 0x44, 0x67, 0x78, 0x4d, 0x6c, 0x6f, 0x59, 0x44, 0x7a, 0x49, 0x77,
+    0x4e, 0x6a, 0x6b, 0x78, 0x4d, 0x6a, 0x4d, 0x78, 0x4d, 0x54, 0x51, 0x31, 0x4f, 0x54, 0x55, 0x35,
+    0x57, 0x6a, 0x43, 0x42, 0x6a, 0x54, 0x46, 0x49, 0x4d, 0x45, 0x59, 0x47, 0x41, 0x31, 0x55, 0x45,
+    0x41, 0x78, 0x4d, 0x2f, 0x54, 0x30, 0x4e, 0x47, 0x49, 0x45, 0x52, 0x6c, 0x64, 0x6d, 0x6c, 0x6a,
+    0x0a, 0x5a, 0x53, 0x42, 0x55, 0x52, 0x56, 0x4e, 0x55, 0x4f, 0x69, 0x42, 0x4f, 0x5a, 0x58, 0x52,
+    0x33, 0x62, 0x33, 0x4a, 0x72, 0x49, 0x43, 0x67, 0x77, 0x4e, 0x6a, 0x51, 0x79, 0x4e, 0x32, 0x45,
+    0x32, 0x4e, 0x53, 0x31, 0x69, 0x5a, 0x6a, 0x63, 0x30, 0x4c, 0x54, 0x51, 0x33, 0x4d, 0x7a, 0x63,
+    0x74, 0x4f, 0x54, 0x5a, 0x6d, 0x4d, 0x53, 0x30, 0x78, 0x59, 0x6d, 0x49, 0x78, 0x4f, 0x44, 0x5a,
+    0x6b, 0x0a, 0x4f, 0x47, 0x59, 0x33, 0x59, 0x6a, 0x4d, 0x70, 0x4d, 0x52, 0x59, 0x77, 0x46, 0x41,
+    0x59, 0x44, 0x56, 0x51, 0x51, 0x4c, 0x45, 0x77, 0x31, 0x50, 0x51, 0x30, 0x59, 0x67, 0x54, 0x55,
+    0x4d, 0x67, 0x52, 0x47, 0x56, 0x32, 0x61, 0x57, 0x4e, 0x6c, 0x4d, 0x52, 0x77, 0x77, 0x47, 0x67,
+    0x59, 0x44, 0x56, 0x51, 0x51, 0x4b, 0x45, 0x78, 0x4e, 0x54, 0x59, 0x57, 0x31, 0x7a, 0x64, 0x57,
+    0x35, 0x6e, 0x0a, 0x49, 0x45, 0x56, 0x73, 0x5a, 0x57, 0x4e, 0x30, 0x63, 0x6d, 0x39, 0x75, 0x61,
+    0x57, 0x4e, 0x7a, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45,
+    0x77, 0x4a, 0x4c, 0x55, 0x6a, 0x42, 0x5a, 0x4d, 0x42, 0x4d, 0x47, 0x42, 0x79, 0x71, 0x47, 0x53,
+    0x4d, 0x34, 0x39, 0x41, 0x67, 0x45, 0x47, 0x43, 0x43, 0x71, 0x47, 0x53, 0x4d, 0x34, 0x39, 0x41,
+    0x77, 0x45, 0x48, 0x0a, 0x41, 0x30, 0x49, 0x41, 0x42, 0x45, 0x45, 0x77, 0x51, 0x41, 0x52, 0x73,
+    0x62, 0x67, 0x43, 0x59, 0x2b, 0x43, 0x59, 0x6b, 0x49, 0x6a, 0x6b, 0x59, 0x6f, 0x47, 0x78, 0x6f,
+    0x52, 0x33, 0x75, 0x70, 0x33, 0x38, 0x59, 0x47, 0x54, 0x32, 0x63, 0x4b, 0x30, 0x31, 0x74, 0x6d,
+    0x32, 0x70, 0x38, 0x79, 0x4c, 0x4b, 0x4e, 0x73, 0x6d, 0x69, 0x53, 0x6f, 0x76, 0x46, 0x70, 0x4a,
+    0x32, 0x35, 0x63, 0x52, 0x0a, 0x74, 0x72, 0x57, 0x34, 0x41, 0x56, 0x7a, 0x76, 0x73, 0x64, 0x67,
+    0x62, 0x74, 0x72, 0x45, 0x62, 0x6b, 0x2b, 0x37, 0x73, 0x56, 0x61, 0x58, 0x50, 0x74, 0x78, 0x43,
+    0x6a, 0x67, 0x59, 0x41, 0x77, 0x66, 0x6a, 0x41, 0x4f, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x51, 0x38,
+    0x42, 0x41, 0x66, 0x38, 0x45, 0x42, 0x41, 0x4d, 0x43, 0x41, 0x38, 0x67, 0x77, 0x4c, 0x67, 0x59,
+    0x44, 0x56, 0x52, 0x30, 0x66, 0x0a, 0x42, 0x43, 0x63, 0x77, 0x4a, 0x54, 0x41, 0x6a, 0x6f, 0x43,
+    0x47, 0x67, 0x48, 0x34, 0x59, 0x64, 0x61, 0x48, 0x52, 0x30, 0x63, 0x44, 0x6f, 0x76, 0x4c, 0x32,
+    0x4e, 0x68, 0x4c, 0x6e, 0x4e, 0x68, 0x62, 0x58, 0x4e, 0x31, 0x62, 0x6d, 0x64, 0x70, 0x62, 0x33,
+    0x52, 0x7a, 0x4c, 0x6d, 0x4e, 0x76, 0x62, 0x53, 0x39, 0x6a, 0x63, 0x6d, 0x77, 0x77, 0x50, 0x41,
+    0x59, 0x49, 0x4b, 0x77, 0x59, 0x42, 0x0a, 0x42, 0x51, 0x55, 0x48, 0x41, 0x51, 0x45, 0x45, 0x4d,
+    0x44, 0x41, 0x75, 0x4d, 0x43, 0x77, 0x47, 0x43, 0x43, 0x73, 0x47, 0x41, 0x51, 0x55, 0x46, 0x42,
+    0x7a, 0x41, 0x42, 0x68, 0x69, 0x42, 0x6f, 0x64, 0x48, 0x52, 0x77, 0x4f, 0x69, 0x38, 0x76, 0x62,
+    0x32, 0x4e, 0x7a, 0x63, 0x43, 0x31, 0x30, 0x5a, 0x58, 0x4e, 0x30, 0x4c, 0x6e, 0x4e, 0x68, 0x62,
+    0x58, 0x4e, 0x31, 0x62, 0x6d, 0x64, 0x70, 0x0a, 0x62, 0x33, 0x52, 0x7a, 0x4c, 0x6d, 0x4e, 0x76,
+    0x62, 0x54, 0x41, 0x4d, 0x42, 0x67, 0x67, 0x71, 0x68, 0x6b, 0x6a, 0x4f, 0x50, 0x51, 0x51, 0x44,
+    0x41, 0x67, 0x55, 0x41, 0x41, 0x30, 0x6b, 0x41, 0x4d, 0x45, 0x59, 0x43, 0x49, 0x51, 0x43, 0x33,
+    0x58, 0x30, 0x42, 0x61, 0x4f, 0x49, 0x6f, 0x63, 0x4b, 0x4f, 0x45, 0x65, 0x44, 0x46, 0x52, 0x6b,
+    0x63, 0x66, 0x30, 0x48, 0x76, 0x68, 0x68, 0x67, 0x0a, 0x73, 0x6c, 0x65, 0x49, 0x52, 0x32, 0x49,
+    0x62, 0x6d, 0x66, 0x34, 0x6e, 0x69, 0x52, 0x52, 0x55, 0x38, 0x41, 0x49, 0x68, 0x41, 0x4f, 0x4d,
+    0x44, 0x31, 0x77, 0x45, 0x62, 0x50, 0x67, 0x34, 0x70, 0x47, 0x77, 0x49, 0x79, 0x65, 0x77, 0x63,
+    0x61, 0x6b, 0x76, 0x72, 0x4e, 0x4b, 0x66, 0x44, 0x79, 0x2b, 0x4f, 0x4e, 0x43, 0x6e, 0x4e, 0x6e,
+    0x43, 0x59, 0x57, 0x4a, 0x37, 0x39, 0x35, 0x4b, 0x49, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45,
+    0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
+    0x2d, 0x2d, 0x2d
+};
+size_t certChainLen = sizeof(certChain);
+
 unsigned char serverCert[] = {
     0x30, 0x82, 0x02, 0x39, 0x30, 0x82, 0x01, 0xdf, 0x02, 0x01, 0x01, 0x30, 0x0a, 0x06, 0x08, 0x2a,
     0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x7c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
@@ -181,7 +843,7 @@ unsigned char caCert[] = {
 };
 int caCertLen = sizeof(caCert);
 
-unsigned char control_server_message_ccm[] = {
+unsigned char control_server_message_ECDHE_ECDSA_WITH_AES_128_CCM[] = {
     0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
     0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
     0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x32, 0x3e,
@@ -193,9 +855,9 @@ unsigned char control_server_message_ccm[] = {
     0x48, 0x45, 0x2d, 0x45, 0x43, 0x44, 0x53, 0x41, 0x2d, 0x57, 0x49, 0x54, 0x48, 0x2d, 0x41, 0x45,
     0x53, 0x2d, 0x31, 0x32, 0x38, 0x2d, 0x43, 0x43, 0x4d, 0x3c, 0x2f, 0x70, 0x3e, 0x0d, 0x0a
 };
-int control_server_message_ccm_len = sizeof(control_server_message_ccm);
+size_t control_server_message_ECDHE_ECDSA_WITH_AES_128_CCM_len = sizeof(control_server_message_ECDHE_ECDSA_WITH_AES_128_CCM);
 
-unsigned char control_server_message_ccm8[] = {
+unsigned char control_server_message_ECDHE_ECDSA_WITH_AES_128_CCM_8[] = {
     0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
     0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
     0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x32, 0x3e,
@@ -208,9 +870,9 @@ unsigned char control_server_message_ccm8[] = {
     0x53, 0x2d, 0x31, 0x32, 0x38, 0x2d, 0x43, 0x43, 0x4d, 0x2d, 0x38, 0x3c, 0x2f, 0x70, 0x3e, 0x0d,
     0x0a
 };
-int control_server_message_ccm8_len = sizeof(control_server_message_ccm8);
+size_t control_server_message_ECDHE_ECDSA_WITH_AES_128_CCM_8_len = sizeof(control_server_message_ECDHE_ECDSA_WITH_AES_128_CCM_8);
 
-unsigned char control_server_message_cbc[] = {
+unsigned char control_server_message_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256[] = {
     0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
     0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
     0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x32, 0x3e,
@@ -221,15 +883,75 @@ unsigned char control_server_message_cbc[] = {
     0x6e, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x54, 0x4c, 0x53, 0x2d, 0x45, 0x43, 0x44,
     0x48, 0x45, 0x2d, 0x45, 0x43, 0x44, 0x53, 0x41, 0x2d, 0x57, 0x49, 0x54, 0x48, 0x2d, 0x41, 0x45,
     0x53, 0x2d, 0x31, 0x32, 0x38, 0x2d, 0x43, 0x42, 0x43, 0x2d, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36,
-       0x3c, 0x2f, 0x70, 0x3e, 0x0d, 0x0a
+    0x3c, 0x2f, 0x70, 0x3e, 0x0d, 0x0a
+};
+size_t control_server_message_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256_len = sizeof(control_server_message_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256);
+
+unsigned char control_server_message_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256[] = {
+    0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
+    0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
+    0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x32, 0x3e,
+    0x6d, 0x62, 0x65, 0x64, 0x20, 0x54, 0x4c, 0x53, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x65,
+    0x72, 0x76, 0x65, 0x72, 0x3c, 0x2f, 0x68, 0x32, 0x3e, 0x0d, 0x0a, 0x54, 0x45, 0x53, 0x54, 0x20,
+    0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x0d, 0x0a, 0x3c, 0x70, 0x3e, 0x53, 0x75, 0x63, 0x63,
+    0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f,
+    0x6e, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x54, 0x4c, 0x53, 0x2d, 0x45, 0x43, 0x44,
+    0x48, 0x45, 0x2d, 0x45, 0x43, 0x44, 0x53, 0x41, 0x2d, 0x57, 0x49, 0x54, 0x48, 0x2d, 0x41, 0x45,
+    0x53, 0x2d, 0x31, 0x32, 0x38, 0x2d, 0x47, 0x43, 0x4D, 0x2d, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36,
+    0x3c, 0x2f, 0x70, 0x3e, 0x0d, 0x0a
 };
-int control_server_message_cbc_len = sizeof(control_server_message_cbc);
+size_t control_server_message_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256_len = sizeof(control_server_message_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256);
+
+unsigned char control_server_message_ECDHE_ECDSA_WITH_AES_128_CBC_SHA[] = {
+    0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
+    0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
+    0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x32, 0x3e,
+    0x6d, 0x62, 0x65, 0x64, 0x20, 0x54, 0x4c, 0x53, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x65,
+    0x72, 0x76, 0x65, 0x72, 0x3c, 0x2f, 0x68, 0x32, 0x3e, 0x0d, 0x0a, 0x54, 0x45, 0x53, 0x54, 0x20,
+    0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x0d, 0x0a, 0x3c, 0x70, 0x3e, 0x53, 0x75, 0x63, 0x63,
+    0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f,
+    0x6e, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x54, 0x4c, 0x53, 0x2d, 0x45, 0x43, 0x44,
+    0x48, 0x45, 0x2d, 0x45, 0x43, 0x44, 0x53, 0x41, 0x2d, 0x57, 0x49, 0x54, 0x48, 0x2d, 0x41, 0x45,
+    0x53, 0x2d, 0x31, 0x32, 0x38, 0x2d, 0x43, 0x42, 0x43, 0x2d, 0x53, 0x48, 0x41, 0x3c, 0x2f, 0x70,
+    0x3e, 0x0d, 0x0a
+};
+size_t control_server_message_ECDHE_ECDSA_WITH_AES_128_CBC_SHA_len = sizeof(control_server_message_ECDHE_ECDSA_WITH_AES_128_CBC_SHA);
 
 unsigned char control_client_message[] = {
     0x47, 0x45, 0x54, 0x20, 0x2f, 0x20, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x0d, 0x0a,
     0x0d, 0x0a
 };
-int control_client_message_len = sizeof(control_client_message);
+size_t control_client_message_len = sizeof(control_client_message);
+
+unsigned char control_server_message_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384[] = {
+    0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
+    0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
+    0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x32, 0x3e,
+    0x6d, 0x62, 0x65, 0x64, 0x20, 0x54, 0x4c, 0x53, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x65,
+    0x72, 0x76, 0x65, 0x72, 0x3c, 0x2f, 0x68, 0x32, 0x3e, 0x0d, 0x0a, 0x54, 0x45, 0x53, 0x54, 0x20,
+    0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x0d, 0x0a, 0x3c, 0x70, 0x3e, 0x53, 0x75, 0x63, 0x63,
+    0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f,
+    0x6e, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x54, 0x4c, 0x53, 0x2d, 0x45, 0x43, 0x44,
+    0x48, 0x45, 0x2d, 0x45, 0x43, 0x44, 0x53, 0x41, 0x2d, 0x57, 0x49, 0x54, 0x48, 0x2d, 0x41, 0x45,
+    0x53, 0x2d, 0x32, 0x35, 0x36, 0x2d, 0x43, 0x42, 0x43, 0x2d, 0x53, 0x48, 0x41, 0x33, 0x38, 0x34,
+    0x3c, 0x2f, 0x70, 0x3e, 0x0d, 0x0a
+};
+size_t control_server_message_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384_len = sizeof(control_server_message_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384);
+
+unsigned char control_server_message_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384[] = {
+    0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
+    0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74,
+    0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x32, 0x3e,
+    0x6d, 0x62, 0x65, 0x64, 0x20, 0x54, 0x4c, 0x53, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x65,
+    0x72, 0x76, 0x65, 0x72, 0x3c, 0x2f, 0x68, 0x32, 0x3e, 0x0d, 0x0a, 0x54, 0x45, 0x53, 0x54, 0x20,
+    0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x0d, 0x0a, 0x3c, 0x70, 0x3e, 0x53, 0x75, 0x63, 0x63,
+    0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f,
+    0x6e, 0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x54, 0x4c, 0x53, 0x2d, 0x45, 0x43, 0x44,
+    0x48, 0x45, 0x2d, 0x45, 0x43, 0x44, 0x53, 0x41, 0x2d, 0x57, 0x49, 0x54, 0x48, 0x2d, 0x41, 0x45,
+    0x53, 0x2d, 0x32, 0x35, 0x36, 0x2d, 0x47, 0x43, 0x4D, 0x2d, 0x53, 0x48, 0x41, 0x33, 0x38, 0x34,
+    0x3c, 0x2f, 0x70, 0x3e, 0x0d, 0x0a
+};
+size_t control_server_message_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384_len = sizeof(control_server_message_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384);
 
 static void error(const char *msg)
 {
@@ -275,10 +997,12 @@ static ssize_t CATCPPacketSendCB(CAEndpoint_t *, const void *buf, size_t buflen)
 }
 
 char msg[256] = {0}; size_t msglen = 0;
-static void CATCPPacketReceivedCB(const CASecureEndpoint_t *, const void *data, size_t dataLength)
+static CAResult_t CATCPPacketReceivedCB(const CASecureEndpoint_t *, const void *data, size_t dataLength)
 {
     memcpy(msg, data, dataLength);
     msglen = dataLength;
+
+    return CA_STATUS_OK;
 }
 
 static void PacketReceive(unsigned char *data, int * datalen)
@@ -353,10 +1077,12 @@ static ssize_t CATCPPacketSendCB_server(CAEndpoint_t *, const void *buf, size_t
     return n;
 }
 
-static void CATCPPacketReceivedCB_server(const CASecureEndpoint_t *, const void *data, size_t dataLength)
+static CAResult_t CATCPPacketReceivedCB_server(const CASecureEndpoint_t *, const void *data, size_t dataLength)
 {
     memcpy(msg, data, dataLength);
     msglen = dataLength;
+
+    return CA_STATUS_OK;
 }
 static void PacketReceive_server(unsigned char *data, int * datalen)
 {
@@ -1129,7 +1855,7 @@ static int testCAinitSslAdapter()
     }
 
     // CAdeinitSslAdapter
-    ca_mutex_lock(g_sslContextMutex);
+    oc_mutex_lock(g_sslContextMutex);
     DeletePeerList();
     mbedtls_x509_crt_free(&g_caSslContext->crt);
     mbedtls_pk_free(&g_caSslContext->pkey);
@@ -1139,8 +1865,8 @@ static int testCAinitSslAdapter()
     mbedtls_entropy_free(&g_caSslContext->entropy);
     OICFree(g_caSslContext);
     g_caSslContext = NULL;
-    ca_mutex_unlock(g_sslContextMutex);
-    ca_mutex_free(g_sslContextMutex);
+    oc_mutex_unlock(g_sslContextMutex);
+    oc_mutex_free(g_sslContextMutex);
     g_sslContextMutex = NULL;
 
     return ret;
@@ -1174,15 +1900,15 @@ static int testCAsetSslAdapterCallbacks()
     serverAddr.ifindex = 0;
 
     // CAinitSslAdapter
-    g_sslContextMutex = ca_mutex_new();
-    ca_mutex_lock(g_sslContextMutex);
+    g_sslContextMutex = oc_mutex_new();
+    oc_mutex_lock(g_sslContextMutex);
     g_caSslContext = (SslContext_t *)OICCalloc(1, sizeof(SslContext_t));
     g_caSslContext->peerList = u_arraylist_create();
     mbedtls_entropy_init(&g_caSslContext->entropy);
     mbedtls_ctr_drbg_init(&g_caSslContext->rnd);
-    unsigned char * seed = (unsigned char*) SEED;
+    unsigned char * seed = (unsigned char*) UT_SSL_SEED;
     mbedtls_ctr_drbg_seed(&g_caSslContext->rnd, mbedtls_entropy_func_clutch,
-                                  &g_caSslContext->entropy, seed, sizeof(SEED));
+                                  &g_caSslContext->entropy, seed, sizeof(UT_SSL_SEED));
     mbedtls_ctr_drbg_set_prediction_resistance(&g_caSslContext->rnd, MBEDTLS_CTR_DRBG_PR_OFF);
     mbedtls_ssl_config_init(&g_caSslContext->clientTlsConf);
     mbedtls_ssl_config_defaults(&g_caSslContext->clientTlsConf, MBEDTLS_SSL_IS_CLIENT,
@@ -1200,7 +1926,7 @@ static int testCAsetSslAdapterCallbacks()
     mbedtls_x509_crt_init(&g_caSslContext->crt);
     mbedtls_pk_init(&g_caSslContext->pkey);
     mbedtls_x509_crl_init(&g_caSslContext->crl);
-    ca_mutex_unlock(g_sslContextMutex);
+    oc_mutex_unlock(g_sslContextMutex);
 
     CAsetSslAdapterCallbacks(CATCPPacketReceivedCB, CATCPPacketSendCB, (CATransportAdapter_t)0);
     if (g_caSslContext->adapterCallbacks[0].recvCallback == NULL &&
@@ -1229,7 +1955,7 @@ static int testCAsetSslAdapterCallbacks()
     }
 
     // CAdeinitSslAdapter
-    ca_mutex_lock(g_sslContextMutex);
+    oc_mutex_lock(g_sslContextMutex);
     DeletePeerList();
     mbedtls_x509_crt_free(&g_caSslContext->crt);
     mbedtls_pk_free(&g_caSslContext->pkey);
@@ -1239,8 +1965,8 @@ static int testCAsetSslAdapterCallbacks()
     mbedtls_entropy_free(&g_caSslContext->entropy);
     OICFree(g_caSslContext);
     g_caSslContext = NULL;
-    ca_mutex_unlock(g_sslContextMutex);
-    ca_mutex_free(g_sslContextMutex);
+    oc_mutex_unlock(g_sslContextMutex);
+    oc_mutex_free(g_sslContextMutex);
     g_sslContextMutex = NULL;
 
     return ret;
@@ -1271,6 +1997,7 @@ unsigned char predictedClientHello[] = {
     0x02, 0x01, 0x00, 0x0a, 0x00, 0x04, 0x00, 0x02, 0x00, 0x17, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00,
     0x00, 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00
 };
+#if 0
 static unsigned char controlBuf[sizeof(predictedClientHello)];
 static char controlBufLen = 0;
 static ssize_t CATCPPacketSendCB_forInitHsTest(CAEndpoint_t *, const void * buf, size_t buflen)
@@ -1297,15 +2024,15 @@ static void * test0CAinitiateSslHandshake(void * arg)
     serverAddr.ifindex = 0;
 
     // CAinitSslAdapter
-    g_sslContextMutex = ca_mutex_new();
-    ca_mutex_lock(g_sslContextMutex);
+    g_sslContextMutex = oc_mutex_new();
+    oc_mutex_lock(g_sslContextMutex);
     g_caSslContext = (SslContext_t *)OICCalloc(1, sizeof(SslContext_t));
     g_caSslContext->peerList = u_arraylist_create();
     mbedtls_entropy_init(&g_caSslContext->entropy);
     mbedtls_ctr_drbg_init(&g_caSslContext->rnd);
-    unsigned char * seed = (unsigned char*) SEED;
+    unsigned char * seed = (unsigned char*) UT_SSL_SEED;
     mbedtls_ctr_drbg_seed(&g_caSslContext->rnd, mbedtls_entropy_func_clutch,
-                                  &g_caSslContext->entropy, seed, sizeof(SEED));
+                                  &g_caSslContext->entropy, seed, sizeof(UT_SSL_SEED));
     mbedtls_ctr_drbg_set_prediction_resistance(&g_caSslContext->rnd, MBEDTLS_CTR_DRBG_PR_OFF);
     mbedtls_ssl_config_init(&g_caSslContext->clientTlsConf);
     mbedtls_ssl_config_defaults(&g_caSslContext->clientTlsConf, MBEDTLS_SSL_IS_CLIENT,
@@ -1322,7 +2049,7 @@ static void * test0CAinitiateSslHandshake(void * arg)
     mbedtls_x509_crt_init(&g_caSslContext->crt);
     mbedtls_pk_init(&g_caSslContext->pkey);
     mbedtls_x509_crl_init(&g_caSslContext->crl);
-    ca_mutex_unlock(g_sslContextMutex);
+    oc_mutex_unlock(g_sslContextMutex);
 
     // CAsetSslAdapterCallbacks
     g_caSslContext->adapterCallbacks[1].recvCallback = CATCPPacketReceivedCB;
@@ -1336,10 +2063,10 @@ static void * test0CAinitiateSslHandshake(void * arg)
 
     // CAsetTlsCipherSuite
     mbedtls_ssl_conf_ciphersuites(&g_caSslContext->clientTlsConf,
-                                         tlsCipher[ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CCM]);
+                                         tlsCipher[SSL_ECDHE_ECDSA_WITH_AES_128_CCM]);
     mbedtls_ssl_conf_ciphersuites(&g_caSslContext->serverTlsConf,
-                                         tlsCipher[ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CCM]);
-    g_caSslContext->cipher = ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CCM;
+                                         tlsCipher[SSL_ECDHE_ECDSA_WITH_AES_128_CCM]);
+    g_caSslContext->cipher = SSL_ECDHE_ECDSA_WITH_AES_128_CCM;
 
     CAsetPskCredentialsCallback(GetDtlsPskCredentials);
 
@@ -1353,14 +2080,14 @@ static void * test0CAinitiateSslHandshake(void * arg)
     predictedClientHello[14] = (unixTime << 24) >> 24;
 
     // CAcloseTlsConnection
-    ca_mutex_lock(g_sslContextMutex);
+    oc_mutex_lock(g_sslContextMutex);
     SslEndPoint_t * tep = GetSslPeer(&serverAddr);
     mbedtls_ssl_close_notify(&tep->ssl);
     RemovePeerFromList(&tep->sep.endpoint);
-    ca_mutex_unlock(g_sslContextMutex);
+    oc_mutex_unlock(g_sslContextMutex);
 
     // CAdeinitTlsAdapter
-    ca_mutex_lock(g_sslContextMutex);
+    oc_mutex_lock(g_sslContextMutex);
     DeletePeerList();
     mbedtls_x509_crt_free(&g_caSslContext->crt);
     mbedtls_pk_free(&g_caSslContext->pkey);
@@ -1370,8 +2097,8 @@ static void * test0CAinitiateSslHandshake(void * arg)
     mbedtls_entropy_free(&g_caSslContext->entropy);
     OICFree(g_caSslContext);
     g_caSslContext = NULL;
-    ca_mutex_unlock(g_sslContextMutex);
-    ca_mutex_free(g_sslContextMutex);
+    oc_mutex_unlock(g_sslContextMutex);
+    oc_mutex_free(g_sslContextMutex);
     g_sslContextMutex = NULL;
 
     socketClose();
@@ -1388,6 +2115,7 @@ static void * test0CAinitiateSslHandshake(void * arg)
         return (void *) 0xFF;
     }
 }
+#endif
 
 static int test1CAinitiateSslHandshake()
 {
@@ -1404,6 +2132,7 @@ static int test1CAinitiateSslHandshake()
     return ret;
 }
 
+/*
 // CAinitiateSslHandshake()
 TEST(TLSAdaper, Test_3_0)
 {
@@ -1431,6 +2160,7 @@ TEST(TLSAdaper, Test_3_0)
 
     EXPECT_EQ(0, arg);
 }
+*/
 
 TEST(TLSAdaper, Test_3_1)
 {
@@ -1459,15 +2189,15 @@ static void * testCAencryptSsl(void * arg)
     serverAddr.ifindex = 0;
 
     // CAinitTlsAdapter
-    g_sslContextMutex = ca_mutex_new();
-    ca_mutex_lock(g_sslContextMutex);
+    g_sslContextMutex = oc_mutex_new();
+    oc_mutex_lock(g_sslContextMutex);
     g_caSslContext = (SslContext_t *)OICCalloc(1, sizeof(SslContext_t));
     g_caSslContext->peerList = u_arraylist_create();
     mbedtls_entropy_init(&g_caSslContext->entropy);
     mbedtls_ctr_drbg_init(&g_caSslContext->rnd);
-    unsigned char * seed = (unsigned char*) SEED;
+    unsigned char * seed = (unsigned char*) UT_SSL_SEED;
     mbedtls_ctr_drbg_seed(&g_caSslContext->rnd, mbedtls_entropy_func_clutch,
-                                  &g_caSslContext->entropy, seed, sizeof(SEED));
+                                  &g_caSslContext->entropy, seed, sizeof(UT_SSL_SEED));
     mbedtls_ctr_drbg_set_prediction_resistance(&g_caSslContext->rnd, MBEDTLS_CTR_DRBG_PR_OFF);
     mbedtls_ssl_config_init(&g_caSslContext->clientTlsConf);
     mbedtls_ssl_config_defaults(&g_caSslContext->clientTlsConf, MBEDTLS_SSL_IS_CLIENT,
@@ -1485,7 +2215,7 @@ static void * testCAencryptSsl(void * arg)
     mbedtls_x509_crt_init(&g_caSslContext->crt);
     mbedtls_pk_init(&g_caSslContext->pkey);
     mbedtls_x509_crl_init(&g_caSslContext->crl);
-    ca_mutex_unlock(g_sslContextMutex);
+    oc_mutex_unlock(g_sslContextMutex);
 
     CAsetSslAdapterCallbacks(CATCPPacketReceivedCB, CATCPPacketSendCB, CA_ADAPTER_TCP);
 
@@ -1498,7 +2228,7 @@ static void * testCAencryptSsl(void * arg)
     {
         CAsetTlsCipherSuite(MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM);
     }
-    if (*((int*)arg) == 1)
+    else if (*((int*)arg) == 1)
     {
         CAsetTlsCipherSuite(MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8);
     }
@@ -1506,14 +2236,27 @@ static void * testCAencryptSsl(void * arg)
     {
         CAsetTlsCipherSuite(MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256);
     }
+    else if (*((int*)arg) == 3)
+    {
+        CAsetTlsCipherSuite(MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256);
+    }
+    else if (*((int*)arg) == 4)
+    {
+        CAsetTlsCipherSuite(MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384);
+    }
+    else if (*((int*)arg) == 5)
+    {
+        CAsetTlsCipherSuite(MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384);
+    }
+
     CAsetPskCredentialsCallback(GetDtlsPskCredentials);
 
     socketConnect();
 
     // CAinitiateSslHandshake
-    ca_mutex_lock(g_sslContextMutex);
+    oc_mutex_lock(g_sslContextMutex);
     InitiateTlsHandshake(&serverAddr);
-    ca_mutex_unlock(g_sslContextMutex);
+    oc_mutex_unlock(g_sslContextMutex);
 
     unsigned char buffer[2048] = {'\0'};
     int buflen = 0;
@@ -1536,7 +2279,7 @@ static void * testCAencryptSsl(void * arg)
     CAcloseSslConnection(&serverAddr);
 
     // CAdeinitSslAdapter
-    ca_mutex_lock(g_sslContextMutex);
+    oc_mutex_lock(g_sslContextMutex);
     DeletePeerList();
     mbedtls_x509_crt_free(&g_caSslContext->crt);
     mbedtls_pk_free(&g_caSslContext->pkey);
@@ -1546,15 +2289,17 @@ static void * testCAencryptSsl(void * arg)
     mbedtls_entropy_free(&g_caSslContext->entropy);
     OICFree(g_caSslContext);
     g_caSslContext = NULL;
-    ca_mutex_unlock(g_sslContextMutex);
-    ca_mutex_free(g_sslContextMutex);
+    oc_mutex_unlock(g_sslContextMutex);
+    oc_mutex_free(g_sslContextMutex);
     g_sslContextMutex = NULL;
 
     socketClose();
 
     if (*((int*)arg) == 0)
     {
-        if (control_server_message_ccm_len == msglen && memcmp(msg, control_server_message_ccm, control_server_message_ccm_len) == 0)
+        if (control_server_message_ECDHE_ECDSA_WITH_AES_128_CCM_len == msglen &&
+            memcmp(msg, control_server_message_ECDHE_ECDSA_WITH_AES_128_CCM,
+            control_server_message_ECDHE_ECDSA_WITH_AES_128_CCM_len) == 0)
         {
             ret = 0;
         }
@@ -1565,7 +2310,9 @@ static void * testCAencryptSsl(void * arg)
     }
     if (*((int*)arg) == 1)
     {
-        if (control_server_message_ccm8_len == msglen && memcmp(msg, control_server_message_ccm8, control_server_message_ccm8_len) == 0)
+        if (control_server_message_ECDHE_ECDSA_WITH_AES_128_CCM_8_len == msglen &&
+            memcmp(msg, control_server_message_ECDHE_ECDSA_WITH_AES_128_CCM_8,
+            control_server_message_ECDHE_ECDSA_WITH_AES_128_CCM_8_len) == 0)
         {
             ret = 0;
         }
@@ -1576,7 +2323,48 @@ static void * testCAencryptSsl(void * arg)
     }
     else if (*((int*)arg) == 2)
     {
-        if (control_server_message_cbc_len == msglen && memcmp(msg, control_server_message_cbc, control_server_message_cbc_len) == 0)
+        if (control_server_message_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256_len == msglen &&
+            memcmp(msg, control_server_message_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+            control_server_message_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256_len) == 0)
+        {
+            ret = 0;
+        }
+        else
+        {
+            ret = 1;
+        }
+    }
+    else if (*((int*)arg) == 3)
+    {
+        if (control_server_message_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256_len == msglen &&
+            memcmp(msg, control_server_message_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+            control_server_message_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256_len) == 0)
+        {
+            ret = 0;
+        }
+        else
+        {
+            ret = 1;
+        }
+    }
+    else if (*((int*)arg) == 4)
+    {
+        if (control_server_message_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384_len == msglen &&
+            memcmp(msg, control_server_message_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
+                   control_server_message_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384_len) == 0)
+        {
+            ret = 0;
+        }
+        else
+        {
+            ret = 1;
+        }
+    }
+    else if (*((int*)arg) == 5)
+    {
+        if (control_server_message_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384_len == msglen &&
+            memcmp(msg, control_server_message_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+                   control_server_message_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384_len) == 0)
         {
             ret = 0;
         }
@@ -1598,6 +2386,7 @@ static void * testCAencryptSsl(void * arg)
     }
 }
 
+/*
 // CAencryptSsl()
 TEST(TLSAdaper, Test_4_0)
 {
@@ -1682,6 +2471,90 @@ TEST(TLSAdaper, Test_4_2)
     EXPECT_EQ(0, arg);
 }
 
+// CAencryptSsl()
+TEST(TLSAdaper, Test_4_3)
+{
+    pthread_t thread1, thread2;
+    int ret = 0;
+    int arg = 3;
+
+    ret = pthread_create( &thread1, NULL, server, (void*) NULL);
+    if(ret)
+    {
+        fprintf(stderr,"Error - pthread_create() return code: %d\n", ret);
+        exit(EXIT_FAILURE);
+    }
+
+    sleep(5);
+
+    ret = pthread_create( &thread2, NULL, testCAencryptSsl, &arg);
+    if(ret)
+    {
+        fprintf(stderr,"Error - pthread_create() return code: %d\n", ret);
+        exit(EXIT_FAILURE);
+    }
+
+    sleep(5);
+
+    EXPECT_EQ(0, arg);
+}
+
+// CAencryptSsl()
+TEST(TLSAdaper, Test_4_4)
+{
+    pthread_t thread1, thread2;
+    int ret = 0;
+    int arg = 4;
+
+    ret = pthread_create( &thread1, NULL, server, (void*) NULL);
+    if(ret)
+    {
+        fprintf(stderr,"Error - pthread_create() return code: %d\n", ret);
+        exit(EXIT_FAILURE);
+    }
+
+    sleep(5);
+
+    ret = pthread_create( &thread2, NULL, testCAencryptSsl, &arg);
+    if(ret)
+    {
+        fprintf(stderr,"Error - pthread_create() return code: %d\n", ret);
+        exit(EXIT_FAILURE);
+    }
+
+    sleep(5);
+
+    EXPECT_EQ(0, arg);
+}
+*/
+
+TEST(TLSAdaper, Test_4_5)
+{
+    pthread_t thread1, thread2;
+    int ret = 0;
+    int arg = 5;
+
+    ret = pthread_create( &thread1, NULL, server, (void*) NULL);
+    if(ret)
+    {
+        fprintf(stderr,"Error - pthread_create() return code: %d\n", ret);
+        exit(EXIT_FAILURE);
+    }
+
+    sleep(5);
+
+    ret = pthread_create( &thread2, NULL, testCAencryptSsl, &arg);
+    if(ret)
+    {
+        fprintf(stderr,"Error - pthread_create() return code: %d\n", ret);
+        exit(EXIT_FAILURE);
+    }
+
+    sleep(5);
+
+    EXPECT_EQ(0, arg);
+}
+
 /* **************************
  *
  *
@@ -1689,7 +2562,7 @@ TEST(TLSAdaper, Test_4_2)
  *
  *
  * *************************/
-
+#if 0
 static void * testCAdecryptSsl(void * arg)
 {
     int ret = 0;
@@ -1705,15 +2578,15 @@ static void * testCAdecryptSsl(void * arg)
     serverAddr.ifindex = 0;
 
     // CAinitTlsAdapter
-    g_sslContextMutex = ca_mutex_new();
-    ca_mutex_lock(g_sslContextMutex);
+    g_sslContextMutex = oc_mutex_new();
+    oc_mutex_lock(g_sslContextMutex);
     g_caSslContext = (SslContext_t *)OICCalloc(1, sizeof(SslContext_t));
     g_caSslContext->peerList = u_arraylist_create();
     mbedtls_entropy_init(&g_caSslContext->entropy);
     mbedtls_ctr_drbg_init(&g_caSslContext->rnd);
-    unsigned char * seed = (unsigned char*) SEED;
+    unsigned char * seed = (unsigned char*) UT_SSL_SEED;
     mbedtls_ctr_drbg_seed(&g_caSslContext->rnd, mbedtls_entropy_func_clutch,
-                                  &g_caSslContext->entropy, seed, sizeof(SEED));
+                                  &g_caSslContext->entropy, seed, sizeof(UT_SSL_SEED));
     mbedtls_ctr_drbg_set_prediction_resistance(&g_caSslContext->rnd, MBEDTLS_CTR_DRBG_PR_OFF);
     mbedtls_ssl_config_init(&g_caSslContext->clientTlsConf);
     mbedtls_ssl_config_defaults(&g_caSslContext->clientTlsConf, MBEDTLS_SSL_IS_CLIENT,
@@ -1731,7 +2604,7 @@ static void * testCAdecryptSsl(void * arg)
     mbedtls_x509_crt_init(&g_caSslContext->crt);
     mbedtls_pk_init(&g_caSslContext->pkey);
     mbedtls_x509_crl_init(&g_caSslContext->crl);
-    ca_mutex_unlock(g_sslContextMutex);
+    oc_mutex_unlock(g_sslContextMutex);
 
     // CAsetTlsAdapterCallbacks
     CAsetSslAdapterCallbacks(CATCPPacketReceivedCB, CATCPPacketSendCB, CA_ADAPTER_TCP);
@@ -1749,9 +2622,9 @@ static void * testCAdecryptSsl(void * arg)
     socketConnect();
 
     // CAinitiateSslHandshake
-    ca_mutex_lock(g_sslContextMutex);
+    oc_mutex_lock(g_sslContextMutex);
     InitiateTlsHandshake(&serverAddr);
-    ca_mutex_unlock(g_sslContextMutex);
+    oc_mutex_unlock(g_sslContextMutex);
 
     CASecureEndpoint_t * sep = (CASecureEndpoint_t *) malloc (sizeof(CASecureEndpoint_t));
     sep->endpoint = serverAddr;
@@ -1772,7 +2645,7 @@ static void * testCAdecryptSsl(void * arg)
     CAcloseSslConnection(&serverAddr);
 
     // CAdeinitSslAdapter
-    ca_mutex_lock(g_sslContextMutex);
+    oc_mutex_lock(g_sslContextMutex);
     DeletePeerList();
     mbedtls_x509_crt_free(&g_caSslContext->crt);
     mbedtls_pk_free(&g_caSslContext->pkey);
@@ -1782,14 +2655,15 @@ static void * testCAdecryptSsl(void * arg)
     mbedtls_entropy_free(&g_caSslContext->entropy);
     OICFree(g_caSslContext);
     g_caSslContext = NULL;
-    ca_mutex_unlock(g_sslContextMutex);
-    ca_mutex_free(g_sslContextMutex);
+    oc_mutex_unlock(g_sslContextMutex);
+    oc_mutex_free(g_sslContextMutex);
     g_sslContextMutex = NULL;
 
     socketClose();
 
-    if (control_server_message_ccm_len == msglen && memcmp(msg, control_server_message_ccm,
-                                                                 control_server_message_ccm_len) == 0)
+    if (control_server_message_ECDHE_ECDSA_WITH_AES_128_CCM_len == msglen &&
+            memcmp(msg, control_server_message_ECDHE_ECDSA_WITH_AES_128_CCM,
+            control_server_message_ECDHE_ECDSA_WITH_AES_128_CCM_len) == 0)
     {
         *((int*)arg) = 0;
         return NULL;
@@ -1800,7 +2674,9 @@ static void * testCAdecryptSsl(void * arg)
         return (void *) 0xFF;
     }
 }
+#endif
 
+/*
 // CAdecryptTls()
 TEST(TLSAdaper, Test_5)
 {
@@ -1828,6 +2704,7 @@ TEST(TLSAdaper, Test_5)
 
     EXPECT_EQ(0, arg);
 }
+*/
 
 /* **************************
  *
@@ -1849,15 +2726,15 @@ static int testCAdeinitSslAdapter()
     serverAddr.ifindex = 0;
 
     // CAinitTlsAdapter
-    g_sslContextMutex = ca_mutex_new();
-    ca_mutex_lock(g_sslContextMutex);
+    g_sslContextMutex = oc_mutex_new();
+    oc_mutex_lock(g_sslContextMutex);
     g_caSslContext = (SslContext_t *)OICCalloc(1, sizeof(SslContext_t));
     g_caSslContext->peerList = u_arraylist_create();
     mbedtls_entropy_init(&g_caSslContext->entropy);
     mbedtls_ctr_drbg_init(&g_caSslContext->rnd);
-    unsigned char * seed = (unsigned char*) SEED;
+    unsigned char * seed = (unsigned char*) UT_SSL_SEED;
     mbedtls_ctr_drbg_seed(&g_caSslContext->rnd, mbedtls_entropy_func,
-                                  &g_caSslContext->entropy, seed, sizeof(SEED));
+                                  &g_caSslContext->entropy, seed, sizeof(UT_SSL_SEED));
     mbedtls_ctr_drbg_set_prediction_resistance(&g_caSslContext->rnd, MBEDTLS_CTR_DRBG_PR_OFF);
     mbedtls_ssl_config_init(&g_caSslContext->clientTlsConf);
     mbedtls_ssl_config_defaults(&g_caSslContext->clientTlsConf, MBEDTLS_SSL_IS_CLIENT,
@@ -1874,7 +2751,7 @@ static int testCAdeinitSslAdapter()
     mbedtls_x509_crt_init(&g_caSslContext->crt);
     mbedtls_pk_init(&g_caSslContext->pkey);
     mbedtls_x509_crl_init(&g_caSslContext->crl);
-    ca_mutex_unlock(g_sslContextMutex);
+    oc_mutex_unlock(g_sslContextMutex);
 
     // CAsetTlsAdapterCallbacks
     g_caSslContext->adapterCallbacks[1].recvCallback = CATCPPacketReceivedCB;
@@ -1885,10 +2762,10 @@ static int testCAdeinitSslAdapter()
 
     // CAsetTlsCipherSuite
     mbedtls_ssl_conf_ciphersuites(&g_caSslContext->clientTlsConf,
-                                         tlsCipher[ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CCM]);
+                                         tlsCipher[SSL_ECDHE_ECDSA_WITH_AES_128_CCM]);
     mbedtls_ssl_conf_ciphersuites(&g_caSslContext->serverTlsConf,
-                                         tlsCipher[ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CCM]);
-    g_caSslContext->cipher = ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CCM;
+                                         tlsCipher[SSL_ECDHE_ECDSA_WITH_AES_128_CCM]);
+    g_caSslContext->cipher = SSL_ECDHE_ECDSA_WITH_AES_128_CCM;
 
     CAdeinitSslAdapter();
 
@@ -1958,7 +2835,7 @@ static void * testServer(void * arg)
     CAcloseSslConnection(&serverAddr);
 
     // CAdeinitSslAdapter
-    ca_mutex_lock(g_sslContextMutex);
+    oc_mutex_lock(g_sslContextMutex);
     DeletePeerList();
     mbedtls_x509_crt_free(&g_caSslContext->crt);
     mbedtls_pk_free(&g_caSslContext->pkey);
@@ -1968,8 +2845,8 @@ static void * testServer(void * arg)
     mbedtls_entropy_free(&g_caSslContext->entropy);
     OICFree(g_caSslContext);
     g_caSslContext = NULL;
-    ca_mutex_unlock(g_sslContextMutex);
-    ca_mutex_free(g_sslContextMutex);
+    oc_mutex_unlock(g_sslContextMutex);
+    oc_mutex_free(g_sslContextMutex);
     g_sslContextMutex = NULL;
 
     socketClose_server();
@@ -2093,7 +2970,7 @@ TEST(TLSAdaper, Test_9_2)
  *
  *
  * *************************/
-
+#if 0
 static int testCAsetTlsCipherSuite()
 {
     int ret = 0, status = 0;
@@ -2110,32 +2987,56 @@ static int testCAsetTlsCipherSuite()
     // CAsetCredentialTypesCallback
     g_getCredentialTypesCallback = clutch;
 
-    status = CAsetTlsCipherSuite(MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA);
-    if (ADAPTER_TLS_RSA_WITH_AES_256_CBC_SHA != g_caSslContext->cipher || status != CA_STATUS_OK)
+
+    status = CAsetTlsCipherSuite(MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256);
+    if (SSL_RSA_WITH_AES_256_CBC_SHA256 != g_caSslContext->cipher || status != CA_STATUS_OK)
+    {
+        ret += 1;
+    }
+
+    status = CAsetTlsCipherSuite(MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256);
+    if (SSL_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 != g_caSslContext->cipher || status != CA_STATUS_OK)
+    {
+        ret += 1;
+    }
+    status = CAsetTlsCipherSuite(MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8);
+    if (SSL_ECDHE_ECDSA_WITH_AES_128_CCM_8 != g_caSslContext->cipher || status != CA_STATUS_OK)
     {
         ret += 1;
     }
 
     status = CAsetTlsCipherSuite(MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM);
-    if (ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CCM != g_caSslContext->cipher || status != CA_STATUS_OK)
+    if (SSL_ECDHE_ECDSA_WITH_AES_128_CCM != g_caSslContext->cipher || status != CA_STATUS_OK)
     {
         ret += 1;
     }
 
     status = CAsetTlsCipherSuite(MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256);
-    if (ADAPTER_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 != g_caSslContext->cipher || status != CA_STATUS_OK)
+    if (SSL_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 != g_caSslContext->cipher || status != CA_STATUS_OK)
     {
         ret += 1;
     }
 
-    status = CAsetTlsCipherSuite(MBEDTLS_TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256);
-    if (ADAPTER_TLS_ECDH_ANON_WITH_AES_128_CBC_SHA_256 != g_caSslContext->cipher || status != CA_STATUS_OK)
+    status = CAsetTlsCipherSuite(MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384);
+    if (SSL_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 != g_caSslContext->cipher || status != CA_STATUS_OK)
+    {
+        ret += 1;
+    }
+
+    status = CAsetTlsCipherSuite(MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384);
+    if (SSL_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 != g_caSslContext->cipher || status != CA_STATUS_OK)
     {
         ret += 1;
     }
 
     status = CAsetTlsCipherSuite(MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256);
-    if (ADAPTER_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 != g_caSslContext->cipher || status != CA_STATUS_OK)
+    if (SSL_ECDHE_PSK_WITH_AES_128_CBC_SHA256 != g_caSslContext->cipher || status != CA_STATUS_OK)
+    {
+        ret += 1;
+    }
+
+    status = CAsetTlsCipherSuite(MBEDTLS_TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256);
+    if (SSL_ECDH_ANON_WITH_AES_128_CBC_SHA256 != g_caSslContext->cipher || status != CA_STATUS_OK)
     {
         ret += 1;
     }
@@ -2147,7 +3048,7 @@ static int testCAsetTlsCipherSuite()
     }
 
     // CAdeinitSslAdapter
-    ca_mutex_lock(g_sslContextMutex);
+    oc_mutex_lock(g_sslContextMutex);
     DeletePeerList();
     mbedtls_x509_crt_free(&g_caSslContext->crt);
     mbedtls_pk_free(&g_caSslContext->pkey);
@@ -2157,13 +3058,15 @@ static int testCAsetTlsCipherSuite()
     mbedtls_entropy_free(&g_caSslContext->entropy);
     OICFree(g_caSslContext);
     g_caSslContext = NULL;
-    ca_mutex_unlock(g_sslContextMutex);
-    ca_mutex_free(g_sslContextMutex);
+    oc_mutex_unlock(g_sslContextMutex);
+    oc_mutex_free(g_sslContextMutex);
     g_sslContextMutex = NULL;
 
     return ret;
 }
+#endif
 
+/*
 // CAinitTlsAdapter()
 TEST(TLSAdaper, Test_10)
 {
@@ -2171,7 +3074,8 @@ TEST(TLSAdaper, Test_10)
     ret = testCAsetTlsCipherSuite();
     EXPECT_EQ(0, ret);
 }
-
+*/
+#if 0
 static void * testCAsslGenerateOwnerPsk(void * arg)
 {
     int ret = 0;
@@ -2207,15 +3111,15 @@ static void * testCAsslGenerateOwnerPsk(void * arg)
     };
 
     // CAinitTlsAdapter
-    g_sslContextMutex = ca_mutex_new();
-    ca_mutex_lock(g_sslContextMutex);
+    g_sslContextMutex = oc_mutex_new();
+    oc_mutex_lock(g_sslContextMutex);
     g_caSslContext = (SslContext_t *)OICCalloc(1, sizeof(SslContext_t));
     g_caSslContext->peerList = u_arraylist_create();
     mbedtls_entropy_init(&g_caSslContext->entropy);
     mbedtls_ctr_drbg_init(&g_caSslContext->rnd);
-    unsigned char * seed = (unsigned char*) SEED;
+    unsigned char * seed = (unsigned char*) UT_SSL_SEED;
     mbedtls_ctr_drbg_seed(&g_caSslContext->rnd, mbedtls_entropy_func_clutch,
-                                  &g_caSslContext->entropy, seed, sizeof(SEED));
+                                  &g_caSslContext->entropy, seed, sizeof(UT_SSL_SEED));
     mbedtls_ctr_drbg_set_prediction_resistance(&g_caSslContext->rnd, MBEDTLS_CTR_DRBG_PR_OFF);
     mbedtls_ssl_config_init(&g_caSslContext->clientTlsConf);
     mbedtls_ssl_config_defaults(&g_caSslContext->clientTlsConf, MBEDTLS_SSL_IS_CLIENT,
@@ -2233,7 +3137,7 @@ static void * testCAsslGenerateOwnerPsk(void * arg)
     mbedtls_x509_crt_init(&g_caSslContext->crt);
     mbedtls_pk_init(&g_caSslContext->pkey);
     mbedtls_x509_crl_init(&g_caSslContext->crl);
-    ca_mutex_unlock(g_sslContextMutex);
+    oc_mutex_unlock(g_sslContextMutex);
 
     // CAsetTlsAdapterCallbacks
     CAsetSslAdapterCallbacks(CATCPPacketReceivedCB, CATCPPacketSendCB, CA_ADAPTER_TCP);
@@ -2244,16 +3148,16 @@ static void * testCAsslGenerateOwnerPsk(void * arg)
     // CAsetCredentialTypesCallback
     g_getCredentialTypesCallback = clutch;
 
-    CAsetTlsCipherSuite(MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM);
+    CAsetTlsCipherSuite(MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256);
 
     CAsetPskCredentialsCallback(GetDtlsPskCredentials);
 
     socketConnect();
 
     // CAinitiateSslHandshake
-    ca_mutex_lock(g_sslContextMutex);
+    oc_mutex_lock(g_sslContextMutex);
     InitiateTlsHandshake(&serverAddr);
-    ca_mutex_unlock(g_sslContextMutex);
+    oc_mutex_unlock(g_sslContextMutex);
 
     ret = CAsslGenerateOwnerPsk(&serverAddr,
           label, sizeof(label),
@@ -2262,14 +3166,14 @@ static void * testCAsslGenerateOwnerPsk(void * arg)
           ownerPsk, 0x100);
 
     // CAcloseTlsConnection
-    ca_mutex_lock(g_sslContextMutex);
+    oc_mutex_lock(g_sslContextMutex);
     SslEndPoint_t * tep = GetSslPeer(&serverAddr);
     mbedtls_ssl_close_notify(&tep->ssl);
     RemovePeerFromList(&tep->sep.endpoint);
-    ca_mutex_unlock(g_sslContextMutex);
+    oc_mutex_unlock(g_sslContextMutex);
 
     // CAdeinitTlsAdapter
-    ca_mutex_lock(g_sslContextMutex);
+    oc_mutex_lock(g_sslContextMutex);
     DeletePeerList();
     mbedtls_x509_crt_free(&g_caSslContext->crt);
     mbedtls_pk_free(&g_caSslContext->pkey);
@@ -2279,8 +3183,8 @@ static void * testCAsslGenerateOwnerPsk(void * arg)
     mbedtls_entropy_free(&g_caSslContext->entropy);
     OICFree(g_caSslContext);
     g_caSslContext = NULL;
-    ca_mutex_unlock(g_sslContextMutex);
-    ca_mutex_free(g_sslContextMutex);
+    oc_mutex_unlock(g_sslContextMutex);
+    oc_mutex_free(g_sslContextMutex);
     g_sslContextMutex = NULL;
 
     socketClose();
@@ -2296,7 +3200,9 @@ static void * testCAsslGenerateOwnerPsk(void * arg)
         return (void *) 0xFF;
     }
 }
+#endif
 
+/*
 TEST(TLSAdaper, Test_11)
 {
     pthread_t thread1, thread2;
@@ -2323,3 +3229,16 @@ TEST(TLSAdaper, Test_11)
 
     EXPECT_EQ(0, arg);
 }
+*/
+
+TEST(TLSAdaper, Test_ParseChain)
+{
+    int errNum;
+    mbedtls_x509_crt crt;
+    mbedtls_x509_crt_init(&crt);
+    int ret = ParseChain(&crt, certChain, certChainLen, &errNum);
+    mbedtls_x509_crt_free(&crt);
+
+    EXPECT_EQ(10, ret + errNum);
+}
+
index c89cb4c..d7a121c 100644 (file)
@@ -23,11 +23,30 @@ env.AppendUnique(CA_SRC = [os.path.join('./../util/src/cautilinterface.c')])
 if target_os == 'android':
        if (('BLE' in ca_transport) or ('ALL' in ca_transport)):
                        env.AppendUnique(CA_SRC = [
-                       os.path.join(src_dir, 'camanager', 'android', 'caleconnectionmanager.c'),
-                       os.path.join(src_dir, 'camanager', 'android', 'caleautoconnector.c'),
-                       os.path.join(src_dir, 'camanager', 'android', 'camanagerleutil.c'),
-                       os.path.join(src_dir, 'camanager', 'android', 'camanagerdevice.c')])
+                       os.path.join(src_dir, 'camanager', 'bt_le_manager', 'android', 'caleconnectionmanager.c'),
+                       os.path.join(src_dir, 'camanager', 'bt_le_manager', 'android', 'caleautoconnector.c'),
+                       os.path.join(src_dir, 'camanager', 'bt_le_manager', 'android', 'camanagerleutil.c'),
+                       os.path.join(src_dir, 'camanager', 'bt_le_manager', 'android', 'camanagerdevice.c')])
 
        if (('BT' in ca_transport) or ('ALL' in ca_transport)):
                        env.AppendUnique(CA_SRC = [
-                       os.path.join(src_dir, 'btpairing' ,'android', 'cabtpairing.c')])
\ No newline at end of file
+                       os.path.join(src_dir, 'btpairing' ,'android', 'cabtpairing.c')])
+
+if target_os == 'ios':
+       if (('BLE' in ca_transport) or ('ALL' in ca_transport)):
+                       env.AppendUnique(CA_SRC = [
+                       os.path.join(src_dir, 'camanager', 'bt_le_manager', 'ios', 'caleconnectionmanager.m'),
+                       os.path.join(src_dir, 'camanager', 'bt_le_manager', 'ios', 'caleautoconnector.m'),
+                       os.path.join(src_dir, 'camanager', 'bt_le_manager', 'ios', 'camanagerleutil.m'),
+                       os.path.join(src_dir, 'camanager', 'bt_le_manager', 'ios', 'camanagerdevice.m')])
+
+if target_os == 'tizen':
+       if (('BLE' in ca_transport) or ('ALL' in ca_transport)):
+                       env.AppendUnique(CA_SRC = [
+                       os.path.join(src_dir, 'camanager', 'bt_le_manager', 'tizen', 'caleconnectionmanager.c')])
+
+env.AppendUnique(CA_SRC = [
+               os.path.join(src_dir, 'camanager', 'caconnectionmanager.c'),
+               os.path.join(src_dir, 'camanager', 'camanagerutil.c'),
+               os.path.join(src_dir, 'camanager', 'camessagearbiter.c'),
+               os.path.join(src_dir, 'camanager', 'capolicymanager.c')])
diff --git a/resource/csdk/connectivity/util/inc/caconnectionmanager.h b/resource/csdk/connectivity/util/inc/caconnectionmanager.h
new file mode 100644 (file)
index 0000000..47ac402
--- /dev/null
@@ -0,0 +1,118 @@
+/* *****************************************************************
+ *
+ * Copyright 2016 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 function for connection manager
+ */
+
+#ifndef CA_CONNECTIONMANAGER_H_
+#define CA_CONNECTIONMANAGER_H_
+
+#include <stdint.h>
+
+#include <coap/coap.h>
+#include "cathreadpool.h"
+#include "octhread.h"
+#include "logger.h"
+#include "uarraylist.h"
+#include "cacommon.h"
+#include "caprotocolmessage.h"
+#include "camessagehandler.h"
+#include "cautilinterface.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * Callback to send replaced data.
+ * @param[in]   data    send data.
+ */
+typedef void (*CASendThreadFunc)(CAData_t *data);
+
+/**
+ * Callback to notify received data from the remote endpoint.
+ * @param[in]   data    received data.
+ */
+typedef void (*CAReceiveThreadFunc)(CAData_t *data);
+
+/**
+ * Context of connection manager
+ */
+typedef struct
+{
+    /** send method for block data. **/
+    CASendThreadFunc sendThreadFunc;
+
+    /** callback function for received message. **/
+    CAReceiveThreadFunc receivedThreadFunc;
+
+    /** array list on which the thread is operating. **/
+    u_arraylist_t *dataList;
+
+    /** data list mutex for synchronization. **/
+    oc_mutex dataListMutex;
+
+    /** sender mutex for synchronization. **/
+    oc_mutex dataSenderMutex;
+} CAConnectionManagerContext_t;
+
+/**
+ * Initializes the connection manager context.
+ * @param[in]  CASendThreadFunc    function point to add data in send queue thread.
+ * @param[in]  CAReceiveThreadFunc function point to add data in receive queue thread.
+ * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CAInitializeConnectionManager(CASendThreadFunc blockSendMethod,
+                                         CAReceiveThreadFunc receivedDataCallback);
+
+/**
+ * Terminate the connection manager context.
+ */
+void CATerminateConnectionManager();
+
+/**
+ * Initialize mutex.
+ * @return ::CASTATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CAInitConnectionManagerMutexVariables();
+
+/**
+ * Terminate mutex.
+ */
+void CATerminateConnectionManagerMutexVariables();
+
+/**
+ * Get request/response message to send.
+ */
+CAData_t* CAGetConnectionManagerMessageData(CAData_t *data);
+
+/**
+ * Start connection manager.
+ */
+void CAStartConnectionManagerService(CMConfigureInfo_t info);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif  // CA_CONNECTIONMANAGER_H_
index c15b05c..4a0de07 100644 (file)
@@ -48,6 +48,44 @@ CAResult_t CASetLEClientAutoConnectionDeviceInfo();
  */
 CAResult_t CAUnsetLEClientAutoConnectionDeviceInfo();
 
+//custom advertisement data
+#if defined(__TIZEN__) && defined(LE_ADAPTER) && defined(BLE_CUSTOM_ADVERTISE)
+CAResult_t CAManagerLEServerSetAdvertisementData(const char* data, int length);
+CAResult_t CAManagerLEServerSetScanResponseData(const char* data, int length);
+#endif
+
+#if defined(__APPLE__) && defined(LE_ADAPTER)
+/**
+ * initialize client connection manager
+ *
+ * @return  ::CA_STATUS_OK or ::CA_STATUS_FAILED or ::CA_MEMORY_ALLOC_FAILED
+ */
+CAResult_t CAManagerLEClientInitialize();
+
+/**
+ * terminate client connection manager
+ *
+ * @return  ::CA_STATUS_OK or ::CA_STATUS_FAILED or ::CA_MEMORY_ALLOC_FAILED
+ */
+CAResult_t CAManagerLEClientTerminate();
+
+/**
+ * stop BLE scan.
+ */
+void CAManagerLEStopScan();
+
+/**
+ * start BLE scan.
+ */
+void CAManagerLEStartScan();
+
+/**
+ * Disconnect from peripheral
+ */
+void CAManagerLEDisconnect();
+
+#endif
+
 #if defined(__ANDROID__) && defined(LE_ADAPTER)
 /**
  * initialize client connection manager
@@ -74,8 +112,31 @@ CAResult_t CAManagerLEClientTerminate(JNIEnv *env);
  */
 void CAManagerLESetScanInterval(jint intervalTime, jint workingCount);
 
+/**
+ * stop BLE scan.
+ */
+void CAManagerLEStopScan();
 #endif
 
+/**
+ * start BLE advertising.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CAManagerLEStartAdvertising();
+
+/**
+ * stop BLE advertising.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CAManagerLEStopAdvertising();
+
+
+/**
+ * set CAUtilConfig_t configure.
+ * @param[in]  config       ::CAUtilConfig_t value
+ */
+void CAManagerSetConfigure(CAUtilConfig_t config);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
@@ -26,7 +26,7 @@
 #include "caleautoconnector.h"
 #include "cacommonutil.h"
 #include "logger.h"
-#include "camutex.h"
+#include "octhread.h"
 
 #define TAG "OIC_CA_LE_AUTO_CONN"
 
@@ -34,50 +34,50 @@ static const size_t MAX_RETRY_COUNT = 5;
 static const size_t TIMEOUT = 1000000;
 static const size_t WAITING_TIME = 500000;
 
-static ca_mutex g_connectRetryMutex = NULL;
-static ca_cond g_connectRetryCond = NULL;
+static oc_mutex g_connectRetryMutex = NULL;
+static oc_cond g_connectRetryCond = NULL;
 
-static ca_mutex g_recoveryMutex = NULL;
-static ca_cond g_recoveryCond = NULL;
+static oc_mutex g_recoveryMutex = NULL;
+static oc_cond g_recoveryCond = NULL;
 
 CAResult_t CAManagerInitLEAutoConnection()
 {
     if (NULL == g_connectRetryMutex)
     {
-        g_connectRetryMutex = ca_mutex_new();
+        g_connectRetryMutex = oc_mutex_new();
         if (NULL == g_connectRetryMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_connectRetryCond)
     {
-        g_connectRetryCond = ca_cond_new();
+        g_connectRetryCond = oc_cond_new();
         if (NULL == g_connectRetryCond)
         {
-            OIC_LOG(ERROR, TAG, "ca_cond_new has failed");
+            OIC_LOG(ERROR, TAG, "oc_cond_new has failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_recoveryMutex)
     {
-        g_recoveryMutex = ca_mutex_new();
+        g_recoveryMutex = oc_mutex_new();
         if (NULL == g_recoveryMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
             return CA_STATUS_FAILED;
         }
     }
 
     if (NULL == g_recoveryCond)
     {
-        g_recoveryCond = ca_cond_new();
+        g_recoveryCond = oc_cond_new();
         if (NULL == g_recoveryCond)
         {
-            OIC_LOG(ERROR, TAG, "ca_cond_new has failed");
+            OIC_LOG(ERROR, TAG, "oc_cond_new has failed");
             return CA_STATUS_FAILED;
         }
     }
@@ -89,27 +89,27 @@ void CAManagerTerminateLEAutoConnection()
 {
     if (g_connectRetryCond)
     {
-        ca_cond_signal(g_connectRetryCond);
-        ca_cond_free(g_connectRetryCond);
+        oc_cond_signal(g_connectRetryCond);
+        oc_cond_free(g_connectRetryCond);
         g_connectRetryCond = NULL;
     }
 
     if (g_connectRetryMutex)
     {
-        ca_mutex_free(g_connectRetryMutex);
+        oc_mutex_free(g_connectRetryMutex);
         g_connectRetryMutex = NULL;
     }
 
     if (g_recoveryCond)
     {
-        ca_cond_signal(g_recoveryCond);
-        ca_cond_free(g_recoveryCond);
+        oc_cond_signal(g_recoveryCond);
+        oc_cond_free(g_recoveryCond);
         g_recoveryCond = NULL;
     }
 
     if (g_recoveryMutex)
     {
-        ca_mutex_free(g_recoveryMutex);
+        oc_mutex_free(g_recoveryMutex);
         g_recoveryMutex = NULL;
     }
 }
@@ -120,20 +120,20 @@ CAResult_t CAManagerStartAutoConnection(JNIEnv *env, jstring remote_le_address)
     VERIFY_NON_NULL(remote_le_address, TAG, "remote_le_address is null");
 
     OIC_LOG(DEBUG, TAG, "IN - CAManagerStartAutoConnection");
-    ca_mutex_lock(g_connectRetryMutex);
+    oc_mutex_lock(g_connectRetryMutex);
 
     bool isAutoConnecting = false;
     if (CA_STATUS_OK != CAManagerGetAutoConnectingFlag(env, remote_le_address, &isAutoConnecting))
     {
         OIC_LOG(DEBUG, TAG, "CAManagerIsAutoConnecting has failed");
-        ca_mutex_unlock(g_connectRetryMutex);
+        oc_mutex_unlock(g_connectRetryMutex);
         return CA_STATUS_FAILED;
     }
 
     if (isAutoConnecting)
     {
         OIC_LOG(INFO, TAG, "connection has been already in progress or completed");
-        ca_mutex_unlock(g_connectRetryMutex);
+        oc_mutex_unlock(g_connectRetryMutex);
         return CA_STATUS_FAILED;
     }
 
@@ -147,9 +147,9 @@ CAResult_t CAManagerStartAutoConnection(JNIEnv *env, jstring remote_le_address)
         {
             OIC_LOG_V(INFO, TAG, "retry will be started at least %d times after delay 1sec",
                       MAX_RETRY_COUNT - retry_cnt - 1);
-            if (ca_cond_wait_for(g_connectRetryCond, g_connectRetryMutex, TIMEOUT) == 0)
+            if (oc_cond_wait_for(g_connectRetryCond, g_connectRetryMutex, TIMEOUT) == 0)
             {
-                ca_mutex_unlock(g_connectRetryMutex);
+                oc_mutex_unlock(g_connectRetryMutex);
                 OIC_LOG(INFO, TAG, "request to connect gatt was canceled");
                 return CA_STATUS_OK;
             }
@@ -161,7 +161,7 @@ CAResult_t CAManagerStartAutoConnection(JNIEnv *env, jstring remote_le_address)
             break;
         }
     }
-    ca_mutex_unlock(g_connectRetryMutex);
+    oc_mutex_unlock(g_connectRetryMutex);
     OIC_LOG(DEBUG, TAG, "OUT - CAManagerStartAutoConnection");
     return res;
 }
@@ -206,14 +206,14 @@ CAResult_t CAManagerProcessRecovery(JNIEnv *env, uint16_t adapter_state)
     VERIFY_NON_NULL(env, TAG, "env");
     OIC_LOG(DEBUG, TAG, "IN - CAManagerProcessRecovery");
 
-    ca_mutex_lock(g_recoveryMutex);
+    oc_mutex_lock(g_recoveryMutex);
     CAResult_t res = CA_STATUS_OK;
 
     switch(adapter_state)
     {
         case STATE_OFF:
             // adapter will be enabled automatically after WAITING_TIME.
-            if (ca_cond_wait_for(g_recoveryCond, g_recoveryMutex, WAITING_TIME) == 0)
+            if (oc_cond_wait_for(g_recoveryCond, g_recoveryMutex, WAITING_TIME) == 0)
             {
                 OIC_LOG(INFO, TAG, "BT recovery was canceled");
             }
@@ -240,7 +240,7 @@ CAResult_t CAManagerProcessRecovery(JNIEnv *env, uint16_t adapter_state)
             break;
     }
 
-    ca_mutex_unlock(g_recoveryMutex);
+    oc_mutex_unlock(g_recoveryMutex);
     OIC_LOG(DEBUG, TAG, "OUT - CAManagerProcessRecovery");
 
     return res;
@@ -286,6 +286,38 @@ void CAManagerLESetScanInterval(jint interval, jint count)
     CALERestartScanWithInterval(interval, count, BLE_SCAN_ENABLE);
 }
 
+void CAManagerLEStopScan()
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerLEStopScan");
+    CALERestartScanWithInterval(0, 0, BLE_SCAN_DISABLE);
+}
+
+void CAManagerSetConfigure(CAUtilConfig_t config)
+{
+    OIC_LOG_V(INFO, TAG, "set configure for bleFlags : %d", config.bleFlags);
+    caglobals.bleFlags = config.bleFlags;
+}
+
+CAResult_t CAManagerLEStartAdvertising()
+{
+    CAResult_t ret = CALEServerStartAdvertise();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CALEServerStartAdvertise has failed");
+    }
+    return ret;
+}
+
+CAResult_t CAManagerLEStopAdvertising()
+{
+    CAResult_t ret = CALEServerStopAdvertise();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CAManagerLEStopAdvertising has failed");
+    }
+    return ret;
+}
+
 JNIEXPORT void JNICALL
 Java_org_iotivity_ca_CaLeClientInterface_caManagerAdapterStateChangedCallback(
         JNIEnv *env, jobject obj, jint state)
@@ -403,9 +435,6 @@ JNIEXPORT void JNICALL
 Java_org_iotivity_ca_CaLeClientInterface_caManagerLeGattConnectionStateChangeCB(
         JNIEnv *env, jobject obj, jobject gatt, jint status, jint newState)
 {
-    OIC_LOG_V(INFO, TAG, "caManagerLeGattConnectionStateChangeCB - status %d, newState %d",
-              status, newState);
-
     VERIFY_NON_NULL_VOID(env, TAG, "env");
     VERIFY_NON_NULL_VOID(obj, TAG, "obj");
     VERIFY_NON_NULL_VOID(gatt, TAG, "gatt");
@@ -428,12 +457,8 @@ Java_org_iotivity_ca_CaLeClientInterface_caManagerLeGattConnectionStateChangeCB(
         return;
     }
 
-    OIC_LOG_V(DEBUG, TAG, "caManagerLeGattConnectionStateChangeCB - address [%s]", address);
-
     if (GATT_SUCCESS == status && state_connected == newState) // le connected
     {
-        OIC_LOG(DEBUG, TAG, "LE is connected");
-
         CAResult_t res = CAManagerReadRemoteRssi(env, gatt);
         if (CA_STATUS_OK != res)
         {
@@ -443,8 +468,6 @@ Java_org_iotivity_ca_CaLeClientInterface_caManagerLeGattConnectionStateChangeCB(
     }
     else if (state_disconnected == newState)// le disconnected
     {
-        OIC_LOG(DEBUG, TAG, "LE is disconnected");
-
         if (LINK_LOSS == status || REMOTE_DISCONNECT == status)
         {
             if (!CAManagerIsInACDataList(env, jni_address))
@@ -485,7 +508,6 @@ Java_org_iotivity_ca_CaLeClientInterface_caManagerLeServicesDiscoveredCallback(J
                                                                                jobject gatt,
                                                                                jint status)
 {
-    OIC_LOG_V(INFO, TAG, "caManagerLeServicesDiscoveredCallback - status %d", status);
     VERIFY_NON_NULL_VOID(env, TAG, "env");
     VERIFY_NON_NULL_VOID(obj, TAG, "obj");
     VERIFY_NON_NULL_VOID(gatt, TAG, "gatt");
@@ -494,7 +516,8 @@ Java_org_iotivity_ca_CaLeClientInterface_caManagerLeServicesDiscoveredCallback(J
     {
         if (!g_connectedDeviceSet)
         {
-            OIC_LOG(ERROR, TAG, "g_connectedDeviceSet is null");
+            OIC_LOG(INFO, TAG, "g_connectedDeviceSet is needed for CM. "
+                    "please call CAManagerLEClientInitialize");
             return;
         }
 
@@ -513,8 +536,6 @@ Java_org_iotivity_ca_CaLeClientInterface_caManagerLeServicesDiscoveredCallback(J
             return;
         }
 
-        OIC_LOG_V(DEBUG, TAG, "ServicesDiscovered device : %s", address);
-
         if (CAManagerIsConnectedDeviceAddress(env, g_context, jni_address, g_connectedDeviceSet))
         {
             OIC_LOG(INFO, TAG, "AC list - the address will be added to ACData list");
@@ -532,8 +553,6 @@ Java_org_iotivity_ca_CaLeClientInterface_caManagerLeServicesDiscoveredCallback(J
 
         (*env)->ReleaseStringUTFChars(env, jni_address, address);
         (*env)->DeleteLocalRef(env, jni_address);
-
-        OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
     }
     else
     {
 #include "cacommonutil.h"
 #include "camanagerleutil.h"
 #include "uarraylist.h"
-#include "camutex.h"
+#include "octhread.h"
 #include "camanagerdevice.h"
 #include "oic_malloc.h"
 
 #define TAG "OIC_CA_MANAGER_DEVICE"
 
 static u_arraylist_t *g_deviceACDataList = NULL;
-static ca_mutex g_deviceACDataListMutex = NULL;
+static oc_mutex g_deviceACDataListMutex = NULL;
 static bool g_isBTRecovery = false;
 
 jstring CAManagerGetLEAddressFromACData(JNIEnv *env, size_t idx)
@@ -66,13 +66,13 @@ void CAManagerCreateACDataList()
 {
     OIC_LOG(DEBUG, TAG, "CAManagerCreateACDataList");
 
-    ca_mutex_lock(g_deviceACDataListMutex);
+    oc_mutex_lock(g_deviceACDataListMutex);
     if (NULL == g_deviceACDataList)
     {
         OIC_LOG(DEBUG, TAG, "Create AC Data list");
         g_deviceACDataList = u_arraylist_create();
     }
-    ca_mutex_unlock(g_deviceACDataListMutex);
+    oc_mutex_unlock(g_deviceACDataListMutex);
 }
 
 void CAManagerDestroyACDataList()
@@ -90,10 +90,10 @@ CAResult_t CAManagerInitMutexVaraibles()
 {
     if (NULL == g_deviceACDataListMutex)
     {
-        g_deviceACDataListMutex = ca_mutex_new();
+        g_deviceACDataListMutex = oc_mutex_new();
         if (NULL == g_deviceACDataListMutex)
         {
-            OIC_LOG(ERROR, TAG, "ca_mutex_new has failed");
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
             return CA_STATUS_FAILED;
         }
     }
@@ -104,14 +104,13 @@ void CAManagerTerminateMutexVariables()
 {
     if (g_deviceACDataListMutex)
     {
-        ca_mutex_free(g_deviceACDataListMutex);
+        oc_mutex_free(g_deviceACDataListMutex);
         g_deviceACDataListMutex = NULL;
     }
 }
 
 static CAManagerACData_t *CAManagerCreateACData(jstring jaddress)
 {
-    OIC_LOG(DEBUG, TAG, "IN - CAManagerCreateACData");
     VERIFY_NON_NULL_RET(jaddress, TAG, "jaddress", NULL);
 
     // create AC data
@@ -124,8 +123,6 @@ static CAManagerACData_t *CAManagerCreateACData(jstring jaddress)
 
     data->address = jaddress;
     data->isAutoConnecting = false;
-
-    OIC_LOG(DEBUG, TAG, "OUT - CAManagerCreateACData");
     return data;
 }
 
@@ -134,13 +131,13 @@ bool CAManagerIsInACDataList(JNIEnv *env, jstring jaddress)
     VERIFY_NON_NULL_RET(env, TAG, "env", NULL);
     VERIFY_NON_NULL_RET(jaddress, TAG, "jaddress", false);
 
-    ca_mutex_lock(g_deviceACDataListMutex);
+    oc_mutex_lock(g_deviceACDataListMutex);
 
     const char* address = (*env)->GetStringUTFChars(env, jaddress, NULL);
     if (!address)
     {
         OIC_LOG(ERROR, TAG, "address is null");
-        ca_mutex_unlock(g_deviceACDataListMutex);
+        oc_mutex_unlock(g_deviceACDataListMutex);
         return false;
     }
 
@@ -153,7 +150,7 @@ bool CAManagerIsInACDataList(JNIEnv *env, jstring jaddress)
         {
             OIC_LOG(ERROR, TAG, "curData is null");
             (*env)->ReleaseStringUTFChars(env, jaddress, address);
-            ca_mutex_unlock(g_deviceACDataListMutex);
+            oc_mutex_unlock(g_deviceACDataListMutex);
             return false;
         }
 
@@ -162,7 +159,7 @@ bool CAManagerIsInACDataList(JNIEnv *env, jstring jaddress)
         {
             OIC_LOG(ERROR, TAG, "address is null");
             (*env)->ReleaseStringUTFChars(env, jaddress, address);
-            ca_mutex_unlock(g_deviceACDataListMutex);
+            oc_mutex_unlock(g_deviceACDataListMutex);
             return false;
         }
 
@@ -170,7 +167,7 @@ bool CAManagerIsInACDataList(JNIEnv *env, jstring jaddress)
         {
             (*env)->ReleaseStringUTFChars(env, curData->address, setAddress);
             (*env)->ReleaseStringUTFChars(env, jaddress, address);
-            ca_mutex_unlock(g_deviceACDataListMutex);
+            oc_mutex_unlock(g_deviceACDataListMutex);
             return true;
         }
         (*env)->ReleaseStringUTFChars(env, curData->address, setAddress);
@@ -178,15 +175,13 @@ bool CAManagerIsInACDataList(JNIEnv *env, jstring jaddress)
 
     OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in list", address);
     (*env)->ReleaseStringUTFChars(env, jaddress, address);
-    ca_mutex_unlock(g_deviceACDataListMutex);
+    oc_mutex_unlock(g_deviceACDataListMutex);
 
     return false;
 }
 
 void CAManagerAddACData(JNIEnv *env, jstring jaddress)
 {
-    OIC_LOG(DEBUG, TAG, "IN - CAManagerAddACData");
-
     VERIFY_NON_NULL_VOID(env, TAG, "env");
     VERIFY_NON_NULL_VOID(jaddress, TAG, "jaddress");
 
@@ -198,16 +193,14 @@ void CAManagerAddACData(JNIEnv *env, jstring jaddress)
 
         CAManagerACData_t *data = CAManagerCreateACData(gaddress);
 
-        ca_mutex_lock(g_deviceACDataListMutex);
+        oc_mutex_lock(g_deviceACDataListMutex);
         u_arraylist_add(g_deviceACDataList, data);
-        ca_mutex_unlock(g_deviceACDataListMutex);
+        oc_mutex_unlock(g_deviceACDataListMutex);
     }
     else
     {
         OIC_LOG(DEBUG, TAG, "the address is already in ACData list");
     }
-
-    OIC_LOG(DEBUG, TAG, "OUT - CAManagerAddACData");
 }
 
 CAResult_t CAManagerRemoveACData(JNIEnv *env, jstring jaddress)
@@ -216,13 +209,13 @@ CAResult_t CAManagerRemoveACData(JNIEnv *env, jstring jaddress)
     VERIFY_NON_NULL(env, TAG, "env");
     VERIFY_NON_NULL(jaddress, TAG, "jaddress");
 
-    ca_mutex_lock(g_deviceACDataListMutex);
+    oc_mutex_lock(g_deviceACDataListMutex);
 
     const char* address = (*env)->GetStringUTFChars(env, jaddress, NULL);
     if (!address)
     {
         OIC_LOG(ERROR, TAG, "address is null");
-        ca_mutex_unlock(g_deviceACDataListMutex);
+        oc_mutex_unlock(g_deviceACDataListMutex);
         return CA_STATUS_FAILED;
     }
 
@@ -237,7 +230,7 @@ CAResult_t CAManagerRemoveACData(JNIEnv *env, jstring jaddress)
         {
             OIC_LOG(ERROR, TAG, "curData is null");
             (*env)->ReleaseStringUTFChars(env, jaddress, address);
-            ca_mutex_unlock(g_deviceACDataListMutex);
+            oc_mutex_unlock(g_deviceACDataListMutex);
             return CA_STATUS_FAILED;
         }
 
@@ -246,7 +239,7 @@ CAResult_t CAManagerRemoveACData(JNIEnv *env, jstring jaddress)
         {
             OIC_LOG(ERROR, TAG, "address is null");
             (*env)->ReleaseStringUTFChars(env, jaddress, address);
-            ca_mutex_unlock(g_deviceACDataListMutex);
+            oc_mutex_unlock(g_deviceACDataListMutex);
             return CA_STATUS_FAILED;
         }
 
@@ -257,7 +250,7 @@ CAResult_t CAManagerRemoveACData(JNIEnv *env, jstring jaddress)
                 OIC_LOG(ERROR, TAG, "removal has failed.");
                 (*env)->ReleaseStringUTFChars(env, jaddress, address);
                 (*env)->ReleaseStringUTFChars(env, curData->address, setAddress);
-                ca_mutex_unlock(g_deviceACDataListMutex);
+                oc_mutex_unlock(g_deviceACDataListMutex);
                 return CA_STATUS_FAILED;
             }
 
@@ -270,7 +263,7 @@ CAResult_t CAManagerRemoveACData(JNIEnv *env, jstring jaddress)
 
             OICFree(curData);
             (*env)->ReleaseStringUTFChars(env, jaddress, address);
-            ca_mutex_unlock(g_deviceACDataListMutex);
+            oc_mutex_unlock(g_deviceACDataListMutex);
             OIC_LOG(DEBUG, TAG, "remove done");
             return CA_STATUS_OK;
         }
@@ -279,7 +272,7 @@ CAResult_t CAManagerRemoveACData(JNIEnv *env, jstring jaddress)
 
     OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in list", address);
     (*env)->ReleaseStringUTFChars(env, jaddress, address);
-    ca_mutex_unlock(g_deviceACDataListMutex);
+    oc_mutex_unlock(g_deviceACDataListMutex);
 
     return CA_STATUS_OK;
 }
@@ -289,7 +282,7 @@ CAResult_t CAManagerRemoveAllACData(JNIEnv *env)
     OIC_LOG(DEBUG, TAG, "IN - CAManagerRemoveAllACData");
     VERIFY_NON_NULL(env, TAG, "env");
 
-    ca_mutex_lock(g_deviceACDataListMutex);
+    oc_mutex_lock(g_deviceACDataListMutex);
 
     size_t length = u_arraylist_length(g_deviceACDataList);
     for (size_t idx = 0; idx < length; idx++)
@@ -299,14 +292,14 @@ CAResult_t CAManagerRemoveAllACData(JNIEnv *env)
         if (!curData)
         {
             OIC_LOG(ERROR, TAG, "curData is null");
-            ca_mutex_unlock(g_deviceACDataListMutex);
+            oc_mutex_unlock(g_deviceACDataListMutex);
             return CA_STATUS_FAILED;
         }
 
         if (NULL == u_arraylist_remove(g_deviceACDataList, idx))
         {
             OIC_LOG(ERROR, TAG, "removal has failed.");
-            ca_mutex_unlock(g_deviceACDataListMutex);
+            oc_mutex_unlock(g_deviceACDataListMutex);
             return CA_STATUS_FAILED;
         }
 
@@ -317,7 +310,7 @@ CAResult_t CAManagerRemoveAllACData(JNIEnv *env)
 
         OICFree(curData);
     }
-    ca_mutex_unlock(g_deviceACDataListMutex);
+    oc_mutex_unlock(g_deviceACDataListMutex);
     OIC_LOG(DEBUG, TAG, "OUT - CAManagerRemoveAllACData");
     return CA_STATUS_OK;
 }
@@ -328,13 +321,13 @@ CAResult_t CAManagerGetAutoConnectingFlag(JNIEnv *env, jstring jaddress, bool *f
     VERIFY_NON_NULL(env, TAG, "env");
     VERIFY_NON_NULL(jaddress, TAG, "jaddress");
 
-    ca_mutex_lock(g_deviceACDataListMutex);
+    oc_mutex_lock(g_deviceACDataListMutex);
 
     const char* address = (*env)->GetStringUTFChars(env, jaddress, NULL);
     if (!address)
     {
         OIC_LOG(ERROR, TAG, "address is null");
-        ca_mutex_unlock(g_deviceACDataListMutex);
+        oc_mutex_unlock(g_deviceACDataListMutex);
         return CA_STATUS_FAILED;
     }
 
@@ -347,7 +340,7 @@ CAResult_t CAManagerGetAutoConnectingFlag(JNIEnv *env, jstring jaddress, bool *f
         {
             OIC_LOG(ERROR, TAG, "curData is null");
             (*env)->ReleaseStringUTFChars(env, jaddress, address);
-            ca_mutex_unlock(g_deviceACDataListMutex);
+            oc_mutex_unlock(g_deviceACDataListMutex);
             return CA_STATUS_FAILED;
         }
 
@@ -356,7 +349,7 @@ CAResult_t CAManagerGetAutoConnectingFlag(JNIEnv *env, jstring jaddress, bool *f
         {
             OIC_LOG(ERROR, TAG, "setAddress is null");
             (*env)->ReleaseStringUTFChars(env, jaddress, address);
-            ca_mutex_unlock(g_deviceACDataListMutex);
+            oc_mutex_unlock(g_deviceACDataListMutex);
             return CA_STATUS_FAILED;
         }
 
@@ -367,7 +360,7 @@ CAResult_t CAManagerGetAutoConnectingFlag(JNIEnv *env, jstring jaddress, bool *f
             *flag = curData->isAutoConnecting;
             (*env)->ReleaseStringUTFChars(env, curData->address, setAddress);
             (*env)->ReleaseStringUTFChars(env, jaddress, address);
-            ca_mutex_unlock(g_deviceACDataListMutex);
+            oc_mutex_unlock(g_deviceACDataListMutex);
             return CA_STATUS_OK;
         }
         (*env)->ReleaseStringUTFChars(env, curData->address, setAddress);
@@ -375,7 +368,7 @@ CAResult_t CAManagerGetAutoConnectingFlag(JNIEnv *env, jstring jaddress, bool *f
 
     OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in list", address);
     (*env)->ReleaseStringUTFChars(env, jaddress, address);
-    ca_mutex_unlock(g_deviceACDataListMutex);
+    oc_mutex_unlock(g_deviceACDataListMutex);
 
     return CA_STATUS_FAILED;
 }
@@ -386,13 +379,13 @@ bool CAManagerSetAutoConnectingFlag(JNIEnv *env, jstring jaddress, bool flag)
     VERIFY_NON_NULL_RET(env, TAG, "env", false);
     VERIFY_NON_NULL_RET(jaddress, TAG, "jaddress", false);
 
-    ca_mutex_lock(g_deviceACDataListMutex);
+    oc_mutex_lock(g_deviceACDataListMutex);
 
     const char* address = (*env)->GetStringUTFChars(env, jaddress, NULL);
     if (!address)
     {
         OIC_LOG(ERROR, TAG, "address is null");
-        ca_mutex_unlock(g_deviceACDataListMutex);
+        oc_mutex_unlock(g_deviceACDataListMutex);
         return false;
     }
 
@@ -405,7 +398,7 @@ bool CAManagerSetAutoConnectingFlag(JNIEnv *env, jstring jaddress, bool flag)
         {
             OIC_LOG(ERROR, TAG, "curData is null");
             (*env)->ReleaseStringUTFChars(env, jaddress, address);
-            ca_mutex_unlock(g_deviceACDataListMutex);
+            oc_mutex_unlock(g_deviceACDataListMutex);
             return false;
         }
 
@@ -414,7 +407,7 @@ bool CAManagerSetAutoConnectingFlag(JNIEnv *env, jstring jaddress, bool flag)
         {
             OIC_LOG(ERROR, TAG, "address is null");
             (*env)->ReleaseStringUTFChars(env, jaddress, address);
-            ca_mutex_unlock(g_deviceACDataListMutex);
+            oc_mutex_unlock(g_deviceACDataListMutex);
             return false;
         }
 
@@ -425,7 +418,7 @@ bool CAManagerSetAutoConnectingFlag(JNIEnv *env, jstring jaddress, bool flag)
             curData->isAutoConnecting = flag;
             (*env)->ReleaseStringUTFChars(env, curData->address, setAddress);
             (*env)->ReleaseStringUTFChars(env, jaddress, address);
-            ca_mutex_unlock(g_deviceACDataListMutex);
+            oc_mutex_unlock(g_deviceACDataListMutex);
             return true;
         }
         (*env)->ReleaseStringUTFChars(env, curData->address, setAddress);
@@ -433,7 +426,7 @@ bool CAManagerSetAutoConnectingFlag(JNIEnv *env, jstring jaddress, bool flag)
 
     OIC_LOG_V(DEBUG, TAG, "[%s] doesn't exist in list", address);
     (*env)->ReleaseStringUTFChars(env, jaddress, address);
-    ca_mutex_unlock(g_deviceACDataListMutex);
+    oc_mutex_unlock(g_deviceACDataListMutex);
 
     return false;
 }
@@ -215,8 +215,6 @@ bool CAManagerControlAdapter(JNIEnv *env, bool control_flag)
 
 CAResult_t CAManagerReadRemoteRssi(JNIEnv *env, jobject bluetoothGatt)
 {
-    OIC_LOG(DEBUG, TAG, "CAManagerReadRemoteRssi");
-
     VERIFY_NON_NULL(env, TAG, "env is null");
     VERIFY_NON_NULL(bluetoothGatt, TAG, "bluetoothGatt is null");
 
@@ -227,7 +225,6 @@ CAResult_t CAManagerReadRemoteRssi(JNIEnv *env, jobject bluetoothGatt)
     }
 
     // get BluetoothGatt class
-    OIC_LOG(DEBUG, TAG, "get BluetoothGatt class");
     jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, CLASSPATH_BT_GATT);
     if (!jni_cid_BluetoothGatt)
     {
@@ -235,7 +232,6 @@ CAResult_t CAManagerReadRemoteRssi(JNIEnv *env, jobject bluetoothGatt)
         return CA_STATUS_FAILED;
     }
 
-    OIC_LOG(DEBUG, TAG, "discovery gatt services method");
     jmethodID jni_mid_readRemoteRssi = (*env)->GetMethodID(env, jni_cid_BluetoothGatt,
                                                              "readRemoteRssi", "()Z");
     if (!jni_mid_readRemoteRssi)
@@ -244,7 +240,6 @@ CAResult_t CAManagerReadRemoteRssi(JNIEnv *env, jobject bluetoothGatt)
         return CA_STATUS_FAILED;
     }
     // call disconnect gatt method
-    OIC_LOG(DEBUG, TAG, "CALL API - request readremoteRssi");
     jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_readRemoteRssi);
     if (!ret)
     {
@@ -613,7 +608,6 @@ bool CAManagerAddConnectedDeviceAddress(JNIEnv *env, jobject context,
 bool CAManagerIsConnectedDeviceAddress(JNIEnv *env, jobject context,
                                        jstring address, jobject set)
 {
-    OIC_LOG(DEBUG, TAG, "CAManagerIsConnectedDeviceAddress");
     VERIFY_NON_NULL_RET(env, TAG, "env", false);
     VERIFY_NON_NULL_RET(context, TAG, "context", false);
 
@@ -722,7 +716,6 @@ jobject CAManagerCreateSetString(JNIEnv *env)
 bool CAManagerCallFuncSetString(JNIEnv *env, jstring address, jobject set,
                                 CASetMethod_t method_type)
 {
-    OIC_LOG(DEBUG, TAG, "CAManagerCallFuncSetString");
     VERIFY_NON_NULL_RET(env, TAG, "env", false);
     VERIFY_NON_NULL_RET(address, TAG, "address", false);
     VERIFY_NON_NULL_RET(set, TAG, "set", false);
@@ -738,17 +731,14 @@ bool CAManagerCallFuncSetString(JNIEnv *env, jstring address, jobject set,
     switch (method_type)
     {
         case CM_CONTAINS:
-            OIC_LOG(DEBUG, TAG, "java/util/HashSet.contains");
             jni_mid_setMethod = (*env)->GetMethodID(env, jni_cls_set, "contains",
                                                     "(Ljava/lang/Object;)Z");
             break;
         case CM_ADD:
-            OIC_LOG(DEBUG, TAG, "java/util/HashSet.add");
             jni_mid_setMethod = (*env)->GetMethodID(env, jni_cls_set, "add",
                                                     "(Ljava/lang/Object;)Z");
             break;
         case CM_REMOVE:
-            OIC_LOG(DEBUG, TAG, "java/util/HashSet.remove");
             jni_mid_setMethod = (*env)->GetMethodID(env, jni_cls_set, "remove",
                                                     "(Ljava/lang/Object;)Z");
             break;
@@ -762,6 +752,5 @@ bool CAManagerCallFuncSetString(JNIEnv *env, jstring address, jobject set,
     }
 
     jboolean res = (*env)->CallBooleanMethod(env, set, jni_mid_setMethod, address);
-    OIC_LOG_V(DEBUG, TAG, "method return result : %d", res);
     return res;
 }
diff --git a/resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/caleautoconnector.h b/resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/caleautoconnector.h
new file mode 100755 (executable)
index 0000000..4ae237a
--- /dev/null
@@ -0,0 +1,73 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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_AUTO_CONNECTOR_H_
+#define CA_AUTO_CONNECTOR_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define STATE_OFF 10
+#define START_RECOVERY 1
+
+/**
+ * start auto connection.
+ * @param[in]   remote_le_address     remote address.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CAManagerStartAutoConnection(const char *remote_le_address);
+
+/**
+ * request connect gatt on client in adapter
+ * @param[in]   remote_le_address     remote address.
+ * @return  gatt profile object.
+ */
+CAResult_t CAManagerConnectGatt(const char *remote_le_address);
+
+/**
+ * initialize LE AutoConnection.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CAManagerInitLEAutoConnection();
+
+/**
+ * terminate LE AutoConnection
+ */
+void CAManagerTerminateLEAutoConnection();
+
+/**
+ * process BT recovery.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   adapter_state         recovery state to process.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CAManagerProcessRecovery(uint16_t adapter_state);
+
+
+void CAManagerSignalToRetryCond(const char* address);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* CA_AUTO_CONNECTOR_H_ */
+
diff --git a/resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/caleautoconnector.m b/resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/caleautoconnector.m
new file mode 100755 (executable)
index 0000000..48fbdee
--- /dev/null
@@ -0,0 +1,222 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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 "cacommon.h"
+#include "caleclient.h"
+#include "camanagerleutil.h"
+#include "camanagerdevice.h"
+#include "caleautoconnector.h"
+#include "cacommonutil.h"
+#include "logger.h"
+#include "octhread.h"
+
+#define TAG "OIC_CA_LE_AUTO_CONN"
+
+static const size_t MAX_RETRY_COUNT = 1;
+static const size_t TIMEOUT = 30000000; //30sec
+static const size_t WAITING_TIME = 500000;
+
+static oc_mutex g_connectRetryMutex = NULL;
+static oc_cond g_connectRetryCond = NULL;
+
+static oc_mutex g_recoveryMutex = NULL;
+static oc_cond g_recoveryCond = NULL;
+
+CAResult_t CAManagerInitLEAutoConnection()
+{
+    if (NULL == g_connectRetryMutex)
+    {
+        g_connectRetryMutex = oc_mutex_new();
+        if (NULL == g_connectRetryMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_connectRetryCond)
+    {
+        g_connectRetryCond = oc_cond_new();
+        if (NULL == g_connectRetryCond)
+        {
+            OIC_LOG(ERROR, TAG, "oc_cond_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_recoveryMutex)
+    {
+        g_recoveryMutex = oc_mutex_new();
+        if (NULL == g_recoveryMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_recoveryCond)
+    {
+        g_recoveryCond = oc_cond_new();
+        if (NULL == g_recoveryCond)
+        {
+            OIC_LOG(ERROR, TAG, "oc_cond_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    return CA_STATUS_OK;
+}
+
+void CAManagerTerminateLEAutoConnection()
+{
+    if (g_connectRetryCond)
+    {
+        oc_cond_signal(g_connectRetryCond);
+        oc_cond_free(g_connectRetryCond);
+        g_connectRetryCond = NULL;
+    }
+
+    if (g_connectRetryMutex)
+    {
+        oc_mutex_free(g_connectRetryMutex);
+        g_connectRetryMutex = NULL;
+    }
+
+    if (g_recoveryCond)
+    {
+        oc_cond_signal(g_recoveryCond);
+        oc_cond_free(g_recoveryCond);
+        g_recoveryCond = NULL;
+    }
+
+    if (g_recoveryMutex)
+    {
+        oc_mutex_free(g_recoveryMutex);
+        g_recoveryMutex = NULL;
+    }
+}
+
+CAResult_t CAManagerStartAutoConnection(const char *remote_le_address)
+{
+    VERIFY_NON_NULL(remote_le_address, TAG, "remote_le_address is null");
+
+    OIC_LOG(DEBUG, TAG, "IN - CAManagerStartAutoConnection");
+
+    if (true == CAManagerGetAutoConnectionFlag(remote_le_address))
+    {
+        OIC_LOG(INFO, TAG, "auto connecting.");
+        return CA_STATUS_FAILED;
+    }
+
+    oc_mutex_lock(g_connectRetryMutex);
+
+    CBPeripheral *peripheral = CAManagerGetValueConnectedDeviceAddress(remote_le_address);
+    if (!peripheral) {
+        OIC_LOG_V(ERROR, TAG, "address : %s is not valid one", remote_le_address);
+        oc_mutex_unlock(g_connectRetryMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    for (size_t retry_cnt = 0 ; retry_cnt < MAX_RETRY_COUNT ; retry_cnt++)
+    {
+        // there is retry logic 5 times when connectGatt call has failed
+        // because BT adapter might be not ready yet.
+        CAResult_t ret = CAManagerConnectGatt(remote_le_address);
+
+        if (ret != CA_STATUS_OK) {
+            OIC_LOG_V(ERROR, TAG, "CAManagerConnectGatt fail!!");
+            oc_mutex_unlock(g_connectRetryMutex);
+            return CA_STATUS_FAILED;
+        }
+
+        OIC_LOG_V(INFO, TAG, "retry will be started at least %d times after delay 30sec",
+                  MAX_RETRY_COUNT - retry_cnt - 1);
+        if (oc_cond_wait_for(g_connectRetryCond, g_connectRetryMutex, TIMEOUT) == 0)
+        {
+            OIC_LOG(INFO, TAG, "request to connect gatt is done");
+            //CALEClientSetAutoConnectFlag(remote_le_address, false);
+            oc_mutex_unlock(g_connectRetryMutex);
+            return CA_STATUS_OK;
+        }
+        // time out. retry connection
+        CALEClientConnectCancel(peripheral);
+    }
+    oc_mutex_unlock(g_connectRetryMutex);
+    OIC_LOG(DEBUG, TAG, "OUT - CAManagerStartAutoConnection");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAManagerConnectGatt(const char *remote_le_address)
+{
+    VERIFY_NON_NULL_RET(remote_le_address, TAG, "remote_le_address", NULL);
+
+    OIC_LOG(DEBUG, TAG, "IN - CAManagerConnectGatt");
+
+    CBPeripheral *peripheral = CAManagerGetValueConnectedDeviceAddress(remote_le_address);
+
+    if (!peripheral) {
+        OIC_LOG_V(ERROR, TAG, "address : %s is not valid one", remote_le_address);
+        return CA_STATUS_FAILED;
+    }
+
+    // request to connection with AutoConnection Flag
+    OIC_LOG(INFO, TAG, "request to gatt connection for auto connection");
+    CAResult_t res = CALEClientConnect(peripheral, true);
+    if (CA_STATUS_FAILED == res)
+    {
+        OIC_LOG(INFO, TAG, "re-connection will be started");
+        return CA_STATUS_FAILED;
+    }
+
+    // set flag auto connection is requested.
+    CAManagerSetAutoConnectionFlag(remote_le_address, true);
+
+    OIC_LOG(DEBUG, TAG, "OUT - CAManagerConnectGatt");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAManagerProcessRecovery(uint16_t adapter_state)
+{
+    OIC_LOG(DEBUG, TAG, "IN - CAManagerProcessRecovery");
+
+    oc_mutex_lock(g_recoveryMutex);
+    CAResult_t res = CA_STATUS_OK;
+
+    oc_mutex_unlock(g_recoveryMutex);
+    OIC_LOG(DEBUG, TAG, "OUT - CAManagerProcessRecovery");
+
+    return res;
+}
+
+void CAManagerSignalToRetryCond(const char* address)
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerSignalToRetryCond");
+    if(true == CALEClientGetAutoConnectFlag(address))
+    {
+        if(g_connectRetryCond)
+        {
+            OIC_LOG(DEBUG, TAG, "signaling!");
+            oc_mutex_lock(g_connectRetryMutex);
+            oc_cond_signal(g_connectRetryCond);
+            oc_mutex_unlock(g_connectRetryMutex);
+
+        }
+    }
+}
diff --git a/resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/caleconnectionmanager.m b/resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/caleconnectionmanager.m
new file mode 100755 (executable)
index 0000000..a6d22ce
--- /dev/null
@@ -0,0 +1,413 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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 "logger.h"
+#include "cautilinterface.h"
+#include "camanagerleinterface.h"
+#include "camanagerleutil.h"
+#include "caleautoconnector.h"
+#include "cacommon.h"
+#include "cacommonutil.h"
+#include "camanagerdevice.h"
+#include "caleclient.h"
+#include "caleutils.h"
+#include "uarraylist.h"
+
+#define TAG "OIC_CA_MANAGER_LE"
+
+static const int SUPPORT_ADNROID_API_LEVEL = 18;
+static const int AUTH_FAIL = 5;
+static const int LINK_LOSS = 8;
+static const int ACCEPT_TIMEOUT_EXCEPTION = 16;
+static const int REMOTE_DISCONNECT = 19;
+static const int LOCAL_DISCONNECT = 22;
+static const int CONNECTION_FAILED_TO_BE_EASTABLISHED = 62;
+static const int USER_REMOVED_BOND = 68;
+
+static dispatch_queue_t g_caManagerAutoConnectQueue = NULL;
+static NSMutableDictionary *g_candidateACList = NULL;
+
+static void CAManagerAdapterStateChangeCB(CBCentralManager *central);
+static void CAManagerLeGattConnectionStateChangeCB(CBPeripheral *peripheral,
+                                       const char *remote_address, bool connected, NSError *error);
+static void CAManagerLeGattServiceDiscoveredCB(CBPeripheral *peripheral, const char *remote_address,
+                                               NSError *error);
+
+
+CAResult_t CASetLEClientAutoConnectionDeviceInfo(const char* address)
+{
+    OIC_LOG(DEBUG, TAG, "CASetClientAutoConnectionDeviceInfo");
+    VERIFY_NON_NULL(address, TAG, "address");
+
+    OIC_LOG_V(DEBUG, TAG, "set [%s] for Auto Connection", address);
+
+    if (!CAManagerCheckBTAddress(address))
+    {
+        OIC_LOG(ERROR, TAG, "this address is not BT address string format");
+        return CA_STATUS_FAILED;
+    }
+
+    // if there is target address in SharedPreference. it will be reseted.
+    if (CAManagerIsConnectedDeviceAddress(address))
+    {
+        if (!CAManagerRemoveConnectedDeviceAddress(address))
+        {
+            OIC_LOG(ERROR, TAG, "Preference - remove has failed");
+        }
+        else
+        {
+            OIC_LOG(INFO, TAG, "Preference - remove success");
+        }
+    }
+
+    // check candidate AC list
+    if (g_candidateACList[@(address)] != nil) {
+        OIC_LOG_V(DEBUG, TAG, "Candidate device : %s", address);
+
+        if(!CAManagerIsConnectedDeviceAddress(address))
+        {
+            // if BLE address is matched each other
+            // this address will be added into auto connection list.
+            OIC_LOG(INFO, TAG, "AC list - address will be added into ACData list");
+            CBPeripheral *peripheral = (CBPeripheral *)g_candidateACList[@(address)];
+
+            CAManagerAddACData(address);
+
+            if(!CAManagerSetValueConnectedDeviceAddress(peripheral, address))
+            {
+                OIC_LOG(ERROR, TAG, "AC list - address is un-registered");
+                return CA_STATUS_FAILED;
+            }
+
+            [g_candidateACList removeObjectForKey:@(address)];
+
+            CAManagerSetAutoConnectionFlag(address, false);
+
+            // next connection will be requested as true flag
+            // after first connection
+            CALEClientSetAutoConnectFlag(address, true);
+        }
+    }
+
+    else
+    {
+        // it will be added new target address.
+        if (!CAManagerAddConnectedDeviceAddress(address))
+        {
+            OIC_LOG(ERROR, TAG, "Preference - putting has failed");
+        }
+        else
+        {
+            OIC_LOG(INFO, TAG, "Preference - putting success");
+        }
+    }
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAUnsetLEClientAutoConnectionDeviceInfo(const char* address)
+{
+    OIC_LOG(DEBUG, TAG, "CAUnsetClientAutoConnectionDeviceInfo");
+    VERIFY_NON_NULL(address, TAG, "address");
+
+    OIC_LOG_V(DEBUG, TAG, "unset [%s] for Auto Connection", address);
+
+    if (!CAManagerCheckBTAddress(address))
+    {
+        OIC_LOG(ERROR, TAG, "this address is not BT address string format");
+        return CA_STATUS_FAILED;
+    }
+
+    // if there is target address in SharedPreference. it would be removed
+    if (CAManagerIsConnectedDeviceAddress(address))
+    {
+        if (!CAManagerRemoveConnectedDeviceAddress(address))
+        {
+            OIC_LOG(ERROR, TAG, "Preference - remove has failed");
+        }
+        else
+        {
+            OIC_LOG(INFO, TAG, "Preference - remove success");
+        }
+    }
+
+    // remove target device for auto connection
+    CAResult_t ret = CAManagerRemoveData(address);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "CAManagerRemoveData has failed");
+    }
+
+    CALEClientSetAutoConnectFlag(address, false);
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAManagerLEClientInitialize()
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerClientInitialize");
+
+    CAManagerInitMutexVaraibles();
+    CAManagerInitLEAutoConnection();
+
+    CAManagerCreateACDataList();
+
+    g_candidateACList = [[NSMutableDictionary alloc] init];
+
+    if (!g_caManagerAutoConnectQueue) {
+        g_caManagerAutoConnectQueue = dispatch_queue_create("com.caManager.AucoConnect",
+                                                            DISPATCH_QUEUE_SERIAL);
+    }
+
+    //callback register to caleclient
+    CALEClientSetCAManagerCallback(CAManagerAdapterStateChangeCB,
+                                   CAManagerLeGattConnectionStateChangeCB,
+                                   CAManagerLeGattServiceDiscoveredCB);
+
+    // get last connected device list
+    bool ret = false;
+    ret = CAManagerGetConnectedDeviceAddress();
+    if (!ret)
+    {
+        // create new set<String> object
+        ret = CAManagerCreateSetString();
+        if (ret)
+        {
+            OIC_LOG(DEBUG, TAG, "created new SetString");
+        }
+        else
+        {
+            OIC_LOG(ERROR, TAG, "CAManagerCreateSetString has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+    else
+    {
+        OIC_LOG(DEBUG, TAG, "get previous Set<String> object");
+    }
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAManagerLEClientTerminate()
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerClientTerminate");
+
+    // stop gatt connection
+    CAResult_t res = CALEClientDisconnectAll();
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "CALEClientDisconnectAll has failed");
+    }
+
+    res = CAManagerRemoveAllData();
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "CAManagerRemoveAllData has failed");
+    }
+
+    CAManagerTerminateLEAutoConnection();
+    CAManagerTerminateMutexVariables();
+
+    if (g_candidateACList)
+    {
+        [g_candidateACList removeAllObjects];
+        [g_candidateACList release];
+        g_candidateACList = nil;
+    }
+
+    res = CAManagerTerminateSetString();
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "CAManagerTerminateSetString has failed");
+    }
+
+    return res;
+}
+
+
+//BLE CALLBACK
+
+
+static void CAManagerAdapterStateChangeCB(CBCentralManager *central)
+{
+    switch(central.state){
+        case CBCentralManagerStatePoweredOn:
+        {
+            OIC_LOG(DEBUG, TAG, "AdapterStateChangedCallback : state_on");
+
+            // when BT state is on. recovery flag has to be reset.
+            CAManagerSetBTRecovery(false);
+
+            // find target device for autoconnect
+            size_t length = CAManagerGetACDataLength();
+            OIC_LOG_V(DEBUG, TAG, "target device : %d", length);
+            for (size_t idx = 0; idx < length; idx++)
+            {
+                char *leAddress = CAManagerGetLEAddressFromACData(idx);
+                if (leAddress)
+                {
+                    dispatch_async(g_caManagerAutoConnectQueue, ^{
+                        CAResult_t res = CAManagerStartAutoConnection(leAddress);
+                        if (CA_STATUS_OK != res)
+                        {
+                            OIC_LOG(ERROR, TAG, "CAManagerStartAutoConnection has failed");
+                            return;
+                        }
+                    });
+                }
+            }
+            break;
+        }
+        case CBCentralManagerStatePoweredOff:
+        {
+            OIC_LOG(DEBUG, TAG, "AdapterStateChangedCallback : state_off");
+
+            // reset autoconnect flag for all target devices
+            size_t length = CAManagerGetACDataLength();
+            for (size_t idx = 0; idx < length; idx++)
+            {
+                char *address = CAManagerGetLEAddressFromACData(idx);
+                if (address)
+                {
+                    CAManagerSetAutoConnectionFlag(address, false);
+                    CAManagerSignalToRetryCond(address); //cancel if auto connecting is processing
+                }
+            }
+
+            // check whether BT recovery is needed or not
+            if (CAManagerIsRecoveryFlagSet())
+            {
+                CAManagerProcessRecovery(STATE_OFF);
+            }
+            break;
+        }
+        case CBCentralManagerStateUnsupported:
+        case CBCentralManagerStateUnauthorized:
+        case CBCentralManagerStateResetting:
+        default:
+            break;
+    }
+}
+
+static void CAManagerLeGattConnectionStateChangeCB(CBPeripheral *peripheral,
+                                         const char *remote_address, bool connected, NSError *error)
+{
+    OIC_LOG_V(DEBUG, TAG, "peripheral : %s", [[peripheral name] UTF8String]);
+    OIC_LOG_V(DEBUG, TAG, "CAManagerLeGattConnectionStateChangeCB-remote_Address(%s),connected(%s)",
+              remote_address, connected ? "true":"false");
+    if (error) {
+        OIC_LOG_V(ERROR, TAG, "error : %s", [[error localizedDescription] UTF8String]);
+    }
+
+    VERIFY_NON_NULL_VOID(peripheral, TAG, "peripheral");
+    VERIFY_NON_NULL_VOID(remote_address, TAG, "remote_address");
+
+
+    if (connected) {
+        OIC_LOG(DEBUG, TAG, "LE is connected");
+    }
+    else {
+        OIC_LOG(DEBUG, TAG, "LE is disconnected");
+
+        if (!CAManagerIsMatchedACData(remote_address))
+        {
+            OIC_LOG_V(DEBUG, TAG, "this[%s] is not target address for Auto Connection",
+                      remote_address);
+            return;
+        }
+
+        CAManagerSetAutoConnectionFlag(remote_address, false);
+
+        dispatch_async(g_caManagerAutoConnectQueue, ^{
+            CAResult_t res = CAManagerStartAutoConnection(remote_address);
+            if (CA_STATUS_OK != res)
+            {
+                OIC_LOG(ERROR, TAG, "CAManagerStartAutoConnection has failed");
+                return;
+            }
+        });
+    }
+}
+
+static void CAManagerLeGattServiceDiscoveredCB(CBPeripheral *peripheral,
+                                               const char *remote_address, NSError *error)
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerLeGattServiceDiscoveredCB");
+
+    if (error){
+        OIC_LOG(ERROR, TAG, "error - CAManagerLeGattServiceDiscoveredCB");
+        return;
+    }
+
+    VERIFY_NON_NULL_VOID(peripheral, TAG, "peripheral");
+    VERIFY_NON_NULL_VOID(remote_address, TAG, "remote_address");
+
+    OIC_LOG_V(DEBUG, TAG, "ServicesDiscovered device : %s", remote_address);
+
+    if (CAManagerIsConnectedDeviceAddress(remote_address))
+    {
+        // if BLE address is matched each other
+        // this address will be added into auto connection list.
+        OIC_LOG(INFO, TAG, "AC list - address will be added into ACData list");
+        CAManagerAddACData(remote_address);
+
+        if(!CAManagerSetValueConnectedDeviceAddress(peripheral, remote_address))
+        {
+            OIC_LOG(ERROR, TAG, "AC list - address is un-registered");
+            return;
+        }
+
+        CAManagerSetAutoConnectionFlag(remote_address, false);
+
+        // next connection will be requested as true flag
+        // after first connection
+        CALEClientSetAutoConnectFlag(remote_address, true);
+    }
+    else
+    {
+        OIC_LOG(INFO, TAG, "AC list - device is not matched");
+
+        //store candidate AC peripheral
+        g_candidateACList[@(remote_address)] = peripheral;
+    }
+
+    CAManagerSignalToRetryCond(remote_address);
+
+    OIC_LOG(INFO, TAG, "ServicesDiscovery is successful");
+}
+
+void CAManagerLEStopScan()
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerLEStopScan");
+    CALEClientStopScan();
+}
+
+void CAManagerLEStartScan()
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerLEStartScan");
+    CALEClientStartScan();
+}
+
+void CAManagerLEDisconnect()
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerLEDisconnect");
+    CALEClientDisconnectAll();
+}
diff --git a/resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/camanagerdevice.h b/resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/camanagerdevice.h
new file mode 100755 (executable)
index 0000000..e56f5ea
--- /dev/null
@@ -0,0 +1,128 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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_MANAGER_DEVICE_H_
+#define CA_MANAGER_DEVICE_H_
+
+#include "uarraylist.h"
+#include "octhread.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*
+ * Auto Connection Target Device Identity
+ */
+typedef struct
+{
+    char address[18];      /**< remote address */
+    bool isAutoConnect;   /**< auto connection flag */
+} CAManagerACData_t;
+
+/**
+ * get address from auto connection list.
+ * @param[in]   idx                   index of auto connection data list.
+ * @return  address
+ */
+char* CAManagerGetLEAddressFromACData(size_t idx);
+
+/**
+ * create auto connection list.
+ */
+void CAManagerCreateACDataList();
+
+/**
+ * initialize mutex.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CAManagerInitMutexVaraibles();
+
+/**
+ * terminate mutex.
+ */
+void CAManagerTerminateMutexVariables();
+
+/**
+ * check whether target address is already contained in list or not.
+ * @param[in]   address              ble address.
+ * @return  true or false
+ */
+bool CAManagerIsMatchedACData(const char* address);
+
+/**
+ * add auto connection data into list.
+ * @param[in]   address              ble address.
+ */
+void CAManagerAddACData(const char* address);
+
+/**
+ * remove auto connection data for selected ble address.
+ * @param[in]   env                   JNI interface pointer.
+ * @param[in]   address               ble address.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CAManagerRemoveData(const char* address);
+
+/**
+ * remove auto connection data for all devices.
+ * @return  ::CA_STATUS_OK or ERROR CODES (::CAResult_t error codes in cacommon.h).
+ */
+CAResult_t CAManagerRemoveAllData();
+
+/**
+ * get current auto connection flag.
+ * @param[in]   address              ble address.
+ * @return  true or false
+ */
+bool CAManagerGetAutoConnectionFlag(const char* address);
+
+/**
+ * set auto connection flag.
+ * @param[in]   address              ble address.
+ * @param[in]   flag                  auto connection flag.
+ */
+void CAManagerSetAutoConnectionFlag(const char* address, bool flag);
+
+/**
+ * get length of auto connection list.
+ * @return  list size
+ */
+size_t CAManagerGetACDataLength();
+
+/**
+ * set BT adapter recovery flag.
+ * @param[in]   flag                  recovery flag.
+ */
+void CAManagerSetBTRecovery(bool flag);
+
+/**
+ * get BT adapter recovery flag.
+ * @return  recovery flag.
+ */
+bool CAManagerIsRecoveryFlagSet();
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* CA_MANAGER_DEVICE_H_ */
+
diff --git a/resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/camanagerdevice.m b/resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/camanagerdevice.m
new file mode 100755 (executable)
index 0000000..c5dedbe
--- /dev/null
@@ -0,0 +1,351 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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 <string.h>
+
+#include "cacommon.h"
+#include "logger.h"
+#include "cacommonutil.h"
+#include "camanagerleutil.h"
+#include "uarraylist.h"
+#include "octhread.h"
+#include "camanagerdevice.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+
+#define TAG "OIC_CA_MANAGER_DEVICE"
+
+static u_arraylist_t *g_deviceACDataList = NULL;
+static oc_mutex g_deviceACDataListMutex = NULL;
+static bool g_isBTRecovery = false;
+
+char* CAManagerGetLEAddressFromACData(size_t idx)
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerGetLEAddressFromACData");
+    OIC_LOG_V(DEBUG, TAG, "idx : %d", idx);
+    if (idx <= u_arraylist_length(g_deviceACDataList))
+    {
+        CAManagerACData_t *curData = (CAManagerACData_t *) u_arraylist_get(
+                g_deviceACDataList, idx);
+        if (!curData)
+        {
+            OIC_LOG(ERROR, TAG, "curData is null");
+            return NULL;
+        }
+
+        const char* address = curData->address;
+        if (!address)
+        {
+            OIC_LOG(ERROR, TAG, "address is null");
+            return NULL;
+        }
+        OIC_LOG_V(INFO, TAG, "found out target address : %s", address);
+
+        return curData->address;
+    }
+    return NULL;
+}
+
+void CAManagerCreateACDataList()
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerCreateACDataList");
+
+    oc_mutex_lock(g_deviceACDataListMutex);
+    // create new object array
+    if (g_deviceACDataList == NULL)
+    {
+        OIC_LOG(DEBUG, TAG, "Create AC Data list");
+
+        g_deviceACDataList = u_arraylist_create();
+    }
+    oc_mutex_unlock(g_deviceACDataListMutex);
+}
+
+CAResult_t CAManagerInitMutexVaraibles()
+{
+    if (NULL == g_deviceACDataListMutex)
+    {
+        g_deviceACDataListMutex = oc_mutex_new();
+        if (NULL == g_deviceACDataListMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+    return CA_STATUS_OK;
+}
+
+void CAManagerTerminateMutexVariables()
+{
+    if (g_deviceACDataListMutex)
+    {
+        oc_mutex_free(g_deviceACDataListMutex);
+        g_deviceACDataListMutex = NULL;
+    }
+}
+
+static CAManagerACData_t *CAManagerCreateACData(char *address)
+{
+    OIC_LOG(DEBUG, TAG, "IN-CAManagerCreateACData");
+    VERIFY_NON_NULL_RET(address, TAG, "address", NULL);
+
+    // create block data
+    CAManagerACData_t *data = (CAManagerACData_t *) OICCalloc(1, sizeof(*data));
+    if (!data)
+    {
+        OIC_LOG(ERROR, TAG, "memory alloc has failed");
+        return NULL;
+    }
+
+    OICStrcpy(data->address, strlen(address)+1, address);
+    data->isAutoConnect = false;
+
+    OIC_LOG(DEBUG, TAG, "OUT-CAManagerCreateACData");
+    return data;
+}
+
+bool CAManagerIsMatchedACData(const char* address)
+{
+    VERIFY_NON_NULL_RET(address, TAG, "address", false);
+
+    size_t length = u_arraylist_length(g_deviceACDataList);
+    for (size_t idx = 0; idx < length; idx++)
+    {
+        CAManagerACData_t *curData = (CAManagerACData_t *) u_arraylist_get(g_deviceACDataList,
+                                                                           idx);
+        if (!curData)
+        {
+            OIC_LOG(ERROR, TAG, "curData is null");
+            return false;
+        }
+
+        const char* setAddress = curData->address;
+        if (!setAddress)
+        {
+            OIC_LOG(ERROR, TAG, "address is null");
+            return false;
+        }
+
+        if (!strcmp(setAddress, address))
+        {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+void CAManagerAddACData(const char* address)
+{
+    OIC_LOG(DEBUG, TAG, "IN-CAManagerAddACData");
+
+    VERIFY_NON_NULL_VOID(address, TAG, "address");
+
+    oc_mutex_lock(g_deviceACDataListMutex);
+
+    if(!CAManagerIsMatchedACData(address))
+    {
+        OIC_LOG(DEBUG, TAG, "ACdata will be added");
+
+        CAManagerACData_t *data = CAManagerCreateACData(address);
+        u_arraylist_add(g_deviceACDataList, data);
+    }
+    oc_mutex_unlock(g_deviceACDataListMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT-CAManagerAddACData");
+}
+
+CAResult_t CAManagerRemoveData(const char* address)
+{
+    OIC_LOG(DEBUG, TAG, "IN-CAManagerRemoveData");
+    VERIFY_NON_NULL(address, TAG, "address");
+
+    oc_mutex_lock(g_deviceACDataListMutex);
+
+    OIC_LOG_V(DEBUG, TAG, "(%s) will be removed", address);
+
+    size_t length = u_arraylist_length(g_deviceACDataList);
+    for (size_t idx = 0; idx < length; idx++)
+    {
+        CAManagerACData_t *curData = (CAManagerACData_t *) u_arraylist_get(g_deviceACDataList,
+                                                                           idx);
+        if (!curData)
+        {
+            OIC_LOG(ERROR, TAG, "curData is null");
+            oc_mutex_unlock(g_deviceACDataListMutex);
+            return CA_STATUS_FAILED;
+        }
+
+        const char* setAddress = curData->address;
+        if (!setAddress)
+        {
+            OIC_LOG(ERROR, TAG, "address is null");
+            oc_mutex_unlock(g_deviceACDataListMutex);
+            return CA_STATUS_FAILED;
+        }
+
+        if (!strcmp(setAddress, address))
+        {
+            if (NULL == u_arraylist_remove(g_deviceACDataList, idx))
+            {
+                OIC_LOG(ERROR, TAG, "removal has failed.");
+                oc_mutex_unlock(g_deviceACDataListMutex);
+                return CA_STATUS_FAILED;
+            }
+
+            OICFree(curData);
+            oc_mutex_unlock(g_deviceACDataListMutex);
+            OIC_LOG(DEBUG, TAG, "remove done");
+            return CA_STATUS_OK;
+        }
+    }
+
+    oc_mutex_unlock(g_deviceACDataListMutex);
+    OIC_LOG(DEBUG, TAG, "OUT-CAManagerRemoveData");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAManagerRemoveAllData()
+{
+    OIC_LOG(DEBUG, TAG, "IN-CAManagerRemoveAllData");
+
+    oc_mutex_lock(g_deviceACDataListMutex);
+
+    size_t length = u_arraylist_length(g_deviceACDataList);
+    for (size_t idx = 0; idx < length; idx++)
+    {
+        CAManagerACData_t *curData = (CAManagerACData_t *) u_arraylist_get(g_deviceACDataList,
+                                                                           idx);
+        if (!curData)
+        {
+            OIC_LOG(ERROR, TAG, "curData is null");
+            oc_mutex_unlock(g_deviceACDataListMutex);
+            return CA_STATUS_FAILED;
+        }
+
+        if (NULL == u_arraylist_remove(g_deviceACDataList, idx))
+        {
+            OIC_LOG(ERROR, TAG, "removal has failed.");
+            oc_mutex_unlock(g_deviceACDataListMutex);
+            return CA_STATUS_FAILED;
+        }
+
+        OICFree(curData);
+    }
+    oc_mutex_unlock(g_deviceACDataListMutex);
+    OIC_LOG(DEBUG, TAG, "OUT-CAManagerRemoveAllData");
+    return CA_STATUS_OK;
+}
+
+bool CAManagerGetAutoConnectionFlag(const char* address)
+{
+    OIC_LOG(DEBUG, TAG, "IN-CAManagerGetAutoConnectionFlag");
+    VERIFY_NON_NULL_RET(address, TAG, "address", NULL);
+
+    oc_mutex_lock(g_deviceACDataListMutex);
+
+    size_t length = u_arraylist_length(g_deviceACDataList);
+    for (size_t idx = 0; idx < length; idx++)
+    {
+        CAManagerACData_t *curData = (CAManagerACData_t *) u_arraylist_get(g_deviceACDataList,
+                                                                           idx);
+        if (!curData)
+        {
+            OIC_LOG(ERROR, TAG, "curData is null");
+            oc_mutex_unlock(g_deviceACDataListMutex);
+            return CA_STATUS_FAILED;
+        }
+
+        const char* setAddress = curData->address;
+        if (!setAddress)
+        {
+            OIC_LOG(ERROR, TAG, "setAddress is null");
+            oc_mutex_unlock(g_deviceACDataListMutex);
+            return CA_STATUS_FAILED;
+        }
+
+        if (!strcmp(setAddress, address))
+        {
+            oc_mutex_unlock(g_deviceACDataListMutex);
+            OIC_LOG_V(DEBUG, TAG, "flag is %d", curData->isAutoConnect);
+            return curData->isAutoConnect;
+        }
+    }
+    oc_mutex_unlock(g_deviceACDataListMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT-CAManagerGetAutoConnectionFlag");
+    return false;
+}
+
+void CAManagerSetAutoConnectionFlag(const char* address, bool flag)
+{
+    OIC_LOG(DEBUG, TAG, "IN-CAManagerSetAutoConnectionFlag");
+    VERIFY_NON_NULL_VOID(address, TAG, "address");
+
+    oc_mutex_lock(g_deviceACDataListMutex);
+
+    size_t length = u_arraylist_length(g_deviceACDataList);
+    for (size_t idx = 0; idx < length; idx++)
+    {
+        CAManagerACData_t *curData = (CAManagerACData_t *) u_arraylist_get(g_deviceACDataList,
+                                                                           idx);
+        if (!curData)
+        {
+            OIC_LOG(ERROR, TAG, "curData is null");
+            oc_mutex_unlock(g_deviceACDataListMutex);
+            return;
+        }
+
+        const char* setAddress = curData->address;
+        if (!setAddress)
+        {
+            OIC_LOG(ERROR, TAG, "address is null");
+            oc_mutex_unlock(g_deviceACDataListMutex);
+            return;
+        }
+
+        if (!strcmp(setAddress, address))
+        {
+            OIC_LOG_V(DEBUG, TAG, "flag is set to %d", flag);
+            curData->isAutoConnect = flag;
+            oc_mutex_unlock(g_deviceACDataListMutex);
+            return;
+        }
+    }
+    oc_mutex_unlock(g_deviceACDataListMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT-CAManagerSetAutoConnectionFlag");
+}
+
+size_t CAManagerGetACDataLength()
+{
+    return u_arraylist_length(g_deviceACDataList);
+}
+
+void CAManagerSetBTRecovery(bool flag)
+{
+    g_isBTRecovery = flag;
+    OIC_LOG_V(DEBUG, TAG, "BT recovery flag : %d", g_isBTRecovery);
+}
+
+bool CAManagerIsRecoveryFlagSet()
+{
+    return g_isBTRecovery;
+}
diff --git a/resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/camanagerleutil.h b/resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/camanagerleutil.h
new file mode 100755 (executable)
index 0000000..cac0342
--- /dev/null
@@ -0,0 +1,103 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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_MANAGER_LE_UTILS_H_
+#define CA_MANAGER_LE_UTILS_H_
+
+#import <Foundation/Foundation.h>
+#import <CoreBluetooth/CoreBluetooth.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef enum {
+    CM_CONTAINS = 1,
+    CM_ADD,
+    CM_REMOVE
+} CASetMethod_t;
+
+/**
+ * check whether the device is already put or not.
+ * @param[in]   address               LE address.
+ * @return  true or false
+ */
+bool CAManagerIsConnectedDeviceAddress(const char* address);
+
+/**
+ * add connected device into SharedPreference.
+ * @param[in]   address               ble address.
+ * @return  CBPeripheral object or nil
+ */
+CBPeripheral* CAManagerGetValueConnectedDeviceAddress(const char* address);
+
+/**
+ * add connected device into SharedPreference.
+ * @param[in]   peripheral            peripheral object.
+ * @param[in]   address               ble address.
+ * @return  true or false
+ */
+bool CAManagerSetValueConnectedDeviceAddress(CBPeripheral *peripheral, const char* address);
+
+/**
+ * add connected device into SharedPreference.
+ * @param[in]   address               ble address.
+ * @return  true or false
+ */
+bool CAManagerAddConnectedDeviceAddress(const char* address);
+
+/**
+ * get connected device from SharedPreference.
+ * @return  true or false
+ */
+bool CAManagerGetConnectedDeviceAddress();
+
+/**
+ * remove connected device to SharedPreference.
+ * @param[in]   address               LE address.
+ * @return  true or false
+ */
+bool CAManagerRemoveConnectedDeviceAddress(const char* address);
+
+/**
+ * Vaildate a String bluetooth address.
+ * @param[in]   address               LE address.
+ * @return  true or false
+ */
+bool CAManagerCheckBTAddress(const char *address);
+
+/**
+ * create new set<String> object.
+ * @return  true or false
+ */
+bool CAManagerCreateSetString();
+
+/**
+ * terminate new set<String> object.
+ * @return  CA_STATUS_OK or CA_STATUS_FAILED
+ */
+CAResult_t CAManagerTerminateSetString();
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* CA_MANAGER_LE_UTILS_H_ */
diff --git a/resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/camanagerleutil.m b/resource/csdk/connectivity/util/src/camanager/bt_le_manager/ios/camanagerleutil.m
new file mode 100755 (executable)
index 0000000..48a6c40
--- /dev/null
@@ -0,0 +1,295 @@
+/* ****************************************************************
+ *
+ * Copyright 2017 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 "cacommon.h"
+#include "logger.h"
+#include "cacommonutil.h"
+#include "camanagerleutil.h"
+#include "caleclient.h"
+#include "caleutils.h"
+
+#define TAG "OIC_CA_MANAGER_UTIL"
+
+static const NSString *NSUSERDEFULATS_KEY = @"acList_dictionary";
+static NSMutableDictionary *g_connectedDeviceSet = NULL;
+static NSMutableDictionary *g_peripherals = NULL;
+
+NSUserDefaults* CAManagerGetSharedPreference()
+{
+    return [NSUserDefaults standardUserDefaults];
+}
+
+bool CAManagerUpdatePrefStringSet(NSMutableDictionary *set)
+{
+    OIC_LOG(DEBUG, TAG, "IN-CAManagerUpdatePrefStringSet");
+    VERIFY_NON_NULL_RET(set, TAG, "set", false);
+
+    NSUserDefaults *userDefaults = CAManagerGetSharedPreference();
+    @synchronized (userDefaults) {
+        NSData *contentData = [NSKeyedArchiver archivedDataWithRootObject:set];
+        [userDefaults setObject:contentData forKey:NSUSERDEFULATS_KEY];
+    }
+
+    return [userDefaults synchronize];
+}
+
+NSMutableDictionary* CAManagerGetPrefStringSet()
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerGetPrefStringSet");
+
+    NSUserDefaults *userDefaults = CAManagerGetSharedPreference();
+
+    NSMutableDictionary *set = nil;
+
+    if (userDefaults) {
+        NSData *contentData = [[userDefaults objectForKey:NSUSERDEFULATS_KEY] mutableCopy];
+        if (contentData) {
+            set = (NSMutableDictionary*) [NSKeyedUnarchiver unarchiveObjectWithData:contentData];
+        }
+    }
+
+    return [set copy];
+}
+
+bool CAManagerContainsPrefStringSet()
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerContainsPrefStringSet");
+
+    NSUserDefaults *userDefaults = CAManagerGetSharedPreference();
+
+    NSData *data = nil;
+
+    if (userDefaults) {
+        data = [userDefaults dataForKey:NSUSERDEFULATS_KEY];
+    }
+
+    return data != nil ? true : false;
+}
+
+bool CAManagerRemovePrefStringSet()
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerRemovePrefStringSet");
+
+    NSUserDefaults *userDefaults = CAManagerGetSharedPreference();
+    @synchronized (userDefaults) {
+        [userDefaults removeObjectForKey:NSUSERDEFULATS_KEY];
+    }
+
+    return [userDefaults synchronize];
+}
+
+CBPeripheral* CAManagerGetValueConnectedDeviceAddress(const char* address)
+{
+    OIC_LOG(DEBUG, TAG, "IN-CAManagerGetValueConnectedDeviceAddress");
+
+    VERIFY_NON_NULL_RET(address, TAG, "address", nil);
+
+    NSString *ns_address = [NSString stringWithUTF8String:address];
+
+    if (![g_connectedDeviceSet objectForKey:ns_address] || ![g_peripherals objectForKey:ns_address])
+    {
+        OIC_LOG(DEBUG, TAG, "it's un-registered one");
+        return false;
+    }
+
+    return (CBPeripheral *)g_peripherals[ns_address];
+}
+
+bool CAManagerSetValueConnectedDeviceAddress(CBPeripheral *peripheral, const char* address)
+{
+    OIC_LOG(DEBUG, TAG, "IN-CAManagerSetValueConnectedDeviceAddress");
+
+    VERIFY_NON_NULL_RET(address, TAG, "address", false);
+
+    NSString *ns_address = [NSString stringWithUTF8String:address];
+
+    if ([g_connectedDeviceSet objectForKey:ns_address] && [g_peripherals objectForKey:ns_address])
+    {
+        OIC_LOG(DEBUG, TAG, "it's already done");
+        return true;
+    }
+
+    NSUUID *peri_identifier =[[NSUUID alloc] initWithUUIDString:
+                              [[peripheral identifier] UUIDString]];
+
+    [g_connectedDeviceSet setObject:peri_identifier forKey:ns_address];
+    [g_peripherals setObject:peripheral forKey:ns_address];
+
+    return true;
+    //return CAManagerUpdatePrefStringSet(g_connectedDeviceSet);
+}
+
+bool CAManagerAddConnectedDeviceAddress(const char* address)
+{
+    OIC_LOG(DEBUG, TAG, "IN-CAManagerAddConnectedDeviceAddress");
+
+    VERIFY_NON_NULL_RET(address, TAG, "address", false);
+
+    NSString *ns_address = [NSString stringWithUTF8String:address];
+
+    if ([g_connectedDeviceSet objectForKey:ns_address] && [g_peripherals objectForKey:ns_address])
+    {
+        OIC_LOG(DEBUG, TAG, "it's already done");
+        return true;
+    }
+
+    [g_connectedDeviceSet setObject:[NSNull null] forKey:ns_address];
+    [g_peripherals setObject:[NSNull null] forKey:ns_address];
+
+    return true;
+    //return CAManagerUpdatePrefStringSet(g_connectedDeviceSet);
+}
+
+bool CAManagerIsConnectedDeviceAddress(const char* address)
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerIsConnectedDeviceAddress");
+
+    VERIFY_NON_NULL_RET(address, TAG, "address", false);
+
+    NSString *ns_address = [NSString stringWithUTF8String:address];
+
+    return ([g_connectedDeviceSet objectForKey:ns_address] != nil &&
+            [g_peripherals objectForKey:ns_address] != nil) ? true : false;
+}
+
+bool CAManagerGetConnectedDeviceAddress()
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerGetConnectedDeviceAddress");
+
+    return false;
+}
+
+bool CAManagerRemoveConnectedDeviceAddress(const char* address)
+{
+    OIC_LOG(DEBUG, TAG, "IN-CAManagerRemoveConnectedDeviceAddress");
+
+    VERIFY_NON_NULL_RET(address, TAG, "address", false);
+
+    NSString *ns_address = [NSString stringWithUTF8String:address];
+
+    if (![g_connectedDeviceSet objectForKey:ns_address])
+    {
+        OIC_LOG(ERROR, TAG, "it's already done");
+        return true;
+    }
+
+    if (![g_peripherals objectForKey:ns_address])
+    {
+        OIC_LOG(ERROR, TAG, "identifier OR peripheral set is wrong");
+        return false;
+    }
+
+    [g_peripherals removeObjectForKey:ns_address];
+    [g_connectedDeviceSet removeObjectForKey:ns_address];
+
+    return true;
+}
+
+static bool ishexdigit(char var)
+{
+    if(var <= '9')
+    {
+        if(var >= '0') return true;
+        else           return false;
+    }
+    else if(var <= 'F')
+    {
+        if(var >= 'A') return true;
+        else           return false;
+    }
+    else if(var <= 'f')
+    {
+        if(var >= 'a') return true;
+        else           return false;
+    }
+
+    return false;
+}
+
+bool CAManagerCheckBTAddress(const char *address)
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerCheckBTAddress");
+
+    VERIFY_NON_NULL_RET(address, TAG, "address is null", false);
+
+    /*
+    * Check if the provided MAC address is valid.
+    * 1. The length of MAC address should always be 17.
+    * 2. Hyphens are expected at positions {3, 6, 9, 12, 15}.
+    * 3. The rest characters should be simple xdigits.
+    */
+    int hyphens[5] = {3, 6, 9, 12, 15};
+    if (strlen(address) != 17)
+    {
+        return false;//Oops. The lenth doesn't match.
+    }
+
+    for (int i = 0, counter = 0; i < 17; i ++)
+    {
+        char var = address[i];
+        if (i == hyphens[counter] - 1)// Check if a hyphen is expected here.
+        {
+            // Yep. We need a hyphen here.
+            if (var != ':')
+            {
+                return false;// Oops. The character is not a hyphen.
+            }
+            else
+            {
+                counter++;// Move on to the next expected hyphen position.
+            }
+        }
+        else
+        {
+            // Nope. The character here should be a simple xdigit
+            if (ishexdigit(var) == 0)
+            {
+                return false;// Oops. The current character is not a hyphen.
+            }
+        }
+    }
+    return true;// Seen'em all!
+}
+
+bool CAManagerCreateSetString()
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerCreateSetString");
+
+    g_connectedDeviceSet = [[NSMutableDictionary alloc] init];
+    g_peripherals = [[NSMutableDictionary alloc] init];
+
+    return (g_connectedDeviceSet != nil && g_peripherals != nil) ? true : false;
+}
+
+CAResult_t CAManagerTerminateSetString()
+{
+    OIC_LOG(DEBUG, TAG, "CAManagerTerminateSetString");
+
+    [g_connectedDeviceSet removeAllObjects];
+    [g_connectedDeviceSet release];
+
+    [g_peripherals removeAllObjects];
+    [g_peripherals release];
+
+    g_connectedDeviceSet = nil;
+    g_peripherals = nil;
+
+    return (g_connectedDeviceSet == nil && g_peripherals == nil) ? CA_STATUS_OK : CA_STATUS_FAILED;
+}
\ No newline at end of file
@@ -43,35 +43,32 @@ void CASetLENetworkMonitorCallbacks(CAAdapterStateChangedCB adapterStateCB,
 {
     OIC_LOG(DEBUG, TAG, "CASetLENetworkMonitorCallbacks");
 
-    g_adapterStateCB = adapterStateCB;
-    CASetNetworkMonitorCallback(CAManagerAdapterMonitorHandler);
-
-    g_connStateCB = connStateCB;
-    CASetLEConnectionStateChangedCallback(CAManagerConnectionMonitorHandler);
 }
 
-void CAStartServerLEAdvertising()
+CAResult_t CAManagerLEStartAdvertising()
 {
-    OIC_LOG(DEBUG, TAG, "CAStartServerLEAdvertising");
+    OIC_LOG(DEBUG, TAG, "CAManagerLEStartAdvertising");
 
-    CAResult_t res = CALEStartAdvertise(CA_GATT_SERVICE_UUID);
+    CAResult_t res = CALEStartAdvertise();
     if (CA_STATUS_OK != res)
     {
         OIC_LOG_V(ERROR, TAG, "Failed to start le advertising [%d]", res);
-        return;
+        return res;
     }
+    return res;
 }
 
-void CAStopServerLEAdvertising()
+CAResult_t CAManagerLEStopAdvertising()
 {
-    OIC_LOG(DEBUG, TAG, "CAStopServerLEAdvertising");
+    OIC_LOG(DEBUG, TAG, "CAManagerLEStopAdvertising");
 
     CAResult_t res = CALEStopAdvertise();
     if (CA_STATUS_OK != res)
     {
         OIC_LOG_V(ERROR, TAG, "Failed to stop le advertising [%d]", res);
-        return;
+        return res;
     }
+    return res;
 }
 
 CAResult_t CASetLEClientAutoConnectionDeviceInfo(const char * address)
@@ -87,58 +84,28 @@ CAResult_t CAUnsetLEClientAutoConnectionDeviceInfo(const char * address)
     (void)address;
     return CA_NOT_SUPPORTED;
 }
-
-static void CAManagerAdapterMonitorHandler(const CAEndpoint_t *info, CANetworkStatus_t status)
+#if defined(__TIZEN__) && defined(LE_ADAPTER) && defined(BLE_CUSTOM_ADVERTISE)
+CAResult_t CAManagerLEServerSetAdvertisementData(const char *data, int length)
 {
-    if (CA_INTERFACE_DOWN == status)
-    {
-        if (info && g_adapterStateCB)
-        {
-            g_adapterStateCB(info->adapter, false);
-            OIC_LOG(DEBUG, TAG, "Pass the disabled adapter state to upper layer");
-        }
-    }
-    else if (CA_INTERFACE_UP == status)
+
+    CAResult_t res =  CAsetServerAdvertisementData(data, length);
+
+    if (CA_STATUS_OK != res)
     {
-        if (info && g_adapterStateCB)
-        {
-            g_adapterStateCB(info->adapter, true);
-            OIC_LOG(DEBUG, TAG, "Pass the enabled adapter state to upper layer");
-        }
+        OIC_LOG_V(ERROR, TAG, "Failed to stop le CAManagerLEServerSetAdvertisementData [%d]", res);
+        return;
     }
 }
 
-static void CAManagerConnectionMonitorHandler(CATransportAdapter_t adapter,
-                                              const char *remoteAddress, bool connected)
+CAResult_t CAManagerLEServerSetScanResponseData(const char *data, int length)
 {
-    (void)adapter;
 
-    if (!remoteAddress)
-    {
-        OIC_LOG(ERROR, TAG, "remoteAddress is NULL");
-        return;
-    }
+    CAResult_t res =  CAsetServerSanResponseData(data, length);
 
-    if (connected)
-    {
-        if (g_connStateCB)
-        {
-            g_connStateCB(CA_ADAPTER_GATT_BTLE, remoteAddress, true);
-            OIC_LOG(DEBUG, TAG, "Pass the connected device info to upper layer");
-
-            // stop le advertising
-            CAStopServerLEAdvertising();
-        }
-    }
-    else
+    if (CA_STATUS_OK != res)
     {
-        if (g_connStateCB)
-        {
-            g_connStateCB(CA_ADAPTER_GATT_BTLE, remoteAddress, false);
-            OIC_LOG(DEBUG, TAG, "Pass the disconnected device info to upper layer");
-
-            // start le advertising to receive new connection request.
-            CAStartServerLEAdvertising();
-        }
+        OIC_LOG_V(ERROR, TAG, "Failed to stop le CAsetServerSanResponseData [%d]", res);
+        return;
     }
 }
+#endif
diff --git a/resource/csdk/connectivity/util/src/camanager/caconnectionmanager.c b/resource/csdk/connectivity/util/src/camanager/caconnectionmanager.c
new file mode 100644 (file)
index 0000000..d426ac3
--- /dev/null
@@ -0,0 +1,166 @@
+/* *****************************************************************
+ *
+ * Copyright 2016 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "caadapterutils.h"
+#include "cainterface.h"
+#include "camessagehandler.h"
+#include "caremotehandler.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "octhread.h"
+#include "logger.h"
+#include "caadapterutils.h"
+
+#include "caconnectionmanager.h"
+#include "capolicymanager.h"
+
+#define TAG "OIC_CM"
+
+static oc_mutex g_threadCMConfigureMutex = NULL;
+
+// context for connection manager
+static CAConnectionManagerContext_t g_context = {.sendThreadFunc = NULL,
+                                                 .receivedThreadFunc = NULL,
+                                                 .dataList = NULL};
+
+void CAStartConnectionManagerService(CMConfigureInfo_t info)
+{
+    OIC_LOG(DEBUG, TAG, "CAStartConnectionManagerService");
+
+    oc_mutex_lock(g_threadCMConfigureMutex);
+    CMSetConfigure(info);
+    oc_mutex_unlock(g_threadCMConfigureMutex);
+}
+
+CAData_t* CAGetConnectionManagerMessageData(CAData_t *data)
+{
+    OIC_LOG(DEBUG, TAG, "CAGetConnectionManagerMessageData");
+
+    VERIFY_NON_NULL_RET(data, TAG, "data is null", NULL);
+
+    // TODO
+    // decide specific reqeust/response message
+
+    return data;
+}
+
+CAResult_t CAInitializeConnectionManager(CASendThreadFunc sendThreadFunc,
+                                         CAReceiveThreadFunc receivedThreadFunc)
+{
+    OIC_LOG(DEBUG, TAG, "CAInitializeConnectionManager");
+
+    if (!g_context.sendThreadFunc)
+    {
+        g_context.sendThreadFunc = sendThreadFunc;
+    }
+
+    if (!g_context.receivedThreadFunc)
+    {
+        g_context.receivedThreadFunc = receivedThreadFunc;
+    }
+
+    if (!g_context.dataList)
+    {
+        g_context.dataList = u_arraylist_create();
+    }
+
+    CAResult_t res = CAInitConnectionManagerMutexVariables();
+    if (CA_STATUS_OK != res)
+    {
+        u_arraylist_free(&g_context.dataList);
+        g_context.dataList = NULL;
+        OIC_LOG(ERROR, TAG, "init has failed");
+    }
+    return res;
+}
+
+void CATerminateConnectionManager()
+{
+    OIC_LOG(DEBUG, TAG, "CATerminateConnectionManager");
+
+    if (g_context.dataList)
+    {
+        // TODO
+        // Remove all of management data();
+        u_arraylist_free(&g_context.dataList);
+    }
+    CATerminateConnectionManagerMutexVariables();
+}
+
+CAResult_t CAInitConnectionManagerMutexVariables()
+{
+    if (!g_context.dataListMutex)
+    {
+        g_context.dataListMutex = oc_mutex_new();
+        if (!g_context.dataListMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (!g_context.dataSenderMutex)
+    {
+        g_context.dataSenderMutex = oc_mutex_new();
+        if (!g_context.dataSenderMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            CATerminateConnectionManagerMutexVariables();
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_threadCMConfigureMutex)
+    {
+        g_threadCMConfigureMutex = oc_mutex_new();
+        if (NULL == g_threadCMConfigureMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    return CA_STATUS_OK;
+}
+
+void CATerminateConnectionManagerMutexVariables()
+{
+    if (g_context.dataListMutex)
+    {
+        oc_mutex_free(g_context.dataListMutex);
+        g_context.dataListMutex = NULL;
+    }
+
+    if (g_context.dataSenderMutex)
+    {
+        oc_mutex_free(g_context.dataSenderMutex);
+        g_context.dataSenderMutex = NULL;
+    }
+
+    if (g_threadCMConfigureMutex)
+    {
+        oc_mutex_free(g_threadCMConfigureMutex);
+        g_threadCMConfigureMutex = NULL;
+    }
+}
diff --git a/resource/csdk/connectivity/util/src/camanager/camanagerutil.c b/resource/csdk/connectivity/util/src/camanager/camanagerutil.c
new file mode 100644 (file)
index 0000000..2e11586
--- /dev/null
@@ -0,0 +1,28 @@
+/* *****************************************************************
+ *
+ * Copyright 2016 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 "logger.h"
+#include "cathreadpool.h"
+#include "uarraylist.h"
+#include "octhread.h"
+#include "logger.h"
+#include "camanagerutil.h"
+
+#define TAG "OIC_CM_UTIL"
diff --git a/resource/csdk/connectivity/util/src/camanager/camanagerutil.h b/resource/csdk/connectivity/util/src/camanager/camanagerutil.h
new file mode 100644 (file)
index 0000000..bf0191a
--- /dev/null
@@ -0,0 +1,44 @@
+/* *****************************************************************
+ *
+ * Copyright 2016 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 function for connection manager util
+ */
+
+#ifndef CA_MANAGER_UTIL_H_
+#define CA_MANAGER_UTIL_H_
+
+#include "logger.h"
+#include "cathreadpool.h"
+#include "uarraylist.h"
+#include "octhread.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif  // CA_MANAGER_UTIL_H_
diff --git a/resource/csdk/connectivity/util/src/camanager/camessagearbiter.c b/resource/csdk/connectivity/util/src/camanager/camessagearbiter.c
new file mode 100644 (file)
index 0000000..061170b
--- /dev/null
@@ -0,0 +1,25 @@
+/* *****************************************************************
+ *
+ * Copyright 2016 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 "logger.h"
+#include "cathreadpool.h"
+#include "octhread.h"
+
+#define TAG "OIC_CM_ARBITER"
diff --git a/resource/csdk/connectivity/util/src/camanager/camessagearbiter.h b/resource/csdk/connectivity/util/src/camanager/camessagearbiter.h
new file mode 100644 (file)
index 0000000..238362d
--- /dev/null
@@ -0,0 +1,45 @@
+/* *****************************************************************
+ *
+ * Copyright 2016 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 function for connection manager arbiter
+ */
+
+#ifndef CA_CONNECTIONMANAGER_ARBITER_H_
+#define CA_CONNECTIONMANAGER_ARBITER_H_
+
+#include "logger.h"
+#include "cathreadpool.h"
+#include "octhread.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif  // CA_CONNECTIONMANAGER_ARBITER_H_
+
+
diff --git a/resource/csdk/connectivity/util/src/camanager/capolicymanager.c b/resource/csdk/connectivity/util/src/camanager/capolicymanager.c
new file mode 100644 (file)
index 0000000..143850c
--- /dev/null
@@ -0,0 +1,65 @@
+/* *****************************************************************
+ *
+ * Copyright 2016 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "cathreadpool.h"
+#include "octhread.h"
+#include "uarraylist.h"
+#include "cacommon.h"
+#include "logger.h"
+
+#include "caconnectionmanager.h"
+#include "capolicymanager.h"
+#include "oic_string.h"
+
+#define TAG "OIC_CM_POLICY"
+
+static CMConfigureInfo_t g_configure = {.addr = {0},
+                                        .adapter = CA_ADAPTER_IP,
+                                        .level = NORMAL_SPEED};
+
+void CMSetConfigure(CMConfigureInfo_t info)
+{
+    OIC_LOG(DEBUG, TAG, "CMSetConfigurePolicy");
+    OICStrcpy(g_configure.addr, sizeof(g_configure.addr), info.addr);
+    g_configure.adapter = info.adapter;
+    g_configure.level = info.level;
+}
+
+const char* CMGetTargetAddress()
+{
+    OIC_LOG(DEBUG, TAG, "CMGetTargetAddress");
+    return g_configure.addr;
+}
+
+CATransportAdapter_t CMGetAdapterType()
+{
+    OIC_LOG(DEBUG, TAG, "CMGetAdapterType");
+    return g_configure.adapter;
+}
+
+CMSpeedLevel_t CMGetSpeedOfResponseLevel()
+{
+    OIC_LOG(DEBUG, TAG, "CMGetSpeedOfResponseLevel");
+    return g_configure.level;
+}
diff --git a/resource/csdk/connectivity/util/src/camanager/capolicymanager.h b/resource/csdk/connectivity/util/src/camanager/capolicymanager.h
new file mode 100644 (file)
index 0000000..9bef0cf
--- /dev/null
@@ -0,0 +1,71 @@
+/* *****************************************************************
+ *
+ * Copyright 2016 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 function for policy manager
+ */
+
+#ifndef CA_POLICY_MANAGER_H_
+#define CA_POLICY_MANAGER_H_
+
+#include <stdint.h>
+
+#include "cathreadpool.h"
+#include "octhread.h"
+#include "uarraylist.h"
+#include "cacommon.h"
+#include "caconnectionmanager.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * Set connection manager configure.
+ * Target address and connectivity priority and speed level can be set in this method.
+ * @param[in] info  configuration data for connection manager policy
+ */
+void CMSetConfigure(CMConfigureInfo_t info);
+
+/**
+ * get target address.
+ * @return address
+ */
+const char* CMGetTargetAddress();
+
+/**
+ * get Adapter Type of current priority.
+ * @return ::CATransportAdapter_t value.
+ */
+CATransportAdapter_t CMGetAdapterType();
+
+/**
+ * get speed of response level.
+ * @return ::CMSpeedLevel_t value.
+ */
+CMSpeedLevel_t CMGetSpeedOfResponseLevel();
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif  // CA_POLICY_MANAGER_H_
index 11a108c..1e84239 100644 (file)
 #include "cainterfacecontroller.h"
 #include "cacommon.h"
 #include "logger.h"
+#include "caremotehandler.h"
 
 #define TAG "OIC_CA_COMMON_UTILS"
 
-CAResult_t CARegisterNetworkMonitorHandler(CAAdapterStateChangedCB adapterStateCB,
-                                           CAConnectionStateChangedCB connStateCB)
+CAResult_t CARegisterNetworkMonitorHandler(CAAdapterStateChangedCB adapterStateCB, CAConnectionStateChangedCB connStateCB)
 {
-    OIC_LOG(DEBUG, TAG, "CARegisterNetworkMonitorHandler");
+       OIC_LOG(DEBUG, TAG, "CARegisterNetworkMonitorHandler");
 
-    CASetNetworkMonitorCallbacks(adapterStateCB, connStateCB);
-    return CA_STATUS_OK;
+       CASetNetworkMonitorCallbacks(adapterStateCB, connStateCB);
+       return CA_STATUS_OK;
 }
 
-CAResult_t CAUnregisterNetworkMonitorHandler(CAAdapterStateChangedCB adapterStateCB,
-                                             CAConnectionStateChangedCB connStateCB)
+CAResult_t CAUnregisterNetworkMonitorHandler(CAAdapterStateChangedCB adapterStateCB, CAConnectionStateChangedCB connStateCB)
 {
-    OIC_LOG(DEBUG, TAG, "CAUnregisterNetworkMonitorHandler");
+       OIC_LOG(DEBUG, TAG, "CAUnregisterNetworkMonitorHandler");
 
-    return CAUnsetNetworkMonitorCallbacks(adapterStateCB, connStateCB);
+       return CAUnsetNetworkMonitorCallbacks(adapterStateCB, connStateCB);
 }
 
 CAResult_t CASetAutoConnectionDeviceInfo(const char *address)
 {
-    OIC_LOG(DEBUG, TAG, "CASetAutoConnectionDeviceInfo");
+       OIC_LOG(DEBUG, TAG, "CASetAutoConnectionDeviceInfo");
 
-#if defined(__ANDROID__) && defined(LE_ADAPTER)
-    return CASetLEClientAutoConnectionDeviceInfo(address);
+#if (defined(__ANDROID__) || defined(__APPLE__)) && defined(LE_ADAPTER)
+       return CASetLEClientAutoConnectionDeviceInfo(address);
 #else
-    (void)address;
-    return CA_NOT_SUPPORTED;
+       (void)address;
+       return CA_NOT_SUPPORTED;
 #endif
 }
 
 CAResult_t CAUnsetAutoConnectionDeviceInfo(const char *address)
 {
-    OIC_LOG(DEBUG, TAG, "CAUnsetAutoConnectionDeviceInfo");
+       OIC_LOG(DEBUG, TAG, "CAUnsetAutoConnectionDeviceInfo");
 
-#if defined(__ANDROID__) && defined(LE_ADAPTER)
-    return CAUnsetLEClientAutoConnectionDeviceInfo(address);
+#if (defined(__ANDROID__) || defined(__APPLE__))  && defined(LE_ADAPTER)
+       return CAUnsetLEClientAutoConnectionDeviceInfo(address);
 #else
-    (void)address;
-    return CA_NOT_SUPPORTED;
+       (void)address;
+       return CA_NOT_SUPPORTED;
 #endif
 }
 
-CAResult_t CASetPortNumberToAssign(CATransportAdapter_t adapter,
-                                   CATransportFlags_t flag, uint16_t port)
+#ifdef __APPLE__
+
+CAResult_t CAUtilClientInitialize()
+{
+       OIC_LOG(DEBUG, TAG, "CAUtilClientInitialize");
+
+       CAResult_t res = CA_STATUS_OK;
+#ifdef LE_ADAPTER
+       if (CA_STATUS_OK != CAManagerLEClientInitialize()) {
+               OIC_LOG(ERROR, TAG, "CAManagerLEClientInitialize has failed");
+               res = CA_STATUS_FAILED;
+       }
+#else
+       OIC_LOG(DEBUG, TAG, "it is not supported");
+       res = CA_NOT_SUPPORTED;
+#endif
+
+       return res;
+}
+
+CAResult_t CAUtilClientTerminate()
+{
+       OIC_LOG(DEBUG, TAG, "CAUtilClientTerminate");
+#ifdef LE_ADAPTER
+       return CAManagerLEClientTerminate();
+#else
+       OIC_LOG(DEBUG, TAG, "it is not supported");
+       return CA_NOT_SUPPORTED;
+#endif
+}
+
+CAResult_t CAUtilStopLEScan()
+{
+       OIC_LOG(DEBUG, TAG, "CAUtilStopLEScan");
+#ifdef LE_ADAPTER
+       CAManagerLEStopScan();
+       return CA_STATUS_OK;
+#else
+       OIC_LOG(DEBUG, TAG, "it is not supported");
+       return CA_NOT_SUPPORTED;
+#endif
+}
+
+CAResult_t CAUtilStartLEScan()
 {
-    uint16_t *targetPort = 0;
-
-    if (CA_ADAPTER_IP & adapter)
-    {
-        if (CA_SECURE & flag)
-        {
-            if (CA_IPV6 & flag)
-            {
-                targetPort = &caglobals.ports.udp.u6s;
-            }
-            else if (CA_IPV4 & flag)
-            {
-                targetPort = &caglobals.ports.udp.u4s;
-            }
-        }
-        else
-        {
-            if (CA_IPV6 & flag)
-            {
-                targetPort = &caglobals.ports.udp.u6;
-            }
-            else if (CA_IPV4 & flag)
-            {
-                targetPort = &caglobals.ports.udp.u4;
-            }
-        }
-    }
+       OIC_LOG(DEBUG, TAG, "CAUtilStartLEScan");
+#ifdef LE_ADAPTER
+       CAManagerLEStartScan();
+       return CA_STATUS_OK;
+#else
+       OIC_LOG(DEBUG, TAG, "it is not supported");
+       return CA_NOT_SUPPORTED;
+#endif
+}
+
+CAResult_t CAUtilClientDisconnect()
+{
+       OIC_LOG(DEBUG, TAG, "CAUtilClientDisconnect");
+#ifdef LE_ADAPTER
+       CAManagerLEDisconnect();
+       return CA_STATUS_OK;
+#else
+       OIC_LOG(DEBUG, TAG, "it is not supported");
+       return CA_NOT_SUPPORTED;
+#endif
+}
+
+#endif
+
+CAResult_t CASetPortNumberToAssign(CATransportAdapter_t adapter, CATransportFlags_t flag, uint16_t port)
+{
+       uint16_t *targetPort = 0;
+
+       if (CA_ADAPTER_IP & adapter) {
+               if (CA_SECURE & flag) {
+                       if (CA_IPV6 & flag) {
+                               targetPort = &caglobals.ports.udp.u6s;
+                       } else if (CA_IPV4 & flag) {
+                               targetPort = &caglobals.ports.udp.u4s;
+                       }
+               } else {
+                       if (CA_IPV6 & flag) {
+                               targetPort = &caglobals.ports.udp.u6;
+                       } else if (CA_IPV4 & flag) {
+                               targetPort = &caglobals.ports.udp.u4;
+                       }
+               }
+       }
 #ifdef TCP_ADAPTER
-    if (CA_ADAPTER_TCP & adapter)
-    {
-        if (CA_IPV6 & flag)
-        {
-            targetPort = &caglobals.ports.tcp.u6;
-        }
-        else if (CA_IPV4 & flag)
-        {
-            targetPort = &caglobals.ports.tcp.u4;
-        }
-    }
+       if (CA_ADAPTER_TCP & adapter) {
+               if (CA_IPV6 & flag) {
+                       targetPort = &caglobals.ports.tcp.u6;
+               } else if (CA_IPV4 & flag) {
+                       targetPort = &caglobals.ports.tcp.u4;
+               }
+       }
 #endif
 
-    if (targetPort)
-    {
-        *targetPort = port;
-        return CA_STATUS_OK;
-    }
+       if (targetPort) {
+               *targetPort = port;
+               return CA_STATUS_OK;
+       }
 
-    return CA_NOT_SUPPORTED;
+       return CA_NOT_SUPPORTED;
 }
 
 uint16_t CAGetAssignedPortNumber(CATransportAdapter_t adapter, CATransportFlags_t flag)
 {
-    OIC_LOG(DEBUG, TAG, "CAGetAssignedPortNumber");
-
-    if (CA_ADAPTER_IP & adapter)
-    {
-        if (CA_SECURE & flag)
-        {
-            if (CA_IPV6 & flag)
-            {
-                return caglobals.ip.u6s.port;
-            }
-            else if (CA_IPV4 & flag)
-            {
-                return caglobals.ip.u4s.port;
-            }
-        }
-        else
-        {
-            if (CA_IPV6 & flag)
-            {
-                return caglobals.ip.u6.port;
-            }
-            else if (CA_IPV4 & flag)
-            {
-                return caglobals.ip.u4.port;
-            }
-        }
-    }
+       OIC_LOG(DEBUG, TAG, "CAGetAssignedPortNumber");
+
+       if (CA_ADAPTER_IP & adapter) {
+               if (CA_SECURE & flag) {
+                       if (CA_IPV6 & flag) {
+                               return caglobals.ip.u6s.port;
+                       } else if (CA_IPV4 & flag) {
+                               return caglobals.ip.u4s.port;
+                       }
+               } else {
+                       if (CA_IPV6 & flag) {
+                               return caglobals.ip.u6.port;
+                       } else if (CA_IPV4 & flag) {
+                               return caglobals.ip.u4.port;
+                       }
+               }
+       }
 #ifdef TCP_ADAPTER
-    if (CA_ADAPTER_TCP & adapter)
-    {
-        if (CA_IPV6 & flag)
-        {
-            return caglobals.tcp.ipv6.port;
-        }
-        else if (CA_IPV4 & flag)
-        {
-            return caglobals.tcp.ipv4.port;
-        }
-    }
+       if (CA_ADAPTER_TCP & adapter) {
+               if (CA_SECURE & flag) {
+                       if (CA_IPV6 & flag) {
+                               return caglobals.tcp.ipv6s.port;
+                       } else if (CA_IPV4 & flag) {
+                               return caglobals.tcp.ipv4s.port;
+                       }
+               } else {
+                       if (CA_IPV6 & flag) {
+                               return caglobals.tcp.ipv6.port;
+                       } else if (CA_IPV4 & flag) {
+                               return caglobals.tcp.ipv4.port;
+                       }
+               }
+       }
 #endif
-    return 0;
+       return 0;
 }
 
+#if defined(__TIZEN__) && defined(LE_ADAPTER) && defined(BLE_CUSTOM_ADVERTISE)
+CAResult_t CASetAdvertisementData(const char* data, int length)
+{
+       return CAManagerLEServerSetAdvertisementData(data, length);
+}
+CAResult_t CASetScanResponseData(const char* data, int length)
+{
+       return CAManagerLEServerSetScanResponseData(data, length);
+}
+#endif
+
 #ifdef __ANDROID__
 /**
  * initialize client connection manager
@@ -175,31 +232,29 @@ uint16_t CAGetAssignedPortNumber(CATransportAdapter_t adapter, CATransportFlags_
  */
 CAResult_t CAUtilClientInitialize(JNIEnv *env, JavaVM *jvm, jobject context)
 {
-    OIC_LOG(DEBUG, TAG, "CAUtilClientInitialize");
+       OIC_LOG(DEBUG, TAG, "CAUtilClientInitialize");
 
-    CAResult_t res = CA_STATUS_OK;
+       CAResult_t res = CA_STATUS_OK;
 #ifdef LE_ADAPTER
-    if (CA_STATUS_OK != CAManagerLEClientInitialize(env, jvm, context))
-    {
-        OIC_LOG(ERROR, TAG, "CAManagerLEClientInitialize has failed");
-        res = CA_STATUS_FAILED;
-    }
+       if (CA_STATUS_OK != CAManagerLEClientInitialize(env, jvm, context)) {
+               OIC_LOG(ERROR, TAG, "CAManagerLEClientInitialize has failed");
+               res = CA_STATUS_FAILED;
+       }
 #endif
 
 #ifdef EDR_ADAPTER
-    if (CA_STATUS_OK != CABTPairingInitialize(env, jvm, context))
-    {
-        OIC_LOG(ERROR, TAG, "CABTPairingInitialize has failed");
-        res = CA_STATUS_FAILED;
-    }
+       if (CA_STATUS_OK != CABTPairingInitialize(env, jvm, context)) {
+               OIC_LOG(ERROR, TAG, "CABTPairingInitialize has failed");
+               res = CA_STATUS_FAILED;
+       }
 #endif
 
 #if !defined(LE_ADAPTER) && !defined(EDR_ADAPTER)
-    (void)env;
-    (void)jvm;
-    (void)context;
+       (void)env;
+       (void)jvm;
+       (void)context;
 #endif
-    return res;
+       return res;
 }
 
 /**
@@ -208,13 +263,13 @@ CAResult_t CAUtilClientInitialize(JNIEnv *env, JavaVM *jvm, jobject context)
  */
 CAResult_t CAUtilClientTerminate(JNIEnv *env)
 {
-    OIC_LOG(DEBUG, TAG, "CAUtilClientTerminate");
+       OIC_LOG(DEBUG, TAG, "CAUtilClientTerminate");
 #ifdef LE_ADAPTER
-    return CAManagerLEClientTerminate(env);
+       return CAManagerLEClientTerminate(env);
 #else
-    OIC_LOG(DEBUG, TAG, "it is not supported");
-    (void)env;
-    return CA_NOT_SUPPORTED;
+       OIC_LOG(DEBUG, TAG, "it is not supported");
+       (void)env;
+       return CA_NOT_SUPPORTED;
 #endif
 }
 
@@ -222,57 +277,207 @@ CAResult_t CAUtilClientTerminate(JNIEnv *env)
 CAResult_t CAUtilStartScan(JNIEnv *env)
 {
 #ifdef EDR_ADAPTER
-    return CABTPairingStartScan(env);
+       return CABTPairingStartScan(env);
 #else
-    OIC_LOG(DEBUG, TAG, "it is not supported");
-    (void)env;
-    return CA_NOT_SUPPORTED;
+       OIC_LOG(DEBUG, TAG, "it is not supported");
+       (void)env;
+       return CA_NOT_SUPPORTED;
 #endif
 }
 
 CAResult_t CAUtilStopScan(JNIEnv *env)
 {
 #ifdef EDR_ADAPTER
-    return CABTPairingStopScan(env);
+       return CABTPairingStopScan(env);
 #else
-    OIC_LOG(DEBUG, TAG, "it is not supported");
-    (void)env;
-    return CA_NOT_SUPPORTED;
+       OIC_LOG(DEBUG, TAG, "it is not supported");
+       (void)env;
+       return CA_NOT_SUPPORTED;
 #endif
 }
 
 CAResult_t CAUtilCreateBond(JNIEnv *env, jobject device)
 {
 #ifdef EDR_ADAPTER
-    return CABTPairingCreateBond(env, device);
+       return CABTPairingCreateBond(env, device);
 #else
-    OIC_LOG(DEBUG, TAG, "it is not supported");
-    (void)env;
-    (void)device;
-    return CA_NOT_SUPPORTED;
+       OIC_LOG(DEBUG, TAG, "it is not supported");
+       (void)env;
+       (void)device;
+       return CA_NOT_SUPPORTED;
 #endif
 }
 
 void CAUtilSetFoundDeviceListener(jobject listener)
 {
 #ifdef EDR_ADAPTER
-    CABTPairingSetFoundDeviceListener(listener);
+       CABTPairingSetFoundDeviceListener(listener);
 #else
-    (void)listener;
+       (void)listener;
 #endif
 }
 
 CAResult_t CAUtilSetLEScanInterval(jint intervalTime, jint workingCount)
 {
-    OIC_LOG(DEBUG, TAG, "CAUtilSetLEScanInterval");
+       OIC_LOG(DEBUG, TAG, "CAUtilSetLEScanInterval");
+#ifdef LE_ADAPTER
+       CAManagerLESetScanInterval(intervalTime, workingCount);
+       return CA_STATUS_OK;
+#else
+       (void)intervalTime;
+       (void)workingCount;
+       OIC_LOG(DEBUG, TAG, "it is not supported");
+       return CA_NOT_SUPPORTED;
+#endif
+}
+
+CAResult_t CAUtilStopLEScan()
+{
+       OIC_LOG(DEBUG, TAG, "CAUtilStopLEScan");
 #ifdef LE_ADAPTER
-    CAManagerLESetScanInterval(intervalTime, workingCount);
-    return CA_STATUS_OK;
+       CAManagerLEStopScan();
+       return CA_STATUS_OK;
+#else
+       OIC_LOG(DEBUG, TAG, "it is not supported");
+       return CA_NOT_SUPPORTED;
+#endif
+}
+#endif // __ANDROID__
+
+CAResult_t CAUtilStartLEAdvertising()
+{
+       OIC_LOG(DEBUG, TAG, "CAUtilStartLEAdvertising");
+#if (defined(__ANDROID__) || defined(__TIZEN__)) && defined(LE_ADAPTER)
+       return CAManagerLEStartAdvertising();
+#else
+       OIC_LOG(DEBUG, TAG, "it is not supported");
+       return CA_NOT_SUPPORTED;
+#endif
+}
+
+CAResult_t CAUtilStopLEAdvertising()
+{
+       OIC_LOG(DEBUG, TAG, "CAUtilStopLEAdvertising");
+#if (defined(__ANDROID__) || defined(__TIZEN__)) && defined(LE_ADAPTER)
+       return CAManagerLEStopAdvertising();
 #else
-    (void)intervalTime;
-    (void)workingCount;
-    OIC_LOG(DEBUG, TAG, "it is not supported");
-    return CA_NOT_SUPPORTED;
+       OIC_LOG(DEBUG, TAG, "it is not supported");
+       return CA_NOT_SUPPORTED;
 #endif
 }
+
+CAResult_t CAUtilSetBTConfigure(CAUtilConfig_t config)
+{
+       OIC_LOG_V(DEBUG, TAG, "CAUtilSetConfigure");
+#if (defined(__ANDROID__) && defined(LE_ADAPTER))
+       OIC_LOG_V(DEBUG, TAG, " - bleFlag [%d]", config.bleFlags);
+       CAManagerSetConfigure(config);
+       return CA_STATUS_OK;
+#else
+       (void) config;
+       OIC_LOG(DEBUG, TAG, "it is not supported");
+       return CA_NOT_SUPPORTED;
+#endif
+}
+
+void CAUtilSetLogLevel(CAUtilLogLevel_t level, bool hidePrivateLogEntries)
+{
+       OIC_LOG(DEBUG, TAG, "CAUtilSetLogLevel");
+       LogLevel logLevel = DEBUG;
+       switch (level) {
+       case CA_LOG_LEVEL_ALL:
+               logLevel = DEBUG;
+               break;
+       case CA_LOG_LEVEL_INFO:
+               logLevel = INFO;
+               break;
+       default:
+               logLevel = DEBUG;
+               break;
+       }
+
+       OCSetLogLevel(logLevel, hidePrivateLogEntries);
+}
+
+CAResult_t CAUtilSetMulticastTTL(size_t ttl)
+{
+       OIC_LOG(DEBUG, TAG, "CAUtilSetMulticastTTL");
+#ifdef IP_ADAPTER
+       if (ttl > 255) {
+               OIC_LOG(ERROR, TAG, "TTL value is invalid");
+               return CA_STATUS_INVALID_PARAM;
+       }
+       if (ttl > 32) {
+               OIC_LOG(INFO, TAG, "TTL value is not supported");
+               return CA_NOT_SUPPORTED;
+       }
+       return CASetMulticastTTL(ttl);
+#else
+       (void) ttl;
+       OIC_LOG(DEBUG, TAG, "it is not supported");
+       return CA_NOT_SUPPORTED;
 #endif
+}
+
+CAResult_t CAUtilGetMulticastTTL(size_t *ttl)
+{
+       OIC_LOG(DEBUG, TAG, "CAUtilGetMulticastTTL");
+#ifdef IP_ADAPTER
+       return CAGetMulticastTTL(ttl);
+#else
+       (void) ttl;
+       OIC_LOG(DEBUG, TAG, "it is not supported");
+       return CA_NOT_SUPPORTED;
+#endif
+}
+
+CAResult_t CAUtilTCPDisconnectSession(const char *address, uint16_t port, CATransportFlags_t flags)
+{
+       OIC_LOG(DEBUG, TAG, "CAUtilTCPDisconnectSession");
+#ifdef TCP_ADAPTER
+       CARequestInfo_t reqInfo = {.info.event = CA_REQ_DISCONNECT};
+       CAEndpoint_t *endpoint = CACreateEndpointObject(flags, CA_ADAPTER_TCP, address, port);
+       if (!endpoint) {
+               return CA_STATUS_FAILED;
+       }
+
+       CAResult_t caResult = CASendRequest(endpoint, &reqInfo);
+       if (CA_STATUS_OK != caResult) {
+               OIC_LOG(ERROR, TAG, "CASendRequest error");
+       }
+       CAFreeEndpoint(endpoint);
+       return caResult;
+#else
+       (void) address;
+       (void) port;
+       (void) flags;
+       OIC_LOG(DEBUG, TAG, "it is not supported");
+       return CA_NOT_SUPPORTED;
+#endif
+}
+
+CAResult_t CAUtilStartGattServer()
+{
+       OIC_LOG(DEBUG, TAG, "CAUtilStartGattServer");
+       CAResult_t res = CA_STATUS_OK;
+#if (defined(__TIZEN__) && defined(LE_ADAPTER))
+       CAStartGattServer();
+#else
+       OIC_LOG(DEBUG, TAG, "it is not supported");
+       res = CA_NOT_SUPPORTED;
+#endif
+       return res;
+}
+
+CAResult_t CAUtilStopGattServer()
+{
+       OIC_LOG(DEBUG, TAG, "CAUtilStopGattServer");
+       CAResult_t res = CA_STATUS_OK;
+#if (defined(__TIZEN__) && defined(LE_ADAPTER))
+       CAStopGattServer();
+#else
+       OIC_LOG(DEBUG, TAG, "it is not supported");
+       res = CA_NOT_SUPPORTED;
+#endif
+       return res;
+}
index b81fb7e..e3ae6b8 100644 (file)
@@ -1,5 +1,6 @@
 Import('env')
 import os
+log_level = env.get('LOG_LEVEL')
 
 env.AppendUnique(CPPPATH = [os.path.join(Dir('.').abspath, 'include'),
                             '../../c_common'
@@ -12,6 +13,9 @@ if env.get('TARGET_OS') == 'tizen':
 else:
        env.AppendUnique(LIBPATH = [os.path.join(env.get('BUILD_DIR'), 'resource', 'csdk', 'logger')])
 
+if env.get('OIC_SUPPORT_TIZEN_TRACE') == 'True':
+    env.AppendUnique(CPPDEFINES = ['OIC_SUPPORT_TIZEN_TRACE'])
+
 env.PrependUnique(LIBS = ['logger'])
 
 local_env = env.Clone()
@@ -28,7 +32,23 @@ if env.get('TARGET_OS') in ['arduino']:
        Command("./src/logger.cpp", "./src/logger.c", Copy("$TARGET", "$SOURCE"))
        logger_src = ['./src/logger.cpp']
 else:
-       logger_src = ['./src/logger.c']
+       logger_src = ['./src/logger.c', './src/trace.c']
+
+if log_level == 'DEBUG':
+       env.AppendUnique(CPPDEFINES = ['SET_LOG_DEBUG'])
+       print "SET_LOG_DEBUG"
+if log_level == 'INFO':
+       env.AppendUnique(CPPDEFINES = ['SET_LOG_INFO'])
+       print "SET_LOG_INFO"
+if log_level == 'ERROR':
+       env.AppendUnique(CPPDEFINES = ['SET_LOG_ERROR'])
+       print "SET_LOG_ERROR"
+if log_level == 'WARNING':
+       env.AppendUnique(CPPDEFINES = ['SET_LOG_WARNING'])
+       print "SET_LOG_WARNING"
+if log_level == 'FATAL':
+       env.AppendUnique(CPPDEFINES = ['SET_LOG_FATAL'])
+       print "SET_LOG_FATAL"
 
 loggerlib = local_env.StaticLibrary('logger', logger_src)
 local_env.InstallTarget(loggerlib, 'logger')
index 2bd6087..af95bc8 100644 (file)
 #ifndef LOGGER_H_
 #define LOGGER_H_
 
-#define IOTIVITY_VERSION "1.2.1"
-
 #include <stdint.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <stdbool.h>
 #include "logger_types.h"
 
 #ifdef __ANDROID__
@@ -45,7 +44,10 @@ extern "C"
 /**
 * Helper for unused warning.
 */
+#ifndef UNUSED
 #define UNUSED(x) (void)(x)
+#endif
+
 
 // Use the PCF macro to wrap strings stored in FLASH on the Arduino
 // Example:  OIC_LOG(INFO, TAG, PCF("Entering function"));
@@ -57,7 +59,7 @@ extern "C"
 #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)
@@ -65,11 +67,14 @@ extern "C"
 // Log levels
 #ifdef __TIZEN__
 typedef enum {
-    DEBUG = DLOG_DEBUG,
+    DEBUG = DLOG_INFO,    // DLOG_INFO : 4
     INFO = DLOG_INFO,
-    WARNING = DLOG_WARN,
-    ERROR = DLOG_ERROR,
-    FATAL = DLOG_ERROR
+    WARNING = DLOG_WARN,  // DLOG_WARN : 5
+    ERROR = DLOG_ERROR,   // DLOG_ERROR : 6
+    FATAL = DLOG_ERROR,
+    DEBUG_LITE = DLOG_INFO,
+    INFO_LITE = DLOG_INFO,
+    INFO_PRIVATE = 255,
 } LogLevel;
 #else
 
@@ -83,10 +88,47 @@ typedef enum {
     INFO,
     WARNING,
     ERROR,
-    FATAL
+    FATAL,
+    DEBUG_LITE,       // The DEBUG log for Lite device
+    INFO_LITE,        // The INFO log for Lite device
+    INFO_PRIVATE,     // The log contained private data
 } LogLevel;
+
+#endif // __TIZEN__
+
+#ifdef SET_LOG_DEBUG
+#define IF_OC_PRINT_LOG_LEVEL(level) if (DEBUG <= (level))
+#elif defined(SET_LOG_INFO)
+#define IF_OC_PRINT_LOG_LEVEL(level) if (INFO <= (level))
+#elif defined(SET_LOG_ERROR)
+#define IF_OC_PRINT_LOG_LEVEL(level) if (ERROR <= (level) && INFO_PRIVATE != (level))
+#elif defined(SET_LOG_WARNING)
+#define IF_OC_PRINT_LOG_LEVEL(level) if (WARNING <= (level) && INFO_PRIVATE != (level))
+#elif defined(SET_LOG_FATAL)
+#define IF_OC_PRINT_LOG_LEVEL(level) if (FATAL <= (level) && INFO_PRIVATE != (level))
+#else
+#define IF_OC_PRINT_LOG_LEVEL(level) if (DEBUG <= (level))
 #endif
 
+#define IF_OC_PRINT_PRIVATE_LOG_LEVEL(level) \
+    if (false == OCGetPrivateLogLevel() || (true == OCGetPrivateLogLevel() && INFO_PRIVATE != (level))) \
+
+#define MAX_LOG_BUFFER_SIZE (4096)
+
+/**
+ * Set log level and privacy log to print.
+ *
+ * @param level                   - log level.
+ * @param hidePrivateLogEntries   - Hide Private Log.
+ */
+void OCSetLogLevel(LogLevel level, bool hidePrivateLogEntries);
+
+/**
+ * get private log flag.
+ * @return  private log flag
+ */
+bool OCGetPrivateLogLevel();
+
 #ifdef __TIZEN__
 /**
  * Output the contents of the specified buffer (in hex) with the specified priority level.
@@ -97,6 +139,8 @@ typedef enum {
  * @param[in]    bufferSize max number of byte in buffer
  */
 void OCLogBuffer(LogLevel level, const char * tag, const uint8_t * buffer, uint16_t bufferSize);
+void OCPrintCALogBuffer(LogLevel level, const char *tag, const uint8_t *buffer,
+                        uint16_t bufferSize, uint8_t isHeader);
 
 #define OCLog(level,tag,mes) LOG_(LOG_ID_MAIN, (level), (tag), mes)
 #define OCLogv(level,tag,fmt,args...) LOG_(LOG_ID_MAIN, (level),tag,fmt,##args)
@@ -153,6 +197,10 @@ void OCLogBuffer(LogLevel level, const char * tag, const uint8_t * buffer, uint1
      * @param bufferSize - max number of byte in buffer
      */
     void OCLogBuffer(LogLevel level, const char * tag, const uint8_t * buffer, uint16_t bufferSize);
+
+    void OCPrintCALogBuffer(LogLevel level, const char *tag, const uint8_t *buffer,
+                            uint16_t bufferSize, uint8_t isHeader);
+
 #else  // For arduino platforms
     /**
      * Initialize the serial logger for Arduino
@@ -201,48 +249,108 @@ void OCLogBuffer(LogLevel level, const char * tag, const uint8_t * buffer, uint1
 #ifdef TB_LOG
 
 #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)\
-    OCLogBuffer((level), (tag), (buffer), (bufferSize))
-
-#else // These macros are defined for Linux, Android, Win32, and Arduino
-
+#define OIC_LOG(level,tag,mes) \
+    do { \
+        IF_OC_PRINT_LOG_LEVEL((level)) \
+            IF_OC_PRINT_PRIVATE_LOG_LEVEL((level)) \
+            { \
+                if ((level) == INFO_PRIVATE) \
+                    LOG_(LOG_ID_MAIN, DLOG_INFO, (tag), mes); \
+                else \
+                    LOG_(LOG_ID_MAIN, (level), (tag), mes); \
+            } \
+    } while(0)
+
+#define OIC_LOG_V(level,tag,fmt,args...) \
+    do { \
+        IF_OC_PRINT_LOG_LEVEL((level)) \
+            IF_OC_PRINT_PRIVATE_LOG_LEVEL((level)) \
+            { \
+                if ((level) == INFO_PRIVATE) \
+                    LOG_(LOG_ID_MAIN, DLOG_INFO, (tag), fmt, ##args); \
+                else \
+                    LOG_(LOG_ID_MAIN, (level), (tag), fmt, ##args); \
+            } \
+    } while(0)
+
+#define OIC_LOG_BUFFER(level, tag, buffer, bufferSize) \
+    do { \
+        IF_OC_PRINT_LOG_LEVEL((level)) \
+            OCLogBuffer((level), (tag), (buffer), (bufferSize)); \
+    } while(0)
+
+#define OIC_LOG_CA_BUFFER(level, tag, buffer, bufferSize, isHeader) \
+    do { \
+        IF_OC_PRINT_LOG_LEVEL((level)) \
+            OCPrintCALogBuffer((level), (tag), (buffer), (bufferSize), (isHeader)); \
+    } while(0)
+
+#else // NO __TIZEN__ - These macros are defined for Linux, Android, Win32, and Arduino
 #define OIC_LOG_INIT()    OCLogInit()
 
 #ifdef ARDUINO
+#define OIC_LOG_BUFFER(level, tag, buffer, bufferSize) \
+    do { \
+        IF_OC_PRINT_LOG_LEVEL((level)) \
+            OCLogBuffer((level), PCF(tag), (buffer), (bufferSize)); \
+    } while(0)
 
-#define OIC_LOG_BUFFER(level, tag, buffer, bufferSize)  OCLogBuffer((level), PCF(tag), (buffer), (bufferSize))
 // Don't define variable argument log function for Arduino
-#define OIC_LOG_V(level, tag, format, ...) OCLogv((level), PCF(tag), __LINE__, PCF(format),__VA_ARGS__)
+#define OIC_LOG_V(level, tag, format, ...) \
+    do { \
+        IF_OC_PRINT_LOG_LEVEL((level)) \
+            OCLogv((level), PCF(tag), __LINE__, PCF(format),__VA_ARGS__); \
+    } while(0)
 
 #define OIC_LOG_CONFIG(ctx)
 #define OIC_LOG_SHUTDOWN()
-#define OIC_LOG(level, tag, logStr) OCLog((level), PCF(tag), __LINE__, PCF(logStr))
+#define OIC_LOG(level, tag, logStr) \
+    do { \
+        IF_OC_PRINT_LOG_LEVEL((level)) \
+            OCLog((level), PCF(tag), __LINE__, PCF(logStr)); \
+    } while(0)
+
 #define OIC_LOG_V(level, tag, ...)
 
-#else
+#else // NO ARDUINO
+#define OIC_LOG_BUFFER(level, tag, buffer, bufferSize) \
+    do { \
+        IF_OC_PRINT_LOG_LEVEL((level)) \
+            OCLogBuffer((level), (tag), (buffer), (bufferSize)); \
+    } while(0)
+
+#define OIC_LOG_CA_BUFFER(level, tag, buffer, bufferSize, isHeader) \
+    do { \
+        IF_OC_PRINT_LOG_LEVEL((level)) \
+            OCPrintCALogBuffer((level), (tag), (buffer), (bufferSize), (isHeader)); \
+    } while(0)
 
-#define OIC_LOG_BUFFER(level, tag, buffer, bufferSize)  OCLogBuffer((level), (tag), (buffer), (bufferSize))
 #define OIC_LOG_CONFIG(ctx)    OCLogConfig((ctx))
 #define OIC_LOG_SHUTDOWN()     OCLogShutdown()
-#define OIC_LOG(level, tag, logStr)  OCLog((level), (tag), (logStr))
-// Define variable argument log function for Linux, Android, and Win32
-#define OIC_LOG_V(level, tag, ...)  OCLogv((level), (tag), __VA_ARGS__)
-
-#endif //ARDUINO
-#endif //__TIZEN__
-
-#else //TB_LOG
+#define OIC_LOG(level, tag, logStr) \
+    do { \
+        IF_OC_PRINT_LOG_LEVEL((level)) \
+            OCLog((level), (tag), (logStr)); \
+    } while(0)
 
+// Define variable argument log function for Linux, Android, and Win32
+#define OIC_LOG_V(level, tag, ...) \
+    do { \
+        IF_OC_PRINT_LOG_LEVEL((level)) \
+            OCLogv((level), (tag), __VA_ARGS__); \
+    } while(0)
+
+#endif // ARDUINO
+#endif // __TIZEN__
+#else // NO TB_LOG
 #define OIC_LOG_CONFIG(ctx)
 #define OIC_LOG_SHUTDOWN()
 #define OIC_LOG(level, tag, logStr)
 #define OIC_LOG_V(level, tag, ...)
 #define OIC_LOG_BUFFER(level, tag, buffer, bufferSize)
+#define OIC_LOG_CA_BUFFER(level, tag, buffer, bufferSize, isHeader)
 #define OIC_LOG_INIT()
-#endif
+#endif // TB_LOG
 
 #ifdef __cplusplus
 }
diff --git a/resource/csdk/logger/include/tizenrt_logger.h b/resource/csdk/logger/include/tizenrt_logger.h
new file mode 100644 (file)
index 0000000..a84e832
--- /dev/null
@@ -0,0 +1,35 @@
+#include "logger.h"
+
+#undef OIC_LOG_INIT()
+#undef OIC_LOG_CONFIG(ctx)
+#undef OIC_LOG_SHUTDOWN()
+#undef OIC_LOG(level, tag, logStr)
+#undef OIC_LOG_V(level, tag, ...)
+#undef OIC_LOG_BUFFER(level, tag, buffer, bufferSize)
+#undef OIC_LOG_CA_BUFFER(level, tag, buffer, bufferSize, isHeader)
+
+#define OIC_LOG_INIT()    OCLogInit()
+#define OIC_LOG_CONFIG(ctx)    OCLogConfig((ctx))
+#define OIC_LOG_SHUTDOWN()     OCLogShutdown()
+#define OIC_LOG(level, tag, logStr) \
+    do { \
+        IF_OC_PRINT_LOG_LEVEL((level)) \
+            OCLog((level), (tag), (logStr)); \
+    } while(0)
+// Define variable argument log function for Linux, Android, and Win32
+#define OIC_LOG_V(level, tag, ...) \
+    do { \
+        IF_OC_PRINT_LOG_LEVEL((level)) \
+            OCLogv((level), (tag), __VA_ARGS__); \
+    } while(0)
+#define OIC_LOG_BUFFER(level, tag, buffer, bufferSize) \
+    do { \
+        IF_OC_PRINT_LOG_LEVEL((level)) \
+            OCLogBuffer((level), (tag), (buffer), (bufferSize)); \
+    } while(0)
+#define OIC_LOG_CA_BUFFER(level, tag, buffer, bufferSize, isHeader) \
+    do { \
+        IF_OC_PRINT_LOG_LEVEL((level)) \
+            OCPrintCALogBuffer((level), (tag), (buffer), (bufferSize), (isHeader)); \
+    } while(0)
+
diff --git a/resource/csdk/logger/include/trace.h b/resource/csdk/logger/include/trace.h
new file mode 100755 (executable)
index 0000000..08a8457
--- /dev/null
@@ -0,0 +1,93 @@
+//******************************************************************
+//
+// Copyright 2017 Samsung 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef TRACE_H_
+#define TRACE_H_
+
+#ifdef __ANDROID__
+#include "logger.h"
+#elif defined(__TIZEN__)
+#ifdef OIC_SUPPORT_TIZEN_TRACE
+#include <ttrace.h>
+#endif
+#elif defined(ARDUINO)
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#ifdef __ANDROID__
+
+void oic_trace_begin(const char *name, ...);
+void oic_trace_end();
+void oic_trace_buffer(const char *name, const uint8_t * buffer, size_t bufferSize);
+
+#define OIC_TRACE_BEGIN(MSG, ...)
+#define OIC_TRACE_END()
+#define OIC_TRACE_MARK(MSG, ...)
+#define OIC_TRACE_BUFFER(MSG, BUF, SIZ)
+
+#elif defined(__TIZEN__)
+/* trace macro for Tizen. this will call ttrace api internally*/
+#ifdef OIC_SUPPORT_TIZEN_TRACE
+
+#include <ttrace.h>
+
+void oic_trace_buffer(const char *name, const uint8_t * buffer, size_t bufferSize);
+
+/* ttrace api is available on tizen2.4 (or above) only */
+#define OIC_TRACE_BEGIN(MSG, ...) \
+        traceBegin(TTRACE_TAG_APP, "OIC:"#MSG, ##__VA_ARGS__)
+#define OIC_TRACE_END() \
+        traceEnd(TTRACE_TAG_APP)
+#define OIC_TRACE_MARK(MSG, ...) \
+        traceBegin(TTRACE_TAG_APP, "OIC:"#MSG, ##__VA_ARGS__), \
+        traceEnd(TTRACE_TAG_APP)
+#define OIC_TRACE_BUFFER(MSG, BUF, SIZ) \
+        oic_trace_buffer(MSG, BUF, SIZ)
+#else
+#define OIC_TRACE_BEGIN(MSG, ...)
+#define OIC_TRACE_END()
+#define OIC_TRACE_MARK(MSG, ...)
+#define OIC_TRACE_BUFFER(MSG, BUF, SIZ)
+#endif
+
+#elif defined(ARDUINO)
+/* trace macro for Arduino. currently this will call nothing*/
+#define OIC_TRACE_BEGIN(MSG, ...)
+#define OIC_TRACE_END()
+#define OIC_TRACE_MARK(MSG, ...)
+#define OIC_TRACE_BUFFER(MSG, BUF, SIZ)
+
+#else
+#define OIC_TRACE_BEGIN(MSG, ...)
+#define OIC_TRACE_END()
+#define OIC_TRACE_MARK(MSG, ...)
+#define OIC_TRACE_BUFFER(MSG, BUF, SIZ)
+
+#endif //endif
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif /* TRACE_H_ */
index edeb167..6758d09 100644 (file)
 #include "string.h"
 #include "logger_types.h"
 
+// log level
+LogLevel g_level = DEBUG;
+// privacy log
+bool g_hidePrivateLogEntries = false;
+
 #ifndef __TIZEN__
 static oc_log_ctx_t *logCtx = 0;
 #endif
 
 #if defined(_MSC_VER)
 #define LINE_BUFFER_SIZE (16 * 2) + 16 + 1  // Show 16 bytes, 2 chars/byte, spaces between bytes, null termination
+#define S_LINE_BUFFER_SIZE (50 * 2) + 50 + 1  // Show 50 bytes, 2 chars/byte, spaces between bytes, null termination
 #else
 static const uint16_t LINE_BUFFER_SIZE = (16 * 2) + 16 + 1;  // Show 16 bytes, 2 chars/byte, spaces between bytes, null termination
+static const uint16_t S_LINE_BUFFER_SIZE = (50 * 2) + 50 + 1;  // Show 50 bytes, 2 chars/byte, spaces between bytes, null termination
 #endif //defined(_MSC_VER)
 
 #ifdef __ANDROID__
-#elif defined __linux__ || defined __APPLE__ || defined _WIN32
+#elif defined __linux__ || defined __APPLE__ || defined _WIN32 || defined(__TIZENRT__)
 static oc_log_level LEVEL_XTABLE[] = {OC_LOG_DEBUG, OC_LOG_INFO,
                                       OC_LOG_WARNING, OC_LOG_ERROR, OC_LOG_FATAL};
 #endif
@@ -81,7 +88,7 @@ static oc_log_level LEVEL_XTABLE[] = {OC_LOG_DEBUG, OC_LOG_INFO,
     static android_LogPriority LEVEL[] =
     {ANDROID_LOG_DEBUG, ANDROID_LOG_INFO, ANDROID_LOG_WARN, ANDROID_LOG_ERROR, ANDROID_LOG_FATAL};
 #endif
-#elif defined(__linux__) || defined(__APPLE__) || defined(__msys_nt__)
+#elif defined(__linux__) || defined(__APPLE__) || defined(__msys_nt__)|| defined(__TIZENRT__)
     static const char * LEVEL[] __attribute__ ((unused)) = {"DEBUG", "INFO", "WARNING", "ERROR", "FATAL"};
 #elif defined(_MSC_VER)
     static const char * LEVEL[] = {"DEBUG", "INFO", "WARNING", "ERROR", "FATAL"};
@@ -155,6 +162,65 @@ void OCLogBuffer(LogLevel level, const char * tag, const uint8_t * buffer, uint1
         OCLogv(level, tag, "%s", lineBuffer);
     }
 }
+
+void OCPrintCALogBuffer(LogLevel level, const char *tag, const uint8_t *buffer,
+                        uint16_t bufferSize, uint8_t isHeader)
+{
+    if (!buffer || !tag || (bufferSize == 0))
+    {
+        return;
+    }
+
+    // No idea why the static initialization won't work here, it seems the compiler is convinced
+    // that this is a variable-sized object.
+    char lineBuffer[S_LINE_BUFFER_SIZE];
+    int lineIndex = 0;
+    int i;
+    for (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 50 values per line
+        if (((i+1)%50) == 0)
+        {
+            if (1 == isHeader)
+            {
+                OCLogv(level, tag, "| Analyzer(Header) | %s", lineBuffer);
+            }
+            else
+            {
+                OCLogv(level, tag, "| Analyzer(Body) | %s", lineBuffer);
+            }
+            memset(lineBuffer, 0, sizeof lineBuffer);
+            lineIndex = 0;
+        }
+    }
+
+    if (bufferSize % 50)
+    {
+        if (1 == isHeader)
+        {
+            OCLogv(level, tag, "| Analyzer(Header) | %s", lineBuffer);
+        }
+        else
+        {
+            OCLogv(level, tag, "| Analyzer(Body) | %s", lineBuffer);
+        }
+    }
+}
+
+void OCSetLogLevel(LogLevel level, bool hidePrivateLogEntries)
+{
+    g_level = level;
+    g_hidePrivateLogEntries = hidePrivateLogEntries;
+}
+
+bool OCGetPrivateLogLevel()
+{
+    return g_hidePrivateLogEntries;
+}
+
 #ifndef __TIZEN__
 void OCLogConfig(oc_log_ctx_t *ctx)
 {
@@ -168,7 +234,7 @@ void OCLogInit()
 
 void OCLogShutdown()
 {
-#if defined(__linux__) || defined(__APPLE__) || defined(_WIN32)
+#if defined(__linux__) || defined(__APPLE__) || defined(_WIN32)|| defined(__TIZENRT__)
     if (logCtx && logCtx->destroy)
     {
         logCtx->destroy(logCtx);
@@ -189,6 +255,17 @@ void OCLogv(LogLevel level, const char * tag, const char * format, ...)
     if (!format || !tag) {
         return;
     }
+
+    if (g_level > level && ERROR != level && WARNING != level && FATAL != level)
+    {
+        return;
+    }
+
+    if (true == g_hidePrivateLogEntries && INFO_PRIVATE == level)
+    {
+        return;
+    }
+
     char buffer[MAX_LOG_V_BUFFER_SIZE] = {0};
     va_list args;
     va_start(args, format);
@@ -212,6 +289,31 @@ void OCLog(LogLevel level, const char * tag, const char * logStr)
        return;
     }
 
+    if (g_level > level && ERROR != level && WARNING != level && FATAL != level)
+    {
+        return;
+    }
+
+    if (true == g_hidePrivateLogEntries && INFO_PRIVATE == level)
+    {
+        return;
+    }
+
+    switch(level)
+    {
+        case DEBUG_LITE:
+            level = DEBUG;
+            break;
+        case INFO_LITE:
+            level = INFO;
+            break;
+        case INFO_PRIVATE:
+            level = INFO;
+            break;
+        default:
+            break;
+    }
+
    #ifdef __ANDROID__
 
    #ifdef ADB_SHELL
diff --git a/resource/csdk/logger/src/trace.c b/resource/csdk/logger/src/trace.c
new file mode 100755 (executable)
index 0000000..50fd4bc
--- /dev/null
@@ -0,0 +1,222 @@
+//******************************************************************
+//
+// Copyright 2017 Samsung 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#include <stdio.h>
+#include "iotivity_config.h"
+#include "trace.h"
+
+#if (defined(__ANDROID__)) || (defined(__TIZEN__) && defined(OIC_SUPPORT_TIZEN_TRACE))
+
+#define MAX_BUFFER_SIZE 8
+#define MAX_LINE_LEN ((MAX_BUFFER_SIZE) * 2) + 1
+
+void oic_trace_buffer(const char *name, const uint8_t * buffer, size_t bufferSize)
+{
+    if (!name || !buffer || (0 == bufferSize))
+    {
+        return;
+    }
+
+    char lineBuffer[MAX_LINE_LEN] = {0};
+    size_t count = (MAX_BUFFER_SIZE > bufferSize) ? bufferSize : MAX_BUFFER_SIZE;
+    size_t remainSize = MAX_LINE_LEN;
+    int writtenSize = 0;
+    char* buf = &lineBuffer[0];
+
+    for (size_t i = 0; i < count; i++)
+    {
+        writtenSize = snprintf(buf, remainSize, "%02x", buffer[i]);
+        if (2 != writtenSize)
+        {
+            break;
+        }
+        buf += writtenSize;
+        remainSize -= 2;
+    }
+
+    OIC_TRACE_BEGIN(%s:%s, name, lineBuffer);
+    OIC_TRACE_END();
+}
+
+#endif
+
+#ifndef __TIZEN__
+
+#include "logger.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#elif defined(HAVE_STRINGS_H)
+#include <strings.h>
+#endif
+
+#define FD_INITIAL_VALUE  -1
+#define FD_NOT_EXIST    -2
+#define MAX_BUF_SIZE    4096
+#define MAX_TRACE_LEN   524
+#define MAX_HEAD_LEN    8
+#define MAX_TAIL_LEN    13
+#define POS_LABEL_ST    ((MAX_TRACE_LEN - MAX_HEAD_LEN))
+#define POS_LABEL_ED    ((MAX_TRACE_LEN - MAX_TAIL_LEN))
+
+#define TAG "OIC_TRACER"
+
+#ifdef __ANDROID__
+/*
+* Currently android api level 21 is used for building iotivity project.
+* Since Atrace (aka. android trace) API has been provided by NDK above android api level 23,
+* we use ftrace directly as workaround to Atrace API until android build level is upgraded
+*/
+int g_trace_marker_hd = FD_INITIAL_VALUE;
+
+int oic_trace_init()
+{
+    OIC_LOG(INFO, TAG, "entering oic_trace_init");
+    int mounts = -1;
+    char buf[MAX_BUF_SIZE] = {0};
+    ssize_t buflen = -1;
+    char *line = NULL, *tmp1 = NULL, *path = NULL;
+
+    if(g_trace_marker_hd == FD_INITIAL_VALUE)
+    {
+        mounts = open("/proc/mounts", O_RDONLY);
+        if (mounts < 0)
+        {
+            OIC_LOG(INFO, TAG, "no /proc/mounts");
+            return -1;
+        }
+
+        buflen = read(mounts, buf, sizeof(buf) - 1);
+        close(mounts);
+
+        if (buflen < 0)
+        {
+            OIC_LOG(INFO, TAG, "failed to read /proc/mounts");
+            return -1;
+        }
+
+        line = strtok_r(buf, "\n", &tmp1);
+        while (line)
+        {
+            char *tmp2 = NULL, *tmp_path = NULL, *fstype = NULL;
+            /* "<dev> <mountpoint> <fs type> ..." */
+            strtok_r(line, " ", &tmp2);
+            tmp_path = strtok_r(NULL, " ", &tmp2);
+            fstype = strtok_r(NULL, " ", &tmp2);
+
+            if ((fstype != NULL) && (strcmp(fstype, "debugfs") == 0))
+            {
+                path = tmp_path;
+                break;
+            }
+            line = strtok_r(NULL, "\n", &tmp1);
+        }
+
+        if (NULL == path)
+        {
+            OIC_LOG(INFO, TAG,  "debugfs mountpoint not found");
+            return -1;
+        }
+
+        snprintf(buf, sizeof(buf) - 1, "%s/tracing/trace_marker", path);
+        g_trace_marker_hd = open(buf, O_WRONLY);
+        if (g_trace_marker_hd < 0)
+        {
+            OIC_LOG_V(INFO, TAG, "failed to open trace_marker file: %s (%d)",
+                      strerror(errno), errno);
+            return -1;
+        }
+    }
+    OIC_LOG_V(INFO, TAG,  "exit oic_trace_init with: %d", g_trace_marker_hd);
+    return g_trace_marker_hd;
+}
+
+void oic_trace_begin(const char *name, ...)
+{
+    if (g_trace_marker_hd == FD_INITIAL_VALUE)
+    {
+        oic_trace_init();
+    }
+
+    if (g_trace_marker_hd > 0)
+    {
+        char buf[MAX_TRACE_LEN] = {0};
+        int len = MAX_HEAD_LEN, ret = 0;
+        va_list ap;
+
+        va_start(ap, name);
+        snprintf(buf, MAX_TRACE_LEN, "B|%5d|", getpid());
+        len += vsnprintf(buf + MAX_HEAD_LEN, POS_LABEL_ST, name, ap);
+        va_end(ap);
+
+        if (len > MAX_TRACE_LEN)
+        {
+            len = MAX_TRACE_LEN - 1;
+        }
+
+        ret = write(g_trace_marker_hd, buf, len);
+
+        if (ret < 0)
+        {
+            OIC_LOG_V(INFO, TAG, "error writing, len: %d, ret: %d, errno: %d at oic_trace_begin",
+                      len, ret, errno);
+        }
+    }
+    else
+    {
+        OIC_LOG_V(INFO, TAG, "oic_trace_begin: invalid fd: %d", g_trace_marker_hd);
+    }
+}
+
+void oic_trace_end()
+{
+    if (FD_INITIAL_VALUE == g_trace_marker_hd)
+    {
+        oic_trace_init();
+    }
+
+    if (g_trace_marker_hd > 0)
+    {
+        int ret = 0, len = 1;
+        char end = 'E';
+
+        ret = write(g_trace_marker_hd, &end, len);
+        if (ret < 0)
+        {
+            OIC_LOG_V(INFO, TAG, "error writing, len: %d, ret: %d, errno: %d at oic_trace_end",
+                      len, ret, errno);
+        }
+    }
+    else
+    {
+        OIC_LOG_V(INFO, TAG, "oic_trace_end: invalid fd: %d", g_trace_marker_hd);
+    }
+}
+
+#elif defined ARDUINO
+/* TODO: Trace api for ARDUINO and others will be implemented */
+#endif //ARDUINO
+
+#endif // #ifndef __TIZEN__
index 78616d7..9447407 100644 (file)
@@ -44,9 +44,11 @@ OCDiscoverDirectPairingDevices
 OCDoDirectPairing
 OCDoResource
 OCDoResponse
+OCDoRequest
 OCEncodeAddressForRFC6874
 OCFreeOCStringLL
 OCGetDeviceId
+OCGetDeviceOwnedState
 OCGetDirectPairedDevices
 OCGetHeaderOption
 OCGetNumberOfResources
index a9525d2..1475b55 100644 (file)
@@ -3,6 +3,8 @@
 
 CreateJustWorksOwnerTransferPayload
 CreateJustWorksSelectOxmPayload
+CreateMVJustWorksSelectOxmPayload
+CreateConMCertificateBasedSelectOxmPayload
 CreatePinBasedSelectOxmPayload
 CreatePinBasedOwnerTransferPayload
 CreateSecureSessionJustWorksCallback
@@ -10,6 +12,7 @@ CreateSecureSessionRandomPinCallback
 InputPinCodeCallback
 LoadSecretJustWorksCallback
 
+OCConfigSelfOwnership
 OCDeleteACLList
 OCDeleteDiscoveredDevices
 OCDeletePdAclList
@@ -22,6 +25,7 @@ OCGetCredResource
 OCGetDevInfoFromNetwork
 OCGetLinkedStatus
 OCInitPM
+OCPDMCleanupForTimeout
 OCProvisionACL
 OCSaveACL
 OCProvisionCredentials
@@ -30,13 +34,24 @@ OCProvisionPairwiseDevices
 OCRemoveDevice
 OCRemoveDeviceWithUuid
 OCResetDevice
+OCResetSVRDB
 OCSetOwnerTransferCallbackData
 OCUnlinkDevices
 OCSetOxmAllowStatus
 
+SetDeviceIdSeed
 SetGeneratePinCB
 SetInputPinCB
 SetRandomPinPolicy
+SetDisplayNumCB
+UnsetDisplayNumCB
+SetUserConfirmCB
+UnsetUserConfirmCB
+SetVerifyOption
+VerifyOwnershipTransfer
+
+SetHwPkixCallbacks
+SetupHwPkContext
 
 registerTimer
-unregisterTimer
\ No newline at end of file
+unregisterTimer
index 4c30d4f..24a0aa0 100755 (executable)
@@ -83,15 +83,15 @@ if 'SERVER' in rd_mode:
             RD_SRC_DIR + 'internal/rd_database.c',
             RD_SRC_DIR + 'rd_server.c',
             ]
-    if target_os not in ['linux', 'tizen'] :
+    if target_os not in ['linux', 'tizen', 'tizenrt'] :
         rd_src += [ '../../../extlibs/sqlite3/sqlite3.c' ]
 
 if 'CLIENT' in rd_mode:
     rd_src += [RD_SRC_DIR + 'rd_client.c',]
-    if target_os not in ['arduino','darwin','ios', 'windows', 'winrt']:
+    if target_os not in ['arduino','darwin','ios', 'windows', 'winrt','tizenrt']:
         rd_src += [ RD_SRC_DIR + 'RDClient.cpp',]
 
-if target_os not in ['arduino', 'darwin', 'ios', 'windows', 'winrt']:
+if target_os not in ['arduino', 'darwin', 'ios', 'windows', 'winrt', 'tizenrt']:
     rdsdk_shared = rd_env.SharedLibrary('resource_directory', rd_src)
     rdsdk_static = rd_env.StaticLibrary('resource_directory', rd_src)
     rdsdk = Flatten([rdsdk_static, rdsdk_shared])
index 2b4a582..7f97ff4 100644 (file)
@@ -36,54 +36,77 @@ extern "C" {
 
 #define DEFAULT_MESSAGE_TYPE "application/json"
 
+/** Platform Model Number.*/
+#define OC_DATA_MODEL_NUMBER            "x.model"
+
 /**
  * Discover Local RD across the network.
  *
- * @param connectivityType Type of connectivity indicating the interface.
- * @param cbBiasFactor Asynchronous callback function that is invoked by the stack when
- *                     response is received. The callback is generated for each response
- *                     received.
- * @param qos Quality of service.
+ * @param handle            To refer to the request sent out on behalf of
+ *                          calling this API. This handle can be used to cancel this operation
+ *                          via the OCCancel API.
+ *                          @note: This reference is handled internally, and should not be free'd by
+ *                          the consumer.  A NULL handle is permitted in the event where the caller
+ *                          has no use for the return value.
+ * @param connectivityType  Type of connectivity indicating the interface.
+ * @param cbBiasFactor      Asynchronous callback function that is invoked by the stack when
+ *                          response is received. The callback is generated for each response
+ *                          received.
+ * @param qos               Quality of service.
  *
  * @return ::OC_STACK_OK on success, some other value upon failure.
  */
-OCStackResult OCRDDiscover(OCConnectivityType connectivityType, OCCallbackData *cbBiasFactor,
-                           OCQualityOfService qos);
+OCStackResult OCRDDiscover(OCDoHandle *handle, OCConnectivityType connectivityType,
+                           OCCallbackData *cbBiasFactor, OCQualityOfService qos);
 
 /**
  * Publish RD resource to Resource Directory.
  *
- * @param host The address of the RD.
- * @param connectivityType Type of connectivity indicating the interface.
- * @param resourceHandles This is the resource handle which we need to register to RD.
- * @param nHandles The counts of resource handle.
- * @param cbData Asynchronous callback function that is invoked by the stack when
- *               response is received. The callback is generated for each response
- *               received.
- * @param qos Quality of service.
+ * @param handle            To refer to the request sent out on behalf of
+ *                          calling this API. This handle can be used to cancel this operation
+ *                          via the OCCancel API.
+ *                          @note: This reference is handled internally, and should not be free'd by
+ *                          the consumer.  A NULL handle is permitted in the event where the caller
+ *                          has no use for the return value.
+ * @param host              The address of the RD.
+ * @param connectivityType  Type of connectivity indicating the interface.
+ * @param resourceHandles   This is the resource handle which we need to register to RD.
+ * @param nHandles          The counts of resource handle.
+ * @param cbData            Asynchronous callback function that is invoked by the stack when
+ *                          response is received. The callback is generated for each response
+ *                          received.
+ * @param qos               Quality of service.
  *
  * @return ::OC_STACK_OK on success, some other value upon failure.
  */
-OCStackResult OCRDPublish(const char *host, OCConnectivityType connectivityType,
+OCStackResult OCRDPublish(OCDoHandle *handle, const char *host,
+                          OCConnectivityType connectivityType,
                           OCResourceHandle *resourceHandles, uint8_t nHandles,
                           OCCallbackData *cbData, OCQualityOfService qos);
 
 /**
  * Publish RD resource to Resource Directory with a specific id.
  *
- * @param host The address of the RD.
- * @param id An unique identifier of publishing device.
- * @param connectivityType Type of connectivity indicating the interface.
- * @param resourceHandles This is the resource handle which we need to register to RD.
- * @param nHandles The counts of resource handle.
- * @param cbData Asynchronous callback function that is invoked by the stack when
- *               response is received. The callback is generated for each response
- *               received.
- * @param qos Quality of service.
+ * @param handle            To refer to the request sent out on behalf of
+ *                          calling this API. This handle can be used to cancel this operation
+ *                          via the OCCancel API.
+ *                          @note: This reference is handled internally, and should not be free'd by
+ *                          the consumer.  A NULL handle is permitted in the event where the caller
+ *                          has no use for the return value.
+ * @param host              The address of the RD.
+ * @param id                An unique identifier of publishing device.
+ * @param connectivityType  Type of connectivity indicating the interface.
+ * @param resourceHandles   This is the resource handle which we need to register to RD.
+ * @param nHandles          The counts of resource handle.
+ * @param cbData            Asynchronous callback function that is invoked by the stack when
+ *                          response is received. The callback is generated for each response
+ *                          received.
+ * @param qos               Quality of service.
  *
  * @return ::OC_STACK_OK on success, some other value upon failure.
  */
-OCStackResult OCRDPublishWithDeviceId(const char *host, const unsigned char *id,
+OCStackResult OCRDPublishWithDeviceId(OCDoHandle *handle, const char *host,
+                                      const unsigned char *id,
                                       OCConnectivityType connectivityType,
                                       OCResourceHandle *resourceHandles, uint8_t nHandles,
                                       OCCallbackData *cbData, OCQualityOfService qos);
@@ -91,37 +114,51 @@ OCStackResult OCRDPublishWithDeviceId(const char *host, const unsigned char *id,
 /**
  * Delete RD resource from Resource Directory.
  *
- * @param host The address of the RD.
- * @param connectivityType Type of connectivity indicating the interface.
- * @param resourceHandles This is the resource handle which we need to delete to RD.
- * @param nHandles The counts of resource handle.
- * @param cbData Asynchronous callback function that is invoked by the stack when
- *               response is received. The callback is generated for each response
- *               received.
- * @param qos Quality of service.
+ * @param handle            To refer to the request sent out on behalf of
+ *                          calling this API. This handle can be used to cancel this operation
+ *                          via the OCCancel API.
+ *                          @note: This reference is handled internally, and should not be free'd by
+ *                          the consumer.  A NULL handle is permitted in the event where the caller
+ *                          has no use for the return value.
+ * @param host              The address of the RD.
+ * @param connectivityType  Type of connectivity indicating the interface.
+ * @param resourceHandles   This is the resource handle which we need to delete to RD.
+ * @param nHandles          The counts of resource handle.
+ * @param cbData            Asynchronous callback function that is invoked by the stack when
+ *                          response is received. The callback is generated for each response
+ *                          received.
+ * @param qos               Quality of service.
  *
  * @return ::OC_STACK_OK on success, some other value upon failure.
  */
-OCStackResult OCRDDelete(const char *host, OCConnectivityType connectivityType,
+OCStackResult OCRDDelete(OCDoHandle *handle, const char *host,
+                         OCConnectivityType connectivityType,
                          OCResourceHandle *resourceHandles, uint8_t nHandles,
                          OCCallbackData *cbData, OCQualityOfService qos);
 
 /**
  * Delete RD resource from Resource Directory.
  *
- * @param host The address of the RD.
- * @param id An unique identifier of publishing device.
- * @param connectivityType Type of connectivity indicating the interface.
- * @param resourceHandles This is the resource handle which we need to delete to RD.
- * @param nHandles The counts of resource handle.
- * @param cbData Asynchronous callback function that is invoked by the stack when
- *               response is received. The callback is generated for each response
- *               received.
- * @param qos Quality of service.
+ * @param handle            To refer to the request sent out on behalf of
+ *                          calling this API. This handle can be used to cancel this operation
+ *                          via the OCCancel API.
+ *                          @note: This reference is handled internally, and should not be free'd by
+ *                          the consumer.  A NULL handle is permitted in the event where the caller
+ *                          has no use for the return value.
+ * @param host              The address of the RD.
+ * @param id                An unique identifier of publishing device.
+ * @param connectivityType  Type of connectivity indicating the interface.
+ * @param resourceHandles   This is the resource handle which we need to delete to RD.
+ * @param nHandles          The counts of resource handle.
+ * @param cbData            Asynchronous callback function that is invoked by the stack when
+ *                          response is received. The callback is generated for each response
+ *                          received.
+ * @param qos               Quality of service.
  *
  * @return ::OC_STACK_OK on success, some other value upon failure.
  */
-OCStackResult OCRDDeleteWithDeviceId(const char *host, const unsigned char *id,
+OCStackResult OCRDDeleteWithDeviceId(OCDoHandle *handle, const char *host,
+                                     const unsigned char *id,
                                      OCConnectivityType connectivityType,
                                      OCResourceHandle *resourceHandles, uint8_t nHandles,
                                      OCCallbackData *cbData, OCQualityOfService qos);
index df9d418..851bcd5 100644 (file)
@@ -143,7 +143,7 @@ int main()
                 cbData.cb = &handleDiscoveryCB;;
                 cbData.cd = NULL;
                 cbData.context = (void*) DEFAULT_CONTEXT_VALUE;
-                OCRDDiscover(CT_ADAPTER_IP, &cbData, OC_LOW_QOS);
+                OCRDDiscover(nullptr, CT_ADAPTER_IP, &cbData, OC_LOW_QOS);
                 break;
             }
             case 2:
@@ -153,7 +153,7 @@ int main()
                 cbData.cd = NULL;
                 cbData.context = (void*) DEFAULT_CONTEXT_VALUE;
                 std::string address = rdAddress.str();
-                OCRDPublish(address.c_str(), CT_ADAPTER_IP, handles,
+                OCRDPublish(nullptr, address.c_str(), CT_ADAPTER_IP, handles,
                             2, &cbData, OC_LOW_QOS);
                 break;
             }
index 115c451..36140bd 100644 (file)
@@ -144,7 +144,7 @@ OCStackResult RDClient::publishResourceToRD(const std::string& host,
     if (cLock)
     {
         std::lock_guard<std::recursive_mutex> lock(*cLock);
-        result = OCRDPublish(host.c_str(), connectivityType, &resourceHandles[0],
+        result = OCRDPublish(nullptr, host.c_str(), connectivityType, &resourceHandles[0],
                              resourceHandles.size(), &cbdata, static_cast<OCQualityOfService>(qos));
     }
 
@@ -204,7 +204,7 @@ OCStackResult RDClient::deleteResourceFromRD(const std::string& host,
     if (cLock)
     {
         std::lock_guard<std::recursive_mutex> lock(*cLock);
-        result = OCRDDelete(host.c_str(), connectivityType, &resourceHandles[0],
+        result = OCRDDelete(nullptr, host.c_str(), connectivityType, &resourceHandles[0],
                             resourceHandles.size(), &cbdata, static_cast<OCQualityOfService>(qos));
     }
 
index 2206a7d..fd65aeb 100644 (file)
@@ -33,8 +33,8 @@
 
 #ifdef RD_CLIENT
 
-OCStackResult OCRDDiscover(OCConnectivityType connectivityType, OCCallbackData *cbBiasFactor,
-                           OCQualityOfService qos)
+OCStackResult OCRDDiscover(OCDoHandle *handle, OCConnectivityType connectivityType,
+                           OCCallbackData *cbBiasFactor, OCQualityOfService qos)
 {
     if (!cbBiasFactor || !cbBiasFactor->cb)
     {
@@ -47,11 +47,12 @@ OCStackResult OCRDDiscover(OCConnectivityType connectivityType, OCCallbackData *
     snprintf(queryUri, MAX_URI_LENGTH, "coap://%s%s", OC_MULTICAST_PREFIX, OC_RSRVD_RD_URI);
     OIC_LOG_V(DEBUG, TAG, "Querying RD: %s\n", queryUri);
 
-    return OCDoResource(NULL, OC_REST_DISCOVER, queryUri, NULL, NULL, connectivityType, qos,
+    return OCDoResource(handle, OC_REST_DISCOVER, queryUri, NULL, NULL, connectivityType, qos,
                         cbBiasFactor, NULL, 0);
 }
 
-OCStackResult OCRDPublish(const char *host, OCConnectivityType connectivityType,
+OCStackResult OCRDPublish(OCDoHandle *handle, const char *host,
+                          OCConnectivityType connectivityType,
                           OCResourceHandle *resourceHandles, uint8_t nHandles,
                           OCCallbackData *cbData, OCQualityOfService qos)
 {
@@ -69,11 +70,12 @@ OCStackResult OCRDPublish(const char *host, OCConnectivityType connectivityType,
     // Get Device ID from stack.
     const unsigned char *id = (const unsigned char *) OCGetServerInstanceIDString();
 
-    return OCRDPublishWithDeviceId(host, id, connectivityType, resourceHandles, nHandles,
-                                   cbData, qos);
+    return OCRDPublishWithDeviceId(handle, host, id, connectivityType, resourceHandles,
+                                   nHandles, cbData, qos);
 }
 
-OCStackResult OCRDPublishWithDeviceId(const char *host, const unsigned char *id,
+OCStackResult OCRDPublishWithDeviceId(OCDoHandle *handle, const char *host,
+                                      const unsigned char *id,
                                       OCConnectivityType connectivityType,
                                       OCResourceHandle *resourceHandles, uint8_t nHandles,
                                       OCCallbackData *cbData, OCQualityOfService qos)
@@ -121,7 +123,24 @@ OCStackResult OCRDPublishWithDeviceId(const char *host, const unsigned char *id,
         return OC_STACK_NO_MEMORY;
     }
 
-    OCRepPayloadSetPropString(rdPayload, OC_RSRVD_DEVICE_ID, id);
+    OCRepPayloadSetPropString(rdPayload, OC_RSRVD_DEVICE_ID, (const char *) id);
+
+    char *deviceName = NULL;
+    OCGetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DEVICE_NAME, (void **) &deviceName);
+    if (deviceName)
+    {
+        OCRepPayloadSetPropString(rdPayload, OC_RSRVD_DEVICE_NAME, deviceName);
+        OICFree(deviceName);
+    }
+
+    char *platformModelName = NULL;
+    OCGetPropertyValue(PAYLOAD_TYPE_PLATFORM, OC_RSRVD_MODEL_NUM, (void **) &platformModelName);
+    if (platformModelName)
+    {
+        OCRepPayloadSetPropString(rdPayload, OC_DATA_MODEL_NUMBER, platformModelName);
+        OICFree(platformModelName);
+    }
+
     OCRepPayloadSetPropInt(rdPayload, OC_RSRVD_DEVICE_TTL, OIC_RD_PUBLISH_TTL);
 
     OCRepPayload **linkArr = OICCalloc(nPubResHandles, sizeof(OCRepPayload *));
@@ -173,7 +192,7 @@ OCStackResult OCRDPublishWithDeviceId(const char *host, const unsigned char *id,
                 OCRepPayloadSetStringArrayAsOwner(link, OC_RSRVD_INTERFACE, itf, ifDim);
             }
 
-            uint8_t ins = 0;
+            int64_t ins = 0;
             if (OC_STACK_OK == OCGetResourceIns(handle, &ins))
             {
                 OCRepPayloadSetPropInt(link, OC_RSRVD_INS, ins);
@@ -216,11 +235,12 @@ OCStackResult OCRDPublishWithDeviceId(const char *host, const unsigned char *id,
     }
     OICFree(linkArr);
 
-    return OCDoResource(NULL, OC_REST_POST, targetUri, NULL, (OCPayload *)rdPayload,
+    return OCDoResource(handle, OC_REST_POST, targetUri, NULL, (OCPayload *)rdPayload,
                         connectivityType, qos, cbData, NULL, 0);
 }
 
-OCStackResult OCRDDelete(const char *host, OCConnectivityType connectivityType,
+OCStackResult OCRDDelete(OCDoHandle *handle, const char *host,
+                         OCConnectivityType connectivityType,
                          OCResourceHandle *resourceHandles, uint8_t nHandles,
                          OCCallbackData *cbData, OCQualityOfService qos)
 {
@@ -237,11 +257,12 @@ OCStackResult OCRDDelete(const char *host, OCConnectivityType connectivityType,
 
     const unsigned char *id = (const unsigned char *) OCGetServerInstanceIDString();
 
-    return OCRDDeleteWithDeviceId(host, id, connectivityType, resourceHandles, nHandles,
-                                  cbData, qos);
+    return OCRDDeleteWithDeviceId(handle, host, id, connectivityType, resourceHandles,
+                                  nHandles, cbData, qos);
 }
 
-OCStackResult OCRDDeleteWithDeviceId(const char *host, const unsigned char *id,
+OCStackResult OCRDDeleteWithDeviceId(OCDoHandle *handle, const char *host,
+                                     const unsigned char *id,
                                      OCConnectivityType connectivityType,
                                      OCResourceHandle *resourceHandles, uint8_t nHandles,
                                      OCCallbackData *cbData, OCQualityOfService qos)
@@ -262,16 +283,16 @@ OCStackResult OCRDDeleteWithDeviceId(const char *host, const unsigned char *id,
     for (uint8_t j = 0; j < nHandles; j++)
     {
         OCResource *handle = (OCResource *) resourceHandles[j];
-        uint8_t ins = 0;
+        int64_t ins = 0;
         OCGetResourceIns(handle, &ins);
-        len += snprintf(queryParam + len, MAX_URI_LENGTH, "&ins=%d", ins);
+        len += snprintf(queryParam + len, MAX_URI_LENGTH, "&ins=%" PRId64, ins);
         OIC_LOG_V(DEBUG, TAG, "queryParam [%s]", queryParam);
     }
 
     OICStrcatPartial(targetUri, sizeof(targetUri), queryParam, strlen(queryParam));
     OIC_LOG_V(DEBUG, TAG, "Target URI: %s", targetUri);
 
-    return OCDoResource(NULL, OC_REST_DELETE, targetUri, NULL, NULL, connectivityType,
+    return OCDoResource(handle, OC_REST_DELETE, targetUri, NULL, NULL, connectivityType,
                         qos, cbData, NULL, 0);
 }
 
index fb7a11c..799ac6e 100644 (file)
@@ -177,7 +177,9 @@ static OCEntityHandlerResult rdEntityHandler(OCEntityHandlerFlag flag,
             case OC_REST_PUT:
             case OC_REST_OBSERVE:
             case OC_REST_OBSERVE_ALL:
+#ifdef WITH_PRESENCE
             case OC_REST_PRESENCE:
+#endif
             case OC_REST_NOMETHOD:
                 break;
         }
index 50909ad..f8f49ef 100644 (file)
@@ -134,7 +134,7 @@ TEST_F(RDTests, CreateRDResource)
     cbData.cb = &handleDiscoveryCB;;
     cbData.cd = NULL;
     cbData.context = (void*) DEFAULT_CONTEXT_VALUE;
-    EXPECT_EQ(OC_STACK_OK, OCRDDiscover(CT_ADAPTER_IP, &cbData, OC_LOW_QOS));
+    EXPECT_EQ(OC_STACK_OK, OCRDDiscover(NULL, CT_ADAPTER_IP, &cbData, OC_LOW_QOS));
 
     EXPECT_EQ(OC_STACK_OK, OCRDStop());
 }
@@ -195,13 +195,13 @@ TEST_F(RDTests, CreateRDResource)
 TEST_F(RDTests, RDPublishResourceNullAddr)
 {
     itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
-    EXPECT_EQ(OC_STACK_INVALID_IP, OCRDPublish(0, CT_ADAPTER_IP, nullptr, 0, 0, OC_LOW_QOS));
+    EXPECT_EQ(OC_STACK_INVALID_IP, OCRDPublish(NULL, 0, CT_ADAPTER_IP, nullptr, 0, 0, OC_LOW_QOS));
 }
 
 TEST_F(RDTests, RDPublishResourceNullCB)
 {
     itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
-    EXPECT_EQ(OC_STACK_INVALID_CALLBACK, OCRDPublish("127.0.0.1", CT_ADAPTER_IP, nullptr,
+    EXPECT_EQ(OC_STACK_INVALID_CALLBACK, OCRDPublish(NULL, "127.0.0.1", CT_ADAPTER_IP, nullptr,
                                                      0, 0, OC_LOW_QOS));
 }
 
@@ -220,7 +220,7 @@ TEST_F(RDTests, RDPublishResource)
                                             "oic.if.baseline", "/a/light", rdEntityHandler,
                                             NULL, (OC_DISCOVERABLE | OC_OBSERVABLE)));
 
-    EXPECT_EQ(OC_STACK_OK, OCRDPublish("127.0.0.1", CT_ADAPTER_IP, &handle,
+    EXPECT_EQ(OC_STACK_OK, OCRDPublish(NULL, "127.0.0.1", CT_ADAPTER_IP, &handle,
                                        1, &cbData, OC_LOW_QOS));
 }
 
@@ -242,20 +242,20 @@ TEST_F(RDTests, RDPublishMultipleResources)
                                             "oic.if.baseline", "/a/light2", rdEntityHandler,
                                             NULL, (OC_DISCOVERABLE | OC_OBSERVABLE)));
 
-    EXPECT_EQ(OC_STACK_OK, OCRDPublish("127.0.0.1", CT_ADAPTER_IP, handles,
+    EXPECT_EQ(OC_STACK_OK, OCRDPublish(NULL, "127.0.0.1", CT_ADAPTER_IP, handles,
                                        2, &cbData, OC_LOW_QOS));
 }
 
 TEST_F(RDTests, RDDeleteResourceNullAddr)
 {
     itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
-    EXPECT_EQ(OC_STACK_INVALID_IP, OCRDDelete(0, CT_ADAPTER_IP, nullptr, 0, 0, OC_LOW_QOS));
+    EXPECT_EQ(OC_STACK_INVALID_IP, OCRDDelete(NULL, 0, CT_ADAPTER_IP, nullptr, 0, 0, OC_LOW_QOS));
 }
 
 TEST_F(RDTests, RDDeleteResourceNullCB)
 {
     itst::DeadmanTimer killSwitch(SHORT_TEST_TIMEOUT);
-    EXPECT_EQ(OC_STACK_INVALID_CALLBACK, OCRDDelete("127.0.0.1", CT_ADAPTER_IP, nullptr,
+    EXPECT_EQ(OC_STACK_INVALID_CALLBACK, OCRDDelete(NULL, "127.0.0.1", CT_ADAPTER_IP, nullptr,
                                                     0, 0, OC_LOW_QOS));
 }
 
@@ -268,7 +268,7 @@ TEST_F(RDTests, RDDeleteAllResource)
     cbData.cd = NULL;
     cbData.context = (void*) DEFAULT_CONTEXT_VALUE;
 
-    EXPECT_EQ(OC_STACK_OK, OCRDDelete("127.0.0.1", CT_ADAPTER_IP, nullptr, 0, &cbData,
+    EXPECT_EQ(OC_STACK_OK, OCRDDelete(NULL, "127.0.0.1", CT_ADAPTER_IP, nullptr, 0, &cbData,
                                       OC_LOW_QOS));
 }
 
@@ -287,7 +287,7 @@ TEST_F(RDTests, RDDeleteSpecificResource)
                                             "oic.if.baseline", "/a/light", rdEntityHandler,
                                             NULL, OC_DISCOVERABLE | OC_OBSERVABLE));
 
-    EXPECT_EQ(OC_STACK_OK, OCRDDelete("127.0.0.1", CT_ADAPTER_IP, &handle,
+    EXPECT_EQ(OC_STACK_OK, OCRDDelete(NULL, "127.0.0.1", CT_ADAPTER_IP, &handle,
                                       1, &cbData, OC_LOW_QOS));
 }
 #endif
index c382167..9f87d2f 100644 (file)
@@ -1244,7 +1244,7 @@ OCStackResult RMHandleRequest(CARequestInfo_t *message, const CAEndpoint_t *send
 {
     if (!g_isRMInitialized)
     {
-        OIC_LOG(ERROR, TAG, "RM not initialized");
+        OIC_LOG(INFO, TAG, "RM not initialized");
         *selfDestination = true;
         return OC_STACK_OK;
     }
@@ -1257,7 +1257,7 @@ OCStackResult RMHandleResponse(CAResponseInfo_t *message, const CAEndpoint_t *se
 {
     if (!g_isRMInitialized)
     {
-        OIC_LOG(ERROR, TAG, "RM not initialized");
+        OIC_LOG(INFO, TAG, "RM not initialized");
         *selfDestination = true;
         return OC_STACK_OK;
     }
index d9b8816..de7781a 100644 (file)
@@ -80,7 +80,6 @@ void RMSetStackMode(OCMode mode)
 OCStackResult RMAddInfo(const char *destination, void *message, bool isRequest,
                         bool *doPost)
 {
-    OIC_LOG(DEBUG, TAG, "IN");
     RM_NULL_CHECK_WITH_RET(message, TAG, "options");
 
     CAHeaderOption_t **options = NULL;
@@ -214,14 +213,12 @@ OCStackResult RMAddInfo(const char *destination, void *message, bool isRequest,
         *options = optionPtr;
     }
 
-    OIC_LOG(DEBUG, TAG, "OUT");
     return OC_STACK_OK;
 }
 
 OCStackResult RMUpdateInfo(CAHeaderOption_t **options, uint8_t *numOptions,
                            CAEndpoint_t *endpoint)
 {
-    OIC_LOG(DEBUG, TAG, "IN");
     RM_NULL_CHECK_WITH_RET(options, TAG, "options");
     RM_NULL_CHECK_WITH_RET(*options, TAG, "invalid option");
     RM_NULL_CHECK_WITH_RET(numOptions, TAG, "numOptions");
@@ -256,8 +253,10 @@ OCStackResult RMUpdateInfo(CAHeaderOption_t **options, uint8_t *numOptions,
         {
             memcpy(endpoint->routeData, (*options + routeIndex)->optionData + count,
                    GATEWAY_ID_LENGTH);
-            OIC_LOG_V(DEBUG, TAG, "adding srcgid: %u in endpoint [%d]",
-                     *((uint32_t *)endpoint->routeData), sLen);
+
+            uint32_t rData1 = 0;
+            memcpy(&rData1, endpoint->routeData, sizeof(rData1));
+            OIC_LOG_V(DEBUG, TAG, "adding srcgid: %u in endpoint [%d]", rData1, sLen);
 
             count += GATEWAY_ID_LENGTH;
 
@@ -265,8 +264,10 @@ OCStackResult RMUpdateInfo(CAHeaderOption_t **options, uint8_t *numOptions,
             {
                 memcpy(endpoint->routeData + GATEWAY_ID_LENGTH,
                        (*options + routeIndex)->optionData + count, ENDPOINT_ID_LENGTH);
-                OIC_LOG_V(DEBUG, TAG, "adding srceid: %u in endpoint",
-                         *((uint16_t *)(endpoint->routeData + GATEWAY_ID_LENGTH)));
+
+                uint16_t rData2 = 0;
+                memcpy(&rData2, endpoint->routeData + GATEWAY_ID_LENGTH, sizeof(rData2));
+                OIC_LOG_V(DEBUG, TAG, "adding srceid: %u in endpoint", rData2);
             }
         }
     }
@@ -284,15 +285,19 @@ OCStackResult RMUpdateInfo(CAHeaderOption_t **options, uint8_t *numOptions,
         OICFree(*options);
         *options = NULL;
     }
-    OIC_LOG(DEBUG, TAG, "OUT");
     return OC_STACK_OK;
 }
 
 void RMGetRouteOptionIndex(const CAHeaderOption_t *options, uint8_t numOptions, int8_t *index)
 {
-    OIC_LOG(DEBUG, TAG, "IN");
-    RM_NULL_CHECK_VOID(options, TAG, "options");
     RM_NULL_CHECK_VOID(index, TAG, "index");
+
+    if (NULL == options)
+    {
+        OIC_LOG(INFO, TAG, "No existing options");
+        return;
+    }
+
     for (uint32_t i = 0; i < numOptions; i++)
     {
         OIC_LOG_V(DEBUG, TAG, "Request- optionID: %u", options[i].optionID);
@@ -303,12 +308,10 @@ void RMGetRouteOptionIndex(const CAHeaderOption_t *options, uint8_t numOptions,
             break;
         }
     }
-    OIC_LOG(DEBUG, TAG, "OUT");
 }
 
 OCStackResult RMCreateRouteOption(const RMRouteOption_t *optValue, CAHeaderOption_t *options)
 {
-    OIC_LOG(DEBUG, RM_TAG, "IN");
     RM_NULL_CHECK_WITH_RET(optValue, RM_TAG, "optValue");
     RM_NULL_CHECK_WITH_RET(options, RM_TAG, "options");
 
@@ -420,13 +423,11 @@ OCStackResult RMCreateRouteOption(const RMRouteOption_t *optValue, CAHeaderOptio
     OIC_LOG_V(INFO, RM_TAG, "Option Length is %d", options->optionLength);
 
     OICFree(tempData);
-    OIC_LOG(DEBUG, RM_TAG, "OUT");
     return OC_STACK_OK;
 }
 
 OCStackResult RMParseRouteOption(const CAHeaderOption_t *options, RMRouteOption_t *optValue)
 {
-    OIC_LOG(DEBUG, RM_TAG, "IN");
     RM_NULL_CHECK_WITH_RET(options, RM_TAG, "options");
     RM_NULL_CHECK_WITH_RET(optValue, RM_TAG, "optValue");
     if (0 == options->optionLength)
@@ -498,6 +499,5 @@ OCStackResult RMParseRouteOption(const CAHeaderOption_t *options, RMRouteOption_
     OIC_LOG_V(INFO, RM_TAG, "Option Sender Addr is [%u][%u]", optValue->srcGw, optValue->srcEp);
     OIC_LOG_V(INFO, RM_TAG, "Option Dest Addr is [%u][%u]", optValue->destGw, optValue->destEp);
     OIC_LOG_V(INFO, RM_TAG, "Message Type is [%u]", optValue->msgType);
-    OIC_LOG(DEBUG, RM_TAG, "OUT");
     return OC_STACK_OK;
 }
index 6d7ccbf..964cdd1 100644 (file)
@@ -49,7 +49,6 @@ else:
 
 libocsrm_env.PrependUnique(CPPPATH = [
                '../../../extlibs/cjson/',
-               '../../../extlibs/tinydtls/',
                '../logger/include',
                '../../c_common/ocrandom/include',
                '../stack/include',
@@ -89,7 +88,7 @@ if env.get('LOGGING'):
        libocsrm_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
 
 if env.get('MULTIPLE_OWNER') == '1':
-       libocsrm_env.AppendUnique(CPPDEFINES=['_ENABLE_MULTIPLE_OWNER_'])
+       libocsrm_env.AppendUnique(CPPDEFINES=['MULTIPLE_OWNER'])
 
 ######################################################################
 # Source files and Targets
@@ -105,7 +104,6 @@ libocsrm_src = [
        OCSRM_SRC + 'pstatresource.c',
        OCSRM_SRC + 'doxmresource.c',
        OCSRM_SRC + 'credresource.c',
-       OCSRM_SRC + 'svcresource.c',
        OCSRM_SRC + 'pconfresource.c',
        OCSRM_SRC + 'dpairingresource.c',
        OCSRM_SRC + 'policyengine.c',
@@ -119,7 +117,9 @@ libocsrm_src = [
 
 if libocsrm_env.get('SECURED') == '1':
        libocsrm_src = libocsrm_src + [OCSRM_SRC + 'oxmpincommon.c', OCSRM_SRC + 'pbkdf2.c']
-       libocsrm_src  = libocsrm_src + [OCSRM_SRC + 'crlresource.c', OCSRM_SRC + 'pkix_interface.c']
+       libocsrm_src = libocsrm_src + [OCSRM_SRC + 'crlresource.c', OCSRM_SRC + 'pkix_interface.c']
+       libocsrm_src = libocsrm_src + [OCSRM_SRC + 'oxmverifycommon.c']
+       libocsrm_src = libocsrm_src + [OCSRM_SRC + 'psiutils.c'] # TODO : need for secure psi
 
 if target_os in ['windows', 'msys_nt']:
        libocsrm_src  = libocsrm_src + [OCSRM_SRC + 'strptime.c']
index db09e46..0172ae4 100644 (file)
@@ -62,7 +62,7 @@ const OicSecAce_t* GetACLResourceData(const OicUuid_t* subjectId, OicSecAce_t **
  */
 OCStackResult AclToCBORPayload(const OicSecAcl_t * acl, uint8_t **outPayload, size_t *size);
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 /**
  * Function to check the ACL access of SubOwner
  *
@@ -73,7 +73,7 @@ OCStackResult AclToCBORPayload(const OicSecAcl_t * acl, uint8_t **outPayload, si
  * @return ::true for valid access, otherwise invalid access
  */
 bool IsValidAclAccessForSubOwner(const OicUuid_t* uuid, const uint8_t *cborPayload, const size_t size);
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
 
 /**
index 32ccefe..1806540 100644 (file)
@@ -82,7 +82,7 @@ OicSecCred_t* GetCredEntryByCredId(const uint16_t credId);
 OCStackResult CredToCBORPayload(const OicSecCred_t* cred, uint8_t **cborPayload,
                                 size_t *cborSize, int secureFlag);
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 /**
  * Function to check the credential access of SubOwner
  *
@@ -93,7 +93,7 @@ OCStackResult CredToCBORPayload(const OicSecCred_t* cred, uint8_t **cborPayload,
  * @return ::true for valid access, otherwise invalid access
  */
 bool IsValidCredentialAccessForSubOwner(const OicUuid_t* uuid, const uint8_t *cborPayload, size_t size);
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
 /**
  * This function generates the bin credential data.
@@ -109,7 +109,7 @@ bool IsValidCredentialAccessForSubOwner(const OicUuid_t* uuid, const uint8_t *cb
 
  */
 OicSecCred_t * GenerateCredential(const OicUuid_t* subject, OicSecCredType_t credType,
-                     const OicSecCert_t * publicData, const OicSecKey_t * privateData,
+                     const OicSecKey_t * publicData, const OicSecKey_t * privateData,
                      const OicUuid_t * rownerID, const OicUuid_t * eownerID);
 
 /**
@@ -238,6 +238,27 @@ void GetDerKey(ByteArray_t * key, const char * usage);
  * @param[in] usage credential usage string.
  */
 void InitCipherSuiteListInternal(bool *list, const char * usage);
+
+
+
+
+//Added as workaround by Chul Lee.
+OCStackResult CredSaveTrustCertChain(const OicUuid_t* subject, uint8_t *trustCertChain, size_t chainSize,
+                                            OicEncodingType_t encodingType,  const char* usage, uint16_t *credId);
+
+OCStackResult CredSaveOwnCert(const OicUuid_t* subject, OicSecKey_t* cert, OicSecKey_t * key,
+                                    const char* usage, uint16_t *credId);
+
+/**
+ * API to add preconfigured PIN for MOT
+ *
+ * @param[in] preconfPin string type of preconfigured PIN
+ *
+ * @retval ::OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult AddPreconfPinCredential(const char* preconfPin);
+
+
 #endif // __WITH_TLS__
 #ifdef __cplusplus
 }
index 97eb65e..349c41b 100644 (file)
@@ -125,7 +125,7 @@ OCStackResult getLastUpdateFromDB(char **lastUpdate);
  *
  * @param crl  crl object
  */
-void printCrl(OicSecCrl_t *crl);
+void printCrl(const OicSecCrl_t *crl);
 
 #ifdef __cplusplus
 }
index 826c187..d42dd73 100644 (file)
@@ -22,9 +22,9 @@
 #define IOTVT_SRM_DOXM_H
 
 #include "octypes.h"
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 #include "cacommon.h"
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
 #ifdef __cplusplus
 extern "C" {
@@ -82,6 +82,18 @@ OCStackResult CBORPayloadToDoxm(const uint8_t *cborPayload, size_t size,
 OCStackResult DoxmToCBORPayload(const OicSecDoxm_t * doxm, uint8_t **cborPayload,
                                 size_t *cborSize, bool rwOnly);
 
+#if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
+/**
+ * API to save the seed value to generate device UUID.
+ *
+ * @param seed buffer of seed value.
+ * @param seedSize byte length of seed
+ *
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
+ */
+OCStackResult SetDoxmDeviceIDSeed(const uint8_t* seed, size_t seedSize);
+#endif
+
 /**
  * This method returns the SRM device ID for this device.
  *
@@ -121,7 +133,7 @@ OCStackResult GetDoxmIsOwned(bool *isOwned);
  */
 OCStackResult GetDoxmRownerId(OicUuid_t *rowneruuid);
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 /**
  * Compare the UUID to SubOwner.
  *
@@ -130,7 +142,7 @@ OCStackResult GetDoxmRownerId(OicUuid_t *rowneruuid);
  * @return true if uuid exists in the SubOwner list of doxm, else false.
  */
 bool IsSubOwner(const OicUuid_t* uuid);
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
 /** This function deallocates the memory for OicSecDoxm_t .
  *
@@ -144,7 +156,7 @@ void DeleteDoxmBinData(OicSecDoxm_t* doxm);
  */
 void RestoreDoxmToInitState();
 
-#if defined(__WITH_DTLS__) && defined(_ENABLE_MULTIPLE_OWNER_)
+#if defined(__WITH_DTLS__) && defined(MULTIPLE_OWNER)
 /**
  * Callback function to handle MOT DTLS handshake result.
  * @param[out]   object           remote device information.
@@ -152,7 +164,44 @@ void RestoreDoxmToInitState();
  */
 void MultipleOwnerDTLSHandshakeCB(const CAEndpoint_t *object,
                                 const CAErrorInfo_t *errorInfo);
-#endif //__WITH_DTLS__ && _ENABLE_MULTIPLE_OWNER_
+#endif //__WITH_DTLS__ && MULTIPLE_OWNER
+
+/**
+ * Internal function to change doxm resource to Ready for Normal Operation.
+ *
+ * @param newROwner new owner
+ *
+ * @retval ::OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult SetDoxmSelfOwnership(const OicUuid_t* newROwner);
+
+/**
+ * Function to set a MOT status
+ *
+ * @param enable whether the MOT is enabled. (true=enable, false=disable)
+ *
+ * @retval ::OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult SetMOTStatus(bool enable);
+
+/**
+ * Function to remove the Sub Owner (include ACL/Cred)
+ *
+ * @param subOwner UUID of Sub Owner to be removed.
+ *
+ * @retVal ::OC_STACK_OK for success, otherwise some error value.
+ */
+OCStackResult RemoveSubOwner(const OicUuid_t* subOwner);
+
+/**
+ * Function to set a max number of sub owner.
+ *
+ * @param maxSubOwner Max number of sub owner.
+ *
+ * @retVal ::OC_STACK_OK for success, otherwise some error value.
+ */
+OCStackResult SetNumberOfSubOwner(size_t maxSubOwner);
+
 
 #ifdef __cplusplus
 }
index 66b399c..83841c1 100644 (file)
@@ -50,10 +50,10 @@ typedef struct PEContext
     SRMAccessResponse_t retVal;
     AmsMgrContext_t     *amsMgrContext;
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
     uint8_t* payload;
     size_t payloadSize;
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 } PEContext_t;
 
 /**
index 493690a..ae228bf 100644 (file)
 #ifndef IOTVT_SRM_PSI_H
 #define IOTVT_SRM_PSI_H
 
+#if defined (__TIZENRT__)
+#include <apps/netutils/cJSON.h>
+#else
 #include "cJSON.h"
+#endif
+
+// Persistent Storage status definition
+typedef enum
+{
+    PS_NORMAL = 0,      // Persistent Storage operating normally
+    PS_OPEN_FAIL,       // Failed to open persistent storage
+    PS_PARSE_FAIL,     // Failed to cbor parse persistent storage
+    PS_NO_EXTERNAL_DB_SET = 99, // no external DB set (initial state)
+} PSStatus_t;
 
 /**
  * Reads the Secure Virtual Database from PS into dynamically allocated
@@ -61,6 +74,20 @@ OCStackResult UpdateSVRDatabase(const char* rsrcName, cJSON* jsonObj);
 OCStackResult GetSecureVirtualDatabaseFromPS(const char *rsrcName, uint8_t **data, size_t *size);
 
 /**
+ * Gets the Secure Virtual Database from the Persistent Storage
+ *
+ * @param ps - Persistent Storage handler
+ * @param rsrcName - pointer of character string for the SVR name (e.g. "acl")
+ * @param data - pointer of the returned Secure Virtual Resource(s)
+ * @param size - pointer of the returned size of Secure Virtual Resource(s)
+ *
+ * @return OCStackResult - result of getting Secure Virtual Resource(s)
+ */
+OCStackResult GetSecureVirtualDatabaseFromPS2(OCPersistentStorage* ps, const char *rsrcName,
+                                              uint8_t **data, size_t *size);
+
+
+/**
  * This method converts updates the persistent storage.
  *
  * @param rsrcName is the name of the secure resource that will be updated.
@@ -69,7 +96,7 @@ OCStackResult GetSecureVirtualDatabaseFromPS(const char *rsrcName, uint8_t **dat
  *
  * @return ::OC_STACK_OK for Success, otherwise some error value
  */
-OCStackResult UpdateSecureResourceInPS(const char* rsrcName, uint8_t* cborPayload, size_t size);
+OCStackResult UpdateSecureResourceInPS(const char* rsrcName, const uint8_t* cborPayload, size_t size);
 
 /**
  * This method resets the secure resources according to the reset profile.
@@ -88,4 +115,41 @@ OCStackResult ResetSecureResourceInPS(void);
  */
 OCStackResult CreateResetProfile(void);
 
+/**
+ * This method sets the persistent storage status.
+ *
+ * @param status is the current persistent storage status
+ */
+void SetPSStatus(PSStatus_t status);
+
+/**
+ * This method prints debug log that displays persistent storage status.
+ */
+void PrintPSStatus(void);
+
+/**
+ * Init the Persistent Storage Database.
+ */
+OCStackResult InitPersistentStorageInterface(void);
+
+/**
+ * DeInit the Persistent Storage Database.
+ */
+void DeinitPersistentStorageInterface(void);
+
+/**
+ * API to encrypt the un-encrypted DB file before OCRegisterPersistentStorageHandler
+ * If the API is successful, un-encrypted file will be removed, and if the encrypted file
+ * is currupted, then it restores encrypted file using rescue file.
+ *
+ * @param[in] key key used for encryption
+ * @param[in] psPlain OCPersistentStorage for the plain DB
+ * @param[in] psEnc OCPersistentStorage for the encrypted DB
+ * @param[in] psRescue OCPersistentStorage for the rescue DB
+ *
+ * @return ::OC_STACK_OK on success and other value otherwise.
+ */
+OCStackResult setSecurePSI(const unsigned char *key, const OCPersistentStorage *psPlain,
+        const OCPersistentStorage *psEnc, const OCPersistentStorage *psRescue);
+
 #endif //IOTVT_SRM_PSI_H
diff --git a/resource/csdk/security/include/internal/psiutils.h b/resource/csdk/security/include/internal/psiutils.h
new file mode 100644 (file)
index 0000000..5e93569
--- /dev/null
@@ -0,0 +1,72 @@
+//******************************************************************
+//
+// Copyright 2017 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 IOTVT_SRM_PSIUTILS_H
+#define IOTVT_SRM_PSIUTILS_H
+
+#define AES_KEY_SIZE 32
+
+/**
+ * @brief Generic Encryption function to encrypt data buffer in plaintext
+ * and update in ciphertext and len in ct_len. (AES-CBC-HMAC)
+ * @param[in] plaintext plaintext to be encrypted
+ * @param[in] pt_len length of plaintext
+ * @param[out] ciphertext ciphered text
+ * @param[out] ct_len is length of the ciphered text.
+ *
+ * @return ::0 for Success.
+ */
+int psiEncrypt(const unsigned char *plaintext, size_t pt_len,
+                unsigned char **ciphertext, size_t *ct_len);
+
+/**
+ * @brief Generic Decryption function to decrypt data buffer in ciphertext
+ * and update in plaintext and len in pt_len. (AES-CBC-HMAC)
+ * @param[in] ciphertext ciphered to be decrypted
+ * @param[in] ct_len length of cipher text
+ * @param[out] plaintext plaintext text
+ * @param[out] pt_len is length of the plaintext text.
+ *
+ * @return ::0 for Success.
+ */
+int psiDecrypt(const unsigned char *ciphertext, size_t ct_len,
+                unsigned char **plaintext, size_t *pt_len);
+
+/**
+ * @brief API to set key to psi
+ * @param[in] key key used for encryption
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
+ */
+OCStackResult psiSetKey(const unsigned char* key);
+
+/**
+ * @brief API to get key from psi
+ * @param[out] key key used for encryption
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
+ */
+OCStackResult psiGetKey(unsigned char* key);
+
+/**
+ * @brief It provides state to set key for encryption
+ * @return ::true for setting key.
+ */
+bool psiIsKeySet();
+
+#endif //IOTVT_SRM_PSIUTILS_H
index c603f34..c021cb0 100644 (file)
@@ -64,6 +64,19 @@ OCStackResult DeInitPstatResource();
  OCStackResult CBORPayloadToPstat(const uint8_t *cborPayload, const size_t cborSize,
                                   OicSecPstat_t **pstat);
 
+#ifdef MULTIPLE_OWNER
+/**
+ * Function to check the pstat access of SubOwner
+ *
+ * @param[in] cborPayload CBOR payload of pstat
+ * @param[in] size Byte length of cborPayload
+ *
+ * @return ::true for valid access, otherwise invalid access
+ */
+bool IsValidPstatAccessForSubOwner(const uint8_t *cborPayload, size_t size);
+#endif
+
+
 /** This function deallocates the memory for OicSecPstat_t.
  *
  * @param pstat is the pointer to @ref OicSecPstat_t.
@@ -100,6 +113,15 @@ OCStackResult GetPstatRownerId(OicUuid_t *rowneruuid);
  */
 bool GetPstatIsop();
 
+/**
+ * Internal function to change pastat resource to Ready for Normal Operation.
+ *
+ * @param newROwner new owner
+ *
+ * @retval ::OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult SetPstatSelfOwnership(const OicUuid_t* newROwner);
+
 #ifdef __cplusplus
 }
 #endif
index 7976452..cc9c531 100644 (file)
@@ -105,6 +105,12 @@ void SRMRegisterProvisioningResponseHandler(SPResponseCallback respHandler);
 bool SRMIsSecurityResourceURI(const char* uri);
 
 /**
+ * Check whether persistent storage is valid
+ * @return OC_STACK_OK if valid, other errors otherwise;
+ */
+OCStackResult CheckPersistentStorage(OCPersistentStorage* persistentStorageHandler);
+
+/**
  * Get the resource type from the URI.
  * @param   uri [IN] Pointers to security resource URI.
  * @return  SVR type (note that "NOT_A_SVR_RESOURCE" is returned if not a SVR)
index 13030d9..42b1e5a 100644 (file)
@@ -46,25 +46,6 @@ OCEntityHandlerResult ACLEntityHandler(OCEntityHandlerFlag flag,
 OCStackResult SetDefaultACL(OicSecAcl_t *acl);
 
 /**
- * Converts CBOR payload to SVC.
- *
- * @param cborPayload is the svc payload cbor value that neds to be converted.
- * @param cborSize of the cborPayload. In case size is not known, it is 0.
- * @param svc is the value that is initialized. It is NULL in case of error.
- *
- * @return ::OC_STACK_OK in case successful. ::OC_STACK_INVALID_PARAM if one of
- * the passed parameter is NULL. ::OC_STACK_ERROR in case of error.
- */
-OCStackResult CBORPayloadToSVC(const uint8_t *cborPayload, size_t size, OicSecSvc_t **svc);
-
-/**
- * Deletes the passed initialized reference to @ref OicSecSvc_t.
- *
- * @param svc is the reference to be deleted.
- */
-void DeleteSVCList(OicSecSvc_t* svc);
-
-/**
  * Create PSTAT resource after default PSTAT initialization is done.
  */
 OCStackResult CreatePstatResource();
index 3a35e28..28cb3cb 100644 (file)
@@ -69,11 +69,6 @@ extern const char * OIC_RSRC_TYPE_SEC_SACL;
 extern const char * OIC_RSRC_SACL_URI;
 extern const char * OIC_JSON_SACL_NAME;
 
-//SVC
-extern const char * OIC_RSRC_TYPE_SEC_SVC;
-extern const char * OIC_RSRC_SVC_URI;
-extern const char * OIC_JSON_SVC_NAME;
-
 //PCONF
 extern const char * OIC_RSRC_TYPE_SEC_PCONF;
 extern const char * OIC_RSRC_PCONF_URI;
@@ -101,15 +96,15 @@ extern const char * OIC_JSON_PERMISSION_NAME;
 extern const char * OIC_JSON_OWNERS_NAME;
 extern const char * OIC_JSON_OWNER_NAME;
 extern const char * OIC_JSON_DEVOWNERID_NAME;
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 extern const char * OIC_JSON_SUBOWNERID_NAME;
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 extern const char * OIC_JSON_OWNED_NAME;
 extern const char * OIC_JSON_OXM_NAME;
 extern const char * OIC_JSON_OXMS_NAME;
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 extern const char * OIC_JSON_MOM_NAME;
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 extern const char * OIC_JSON_OXM_TYPE_NAME;
 extern const char * OIC_JSON_OXM_SEL_NAME;
 extern const char * OIC_JSON_DEVICE_ID_FORMAT_NAME;
@@ -121,6 +116,7 @@ extern const char * OIC_JSON_PRIVATEDATA_NAME;
 extern const char * OIC_JSON_PUBDATA_NAME;
 extern const char * OIC_JSON_PRIVDATA_NAME;
 extern const char * OIC_JSON_OPTDATA_NAME;
+extern const char * OIC_JSON_REVOCATION_STATUS_NAME;
 extern const char * OIC_JSON_CREDUSAGE_NAME;
 extern const char * OIC_JSON_CRMS_NAME;
 extern const char * OIC_JSON_VALIDITY_NAME;
@@ -134,8 +130,6 @@ extern const char * OIC_JSON_CM_NAME;
 extern const char * OIC_JSON_TM_NAME;
 extern const char * OIC_JSON_OM_NAME;
 extern const char * OIC_JSON_SM_NAME;
-extern const char * OIC_JSON_SERVICE_DEVICE_ID;
-extern const char * OIC_JSON_SERVICE_TYPE;
 extern const char * OIC_JSON_SUPPORTED_CRED_TYPE_NAME;
 extern const char * OIC_JSON_DPC_NAME;
 extern const char * OIC_JSON_EDP_NAME;
@@ -152,9 +146,9 @@ extern const char * OIC_JSON_REL_NAME;
 extern const char * OIC_JSON_RT_NAME;
 extern const char * OIC_JSON_IF_NAME;
 extern const char * OIC_JSON_ROWNERID_NAME;
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 extern const char * OIC_JSON_EOWNERID_NAME;
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 extern const char * OIC_JSON_ENCODING_NAME;
 extern const char * OIC_JSON_DATA_NAME;
 extern const char * OIC_JSON_SEC_V_NAME;
@@ -178,9 +172,14 @@ extern const char * WILDCARD_RESOURCE_URI;
 extern const char * OXM_JUST_WORKS;
 extern const char * OXM_RANDOM_DEVICE_PIN;
 extern const char * OXM_MANUFACTURER_CERTIFICATE;
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 extern const char * OXM_PRECONF_PIN;
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
+extern const char * OXM_MV_JUST_WORKS;
+extern const char * OXM_CON_MFG_CERT;
+
+//Mutual Verified Just-Works Message Prefix
+extern const char * MUTUAL_VERIF_NUM;
 
 extern const char * OIC_SEC_ENCODING_BASE64;
 extern const char * OIC_SEC_ENCODING_RAW;
diff --git a/resource/csdk/security/include/internal/svcresource.h b/resource/csdk/security/include/internal/svcresource.h
deleted file mode 100644 (file)
index ce759f8..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-//******************************************************************
-//
-// 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.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-#ifndef IOTVT_SRM_SVCR_H
-#define IOTVT_SRM_SVCR_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Initialize SVC resource by loading data from persistent storage.
- *
- * @return ::OC_STACK_OK for Success, otherwise some error value.
- */
-OCStackResult InitSVCResource();
-
-/**
- * Perform cleanup for SVC resources.
- */
-void DeInitSVCResource();
-
-/**
- * This function converts SVC data into CBOR format.
- * Caller needs to invoke 'free' when done using returned string.
- *
- * @param svc is the instance of @ref OicSecSvc_t structure. In case of NULL it
- * will return ::OC_STACK_INVALID_PARAM.
- * @param cborPayload is the converted cbor value of SVC structure.
- * @param cborSize is the size of the cbor payload. This value is the size of the
- * cborPayload. It should not be NON-NULL value.
- *
- * @return ::OC_STACK_OK for Success. ::OC_STACK_INVALID in case of invalid parameters.
- * ::OC_STACK_ERROR in case of error in converting to cbor.
- */
- OCStackResult SVCToCBORPayload(const OicSecSvc_t *svc, uint8_t **cborPayload,
-                                size_t *cborSize);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif //IOTVT_SRM_SVCR_H
diff --git a/resource/csdk/security/include/oxmverifycommon.h b/resource/csdk/security/include/oxmverifycommon.h
new file mode 100644 (file)
index 0000000..c26852b
--- /dev/null
@@ -0,0 +1,142 @@
+//******************************************************************
+//
+// Copyright 2016 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 _OXM_VERIFY_COMMON_
+#define _OXM_VERIFY_COMMON_
+
+#include "securevirtualresourcetypes.h"
+#include "casecurityinterface.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif // __cplusplus
+
+/** Verification Number Length */
+#define MUTUAL_VERIF_NUM_LEN (3)
+
+/** Label Length */
+#define LABEL_LEN (30)
+
+/**
+ * Verification Method Option definition
+ * This type supports multiple bit set.
+ */
+ typedef enum VerifyOptionBitmask
+{
+    NOT_APPLICABLE              = 0x0,
+    DISPLAY_NUM                 = (0x1 << 0),
+    USER_CONFIRM                = (0x1 << 1)
+} VerifyOptionBitmask_t;
+
+/**
+ * Function pointer to display verification PIN
+ */
+typedef OCStackResult (*DisplayNumCallback)(void * ctx, uint8_t verifNum[MUTUAL_VERIF_NUM_LEN]);
+
+/**
+ * Function pointer to get user confirmation
+ */
+typedef OCStackResult (*UserConfirmCallback)(void * ctx);
+
+/**
+ * Function pointer to notify user input state
+ */
+typedef OCStackResult (*InputStateCallback)(void * ctx);
+
+/**
+ * Context for displaying verification PIN
+ */
+typedef struct DisplayNumContext
+{
+    DisplayNumCallback callback;
+    void * context;
+} DisplayNumContext_t;
+
+/**
+ * Context for getting user confirmation
+ */
+typedef struct UserConfirmContext
+{
+    UserConfirmCallback callback;
+    void * context;
+} UserConfirmContext_t;
+
+/**
+ * Context for notifying user input state
+ */
+typedef struct InputStateContext
+{
+    InputStateCallback callback;
+    void * context;
+} InputStateContext_t;
+
+/**
+ * Set Callback for displaying verification PIN
+ */
+void SetDisplayNumCB(void * ptr, DisplayNumCallback displayNumCB);
+
+/**
+ * Unset Callback for displaying verification PIN
+ */
+void* UnsetDisplayNumCB();
+
+/**
+ * Set Callback for getting user confirmation
+ */
+void SetUserConfirmCB(void * ptr, UserConfirmCallback userConfirmCB);
+
+/**
+ * Unset Callback for getting user confirmation
+ */
+void* UnsetUserConfirmCB();
+
+/**
+ * Set Callback for notifying user input state
+ */
+void SetInputStateCB(void * ptr, UserConfirmCallback userConfirmCB);
+
+/**
+ * Unset Callback for notifying user input state
+ */
+void* UnsetInputStateCB();
+
+/**
+ * Set verification method option.
+ * The default is both display PIN and get user confirmation.
+ */
+void SetVerifyOption(VerifyOptionBitmask_t verifyOption);
+
+/**
+ * Call the Callback for Verifying Ownership Transfer process.
+ */
+OCStackResult VerifyOwnershipTransfer(uint8_t mutualVerifNum[MUTUAL_VERIF_NUM_LEN],
+                                VerifyOptionBitmask_t verifyOption);
+
+/**
+ * Call the Callback for notifying user input state
+ */
+OCStackResult NotifyInputState(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
index 52e411f..5b75684 100644 (file)
@@ -59,6 +59,11 @@ typedef void (*GeneratePinCallback)(char* pinData, size_t pinSize);
 typedef void (*InputPinCallback)(char* pinBuf, size_t bufSize);
 
 /**
+ * Function pointer to close the displied PIN.
+ */
+typedef void (*ClosePinDisplayCallback)(void);
+
+/**
  * Function to setting generate PIN callback from user.
  *
  * @param pinCB implementation of generate PIN callback.
@@ -73,6 +78,14 @@ void SetGeneratePinCB(GeneratePinCallback pinCB);
 void SetInputPinCB(InputPinCallback pinCB);
 
 /**
+ * Function to set the close PIN callback
+ * This callback will be invoked when PIN based OTM is finished.
+ *
+ * @param closeCB implementation of close PIN callback.
+ */
+void SetClosePinDisplayCB(ClosePinDisplayCallback closeCB);
+
+/**
  * Function to unset the input PIN callback.
  * NOTE : Do not call this function while PIN based ownership transfer.
  */
@@ -85,6 +98,12 @@ void UnsetInputPinCB();
 void UnsetGeneratePinCB();
 
 /**
+ * Function to unset the PIN close callback.
+ * NOTE : Do not call this function while PIN based ownership transfer is in progress.
+ */
+void UnsetClosePinCB();
+
+/**
  * Function to generate random PIN.
  * This function will send generated PIN to user via callback.
  *
@@ -105,7 +124,13 @@ OCStackResult GeneratePin(char* pinBuffer, size_t bufferSize);
  */
 OCStackResult InputPin(char* pinBuffer, size_t bufferSize);
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+/**
+ * Function to invoke the callback for close a PIN dispaly.
+ * NOTE : This function will be invoked from SRM while OTM
+ */
+void ClosePinDisplay();
+
+#ifdef MULTIPLE_OWNER
 /**
  * Function to save the Pre-configured PIN.
  *
@@ -153,7 +178,7 @@ int32_t GetDtlsPskForRandomPinOxm( CADtlsPskCredType_t type,
               const unsigned char *UNUSED1, size_t UNUSED2,
               unsigned char *result, size_t result_length);
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 /**
  * This internal callback is used while Random PIN based MOT.
  * This callback will be used to establish a temporary secure session according to
@@ -210,8 +235,7 @@ int32_t GetDtlsPskForMotPreconfPinOxm( CADtlsPskCredType_t type,
               const unsigned char *UNUSED1, size_t UNUSED2,
               unsigned char *result, size_t result_length);
 
-#endif //_ENABLE_MULTIPLE_OWNER_
-
+#endif //MULTIPLE_OWNER
 
 /**
  * API to derive the PSK based on PIN and new device's UUID.
index 5af15ce..105fda3 100644 (file)
 #define PKIX_INTERFACE_H
 
 #include "cainterface.h"
+#ifdef HW_PKIX
+#include "mbedtls/ssl.h"
+#endif //HW_PKIX
 
 #ifdef __cplusplus
 extern "C" {
 #endif
+
+/**
+ * Pre-Definition for key context
+ */
+// IoTivity service name for HW key context query
+#define HWKEY_SVC_IOTIVITY "iotivity"
+
+// Default usage name for HW key context query
+#define HWKEY_USAGE_PRIMARY "primary"
+
+
+/**
+ * Callback function for HW
+ */
+//this callback will be invoked to get key context based on key usage
+typedef void* (*GetHwKeyContext)(const char* service, const char* usage, const char* keytype);
+
+//this callback will free key context that was retreived from TZ
+typedef int (*FreeHwKeyContext)(void* keyContext);
+
+//this callback will be invoked to load own certificate in case of TZ
+typedef int (*GetOwnCertFromHwCallback)(const void* keyContext, uint8_t** certChain, size_t* certChainLen);
+
+//this callback will be invoked to load private key in case of TZ
+typedef int (*SetupPkContextFromHwCallback)(mbedtls_pk_context* ctx, void* keyContext);
+
+typedef struct HWPkixContext {
+    GetHwKeyContext getHwKeyContext;
+    FreeHwKeyContext freeHwKeyContext;
+    GetOwnCertFromHwCallback getOwnCertCb;
+    SetupPkContextFromHwCallback setupPkContextCb;
+    void* hwKeyCtx;
+}HWPkixContext_t;
+
+/**
+ * API to seting callbacks which is requried to use H/W based PKI
+ *
+ * @param[in] getHwKeyContext callback to get hw key context
+ * @param[in] freeHwKeyContext callback to free hw key context
+ * @param[in] getOwnCertCb callback to load certificate chain
+ * @param[in] setupPkContextCb callback to setup PK context
+ *
+ * return 0 on success
+ */
+int SetHwPkixCallbacks(GetHwKeyContext getHwKeyContext,
+                        FreeHwKeyContext freeHwKeyContext,
+                        GetOwnCertFromHwCallback getOwnCertCb,
+                        SetupPkContextFromHwCallback setupPkContextCb);
+
+/**
+ * API to invoke the callback for setup PK context with H/W based PKI
+ *
+ * @param[in] pkCtx mbedtls's PK context
+ *
+ * return 0 on success
+ */
+int SetupHwPkContext(mbedtls_pk_context* pkCtx);
+
 /**
  * This method is used by mbedTLS/SRM to retrieve PKIX related info
  *
index 0f2ac78..f6de36c 100644 (file)
@@ -219,7 +219,7 @@ typedef enum OicSecDpm
     SECURITY_MANAGEMENT_SERVICES    = (0x1 << 3),
     PROVISION_CREDENTIALS           = (0x1 << 4),
     PROVISION_ACLS                  = (0x1 << 5),
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
     TAKE_SUB_OWNER                  = (0x1 << 6),
 #endif
     // << 7 THROUGH 15 RESERVED
@@ -235,13 +235,6 @@ typedef enum OicSecDpom
     SINGLE_SERVICE_CLIENT_DRIVEN      = (0x1 << 2),
 } OicSecDpom_t;
 
-typedef enum OicSecSvcType
-{
-    SERVICE_UNKNOWN                 = 0x0,
-    ACCESS_MGMT_SERVICE             = 0x1,  //urn:oic.sec.ams
-} OicSecSvcType_t;
-
-
 //TODO: Need more clarification on deviceIDFormat field type.
 #if 0
 typedef enum
@@ -261,7 +254,6 @@ typedef enum
     OIC_R_PCONF_TYPE,
     OIC_R_PSTAT_TYPE,
     OIC_R_SACL_TYPE,
-    OIC_R_SVC_TYPE,
     OIC_SEC_SVR_TYPE_COUNT, //define the value to number of SVR
     NOT_A_SVR_RESOURCE = 99
 }OicSecSvrType_t;
@@ -273,9 +265,11 @@ typedef enum
     OIC_MANUFACTURER_CERTIFICATE            = 0x2,
     OIC_DECENTRALIZED_PUBLIC_KEY            = 0x3,
     OIC_OXM_COUNT,
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
     OIC_PRECONFIG_PIN                       = 0xFF00,
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
+    OIC_MV_JUST_WORKS                       = 0xFF01,
+    OIC_CON_MFG_CERT                        = 0xFF02,
 }OicSecOxm_t;
 
 typedef enum
@@ -287,14 +281,14 @@ typedef enum
     OIC_ENCODING_DER = 4
 }OicEncodingType_t;
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 typedef enum
 {
     MOT_STATUS_READY = 0,
     MOT_STATUS_IN_PROGRESS = 1,
     MOT_STATUS_DONE = 2,
 }MotStatus_t;
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
 /*
  * oic.sec.mom type definition
@@ -313,22 +307,22 @@ typedef enum
 
 typedef struct OicSecKey OicSecKey_t;
 
+typedef struct OicSecOpt OicSecOpt_t;
+
 typedef struct OicSecPstat OicSecPstat_t;
 
 typedef struct OicSecRole OicSecRole_t;
 
 typedef struct OicSecSacl OicSecSacl_t;
 
-typedef struct OicSecSvc OicSecSvc_t;
-
 typedef char *OicUrn_t; //TODO is URN type defined elsewhere?
 
 typedef struct OicUuid OicUuid_t; //TODO is UUID type defined elsewhere?
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 typedef struct OicSecSubOwner OicSecSubOwner_t;
 typedef struct OicSecMom OicSecMom_t;
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
 
 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
@@ -369,6 +363,15 @@ struct OicSecKey
 
 };
 
+struct OicSecOpt
+{
+    uint8_t                *data;
+    size_t                  len;
+
+    OicEncodingType_t encoding;
+    bool                revstat;
+};
+
 struct OicSecRsrc
 {
     char *href; // 0:R:S:Y:String
@@ -395,7 +398,7 @@ struct OicSecAce
     OicSecRsrc_t *resources;            // 1:R:M:Y:Resource
     uint16_t permission;                // 2:R:S:Y:UINT16
     OicSecValidity_t *validities;       // 3:R:M:N:Time-interval
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
     OicUuid_t* eownerID;                //4:R:S:N:oic.uuid
 #endif
     OicSecAce_t *next;
@@ -442,20 +445,20 @@ struct OicSecCred
     //OicSecRole_t        *roleIds;       // 2:R:M:N:oic.sec.role
     OicSecCredType_t    credType;       // 3:R:S:Y:oic.sec.credtype
 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
-    OicSecCert_t        publicData;     // own cerificate chain
+    OicSecKey_t         publicData;     // own cerificate chain
     char            *credUsage;            // 4:R:S:N:String
-    OicSecKey_t        optionalData;   // CA's cerificate chain
+    OicSecOpt_t        optionalData;   // CA's cerificate chain
 #endif /* __WITH_DTLS__  or __WITH_TLS__*/
     OicSecKey_t         privateData;    // 6:R:S:N:oic.sec.key
     char                *period;        // 7:R:S:N:String
     OicUuid_t           rownerID;       // 8:R:S:Y:oic.uuid
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
     OicUuid_t           *eownerID;      //9:R:S:N:oic.uuid
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
     OicSecCred_t        *next;
 };
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 struct OicSecSubOwner {
     OicUuid_t uuid;
     MotStatus_t status;
@@ -465,7 +468,7 @@ struct OicSecSubOwner {
 struct OicSecMom{
     OicSecMomType_t mode;
 };
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
 /**
  * /oic/sec/doxm (Device Owner Transfer Methods) data type
@@ -486,10 +489,10 @@ struct OicSecDoxm
     OicUuid_t           deviceID;       // 6:R:S:Y:oic.uuid
     bool                dpc;            // 7:R:S:Y:Boolean
     OicUuid_t           owner;          // 8:R:S:Y:oic.uuid
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
     OicSecSubOwner_t* subOwners;        //9:R/W:M:N:oic.uuid
     OicSecMom_t *mom;                   //10:R/W:S:N:oic.sec.mom
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
     OicUuid_t           rownerID;       // 11:R:S:Y:oic.uuid
 };
 
@@ -534,20 +537,6 @@ struct OicSecSacl
 #endif
 };
 
-/**
- * /oic/sec/svc (Service requiring a secure connection) data type.
- * Derived from OIC Security Spec; see Spec for details.
- */
-struct OicSecSvc
-{
-    // <Attribute ID>:<Read/Write>:<Multiple/Single>:<Mandatory?>:<Type>
-    OicUuid_t               svcdid;                 //0:R:S:Y:oic.uuid
-    OicSecSvcType_t         svct;                   //1:R:M:Y:OIC Service Type
-    size_t                  ownersLen;              //2:the number of elts in Owners
-    OicUuid_t               *owners;                //3:R:M:Y:oic.uuid
-    OicSecSvc_t             *next;
-};
-
 #if defined(__WITH_DTLS__) ||  defined(__WITH_TLS__)
 struct OicSecCrl
 {
@@ -634,7 +623,7 @@ struct OicSecDpairing
     OicUuid_t           rownerID;          // 2:R:S:Y:oic.uuid
 };
 
-#define MAX_VERSION_LEN 16 // Security Version length. i.e., 00.00.000 + reserved space
+#define OIC_SEC_MAX_VER_LEN 16 // Security Version length. i.e., 00.00.000 + reserved space
 
 /**
  * @brief   security version data type
@@ -647,7 +636,7 @@ typedef struct OicSecVer OicSecVer_t;
 struct OicSecVer
 {
     // <Attribute ID>:<Read/Write>:<Multiple/Single>:<Mandatory?>:<Type>
-    char              secv[MAX_VERSION_LEN];          // 0:R:S:Y:String
+    char              secv[OIC_SEC_MAX_VER_LEN];          // 0:R:S:Y:String
     OicUuid_t       deviceID;     // 1:R:S:Y:oic.uuid
 };
 
index bcf5ea8..3608bbc 100644 (file)
 #define IOTVT_SRM_UTILITY_H
 
 #include "ocstack.h"
+#if defined (__TIZENRT__)
+#include <apps/netutils/cJSON.h>
+#else
 #include "cJSON.h"
+#endif
 #include "securevirtualresourcetypes.h"
 #ifdef __cplusplus
 extern "C"
@@ -55,6 +59,24 @@ struct OicParseQueryIter
     coap_parse_iterator_t pi;   /**< coap struct for tokenizing the query.*/
 };
 
+typedef enum OicSecOtmEvent{
+    OIC_OTM_READY = 0,
+    OIC_OTM_STARTED = 1,
+    OIC_OTM_DONE = 2,
+    OIC_OTM_ERROR = 3
+}OicSecOtmEvent_t;
+
+/**
+ * Callback function to recevie the OTM event on server side.
+ *
+ * @param addr PT's address (address can be NULL in case of init state)
+ * @param port PT's port (It is meaningless in case of init state & BLE)
+ * @param uuid PT's UUID (UUID can be NULL in case of init state & coap reqest)
+ * @param event OTM state (@ref OicSecOtmEvent_t)
+ */
+typedef void (*OicSecOtmEventHandler_t)(const char* addr, uint16_t port,
+                                        const char* uuid, int event);
+
 /**
  * Macro to verify success of operation.
  * eg: VERIFY_SUCCESS(TAG, OC_STACK_OK == foo(), ERROR);
@@ -136,6 +158,37 @@ OCStackResult ConvertUuidToStr(const OicUuid_t* uuid, char** strUuid);
 OCStackResult ConvertStrToUuid(const char* strUuid, OicUuid_t* uuid);
 
 
+#if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
+/**
+ * API to save the seed value to generate device UUID.
+ *
+ * @param seed buffer of seed value.
+ * @param seedSize byte length of seed
+ *
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
+ */
+OCStackResult SetDeviceIdSeed(const uint8_t* seed, size_t seedSize);
+
+/**
+ * API to register OTM event handler
+ *
+ * @param otmEventHandler implementation of OTM event handler (@ref OicSecOtmEventHandler_t)
+ */
+void SetOtmEventHandler(OicSecOtmEventHandler_t otmEventHandler);
+
+/**
+ * Invoke OTM event handler to notify the OTM state.
+ *
+ * @param addr PT's address (address can be NULL in case of init state)
+ * @param port PT's port (It is meaningless in case of init state & BLE)
+ * @param uuid PT's UUID (UUID can be NULL in case of init state & coap reqest)
+ * @param event OTM state (@ref OicSecOtmEvent_t)
+ * @param result OTM result code
+ */
+void InvokeOtmEventHandler(const char* addr, uint16_t port,
+                           const OicUuid_t* uuid, OicSecOtmEvent_t event);
+#endif
+
 #ifdef __cplusplus
 }
 #endif // __cplusplus
index c5be751..0e810fb 100644 (file)
@@ -48,7 +48,7 @@ provisioning_env.AppendUnique(CPPPATH = [
                'include/oxm',
                '../../resource/csdk/security/include',
                '../../../../extlibs/cjson/',
-               '../../../../extlibs/tinydtls/',
+               '../../../../extlibs/mbedtls/mbedtls/include',
                '../../connectivity/inc',
                '../../connectivity/inc/pkix',
                '../../connectivity/external/inc',
@@ -56,8 +56,6 @@ provisioning_env.AppendUnique(CPPPATH = [
                '../../connectivity/api',
                '../include',
                '../include/internal',
-               '../../../../extlibs/tinydtls/ecc',
-               '../../../../extlibs/tinydtls/sha2',
                '../../../../extlibs/asn1cert',
                'ck_manager/include'
                ])
@@ -82,6 +80,7 @@ if target_os in ['windows', 'msys_nt']:
 if target_os in ['android']:
        provisioning_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions'])
        provisioning_env.AppendUnique(LIBS = ['gnustl_static'])
+       provisioning_env.AppendUnique(LINKFLAGS = ['-Wl,-soname,libocpmapi.so'])
 
 if target_os in ['darwin', 'ios']:
        provisioning_env.AppendUnique(CPPDEFINES = ['_DARWIN_C_SOURCE'])
@@ -90,7 +89,7 @@ if provisioning_env.get('LOGGING'):
     provisioning_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
 
 if provisioning_env.get('MULTIPLE_OWNER') == '1':
-       provisioning_env.AppendUnique(CPPDEFINES=['_ENABLE_MULTIPLE_OWNER_'])
+       provisioning_env.AppendUnique(CPPDEFINES=['MULTIPLE_OWNER'])
 
 ######################################################################
 # Source files and Targets
index cd35605..ea571d4 100644 (file)
@@ -92,7 +92,7 @@ OCStackResult MOTProvisionPreconfigPIN(void *ctx, const OCProvisionDev_t *target
  *
  * @param[in] ctx Application context would be returned in result callback
  * @param[in] selectedDeviceList linked list of multiple ownership transfer candidate devices.
- * @param[in] resultCB Result callback function to be invoked when multiple ownership transfer finished.
+ * @param[in] resultCallback Result callback function to be invoked when multiple ownership transfer finished.
  * @return OC_STACK_OK in case of success and other value otherwise.
  */
 OCStackResult MOTDoOwnershipTransfer(void* ctx,
@@ -111,6 +111,21 @@ OCStackResult MOTDoOwnershipTransfer(void* ctx,
 OCStackResult MOTAddPreconfigPIN(const OCProvisionDev_t *targetDeviceInfo,
                                  const char* preconfPIN, size_t preconfPINLen);
 
+
+/**
+ * API to remove sub-owner from resource server
+ *
+ * @param[in] ctx Application context would be returned in result callback
+ * @param[in] targetDeviceInfo Selected target device.
+ * @param[in] subOwner sub-owner UUID to be removed
+ * @param[in] resultCallback callback provided by API user, callback will be invoked when
+ *            DELETE 'subowneruuid' request recieves a response from resource server.
+ * @return OC_STACK_OK in case of success and other value otherwise.
+ */
+OCStackResult MOTRemoveSubOwner(void* ctx,
+                                const OCProvisionDev_t *targetDeviceInfo,
+                                const OicUuid_t* subOwner,
+                                OCProvisionResultCB resultCallback);
 #ifdef __cplusplus
 }
 #endif
index 81e92f8..e69de7a 100644 (file)
@@ -65,7 +65,14 @@ OCStackResult AddOTMContext(OTMContext_t* ctx, const char* addr, uint16_t port);
  *
  * @return OTMContext in case of context found, otherwise NULL.
  */
-const OTMContext_t* GetOTMContext(const char* addr, uint16_t port);
+OTMContext_t* GetOTMContext(const char* addr, uint16_t port);
+
+
+/**
+ * API to delete all OTM context from list.
+ * NOTE : This API should be invoked after OCStop API.
+ */
+void DeleteOTMContextList();
 
 #ifdef __cplusplus
 }
index 2df0540..1d0aa24 100644 (file)
@@ -31,7 +31,7 @@ extern "C" {
 #endif // __cplusplus\r
 \r
 #define OXM_STRING_MAX_LENGTH 32\r
-#define WRONG_PIN_MAX_ATTEMP 5\r
+#define WRONG_PIN_MAX_ATTEMP 1\r
 \r
 typedef struct OTMCallbackData OTMCallbackData_t;\r
 typedef struct OTMContext OTMContext_t;\r
@@ -123,6 +123,38 @@ OCStackResult OTMSetOwnershipTransferCallbackData(OicSecOxm_t oxm, OTMCallbackDa
  */\r
 OCStackResult OTMSetOTCallback(OicSecOxm_t oxm, OTMCallbackData_t* callbacks);\r
 \r
+/**\r
+ * Function to save the result of provisioning.\r
+ *\r
+ * @param[in,out] otmCtx   Context value of ownership transfer.\r
+ * @param[in] res   result of provisioning\r
+ */\r
+void SetResult(OTMContext_t* otmCtx, const OCStackResult res);\r
+\r
+/**\r
+ * Function to select appropriate security provisioning method.\r
+ *\r
+ * @param[in] supportedMethods   Array of supported methods\r
+ * @param[in] numberOfMethods   number of supported methods\r
+ * @param[out]  selectedMethod         Selected methods\r
+ * @param[in] ownerType type of owner device (SUPER_OWNER or SUB_OWNER)\r
+ * @return  OC_STACK_OK on success\r
+ */\r
+OCStackResult OTMSelectOwnershipTransferMethod(const OicSecOxm_t *supportedMethods,\r
+        size_t numberOfMethods, OicSecOxm_t *selectedMethod, OwnerType_t ownerType);\r
+\r
+/**\r
+ * This function configures SVR DB as self-ownership.\r
+ *\r
+ *@return OC_STACK_OK in case of successful configue and other value otherwise.\r
+ */\r
+OCStackResult ConfigSelfOwnership(void);\r
+\r
+/**\r
+ * API to terminate the OTM process when terminating OCStack\r
+ */\r
+void OTMTerminate();\r
+\r
 #ifdef __cplusplus\r
 }\r
 #endif\r
index e0dc2b0..7e41f53 100644 (file)
@@ -114,6 +114,15 @@ OCStackResult PDMUnlinkDevices(const OicUuid_t *uuidOfDevice1, const OicUuid_t *
 OCStackResult PDMDeleteDevice(const OicUuid_t *uuidOfDevice);
 
 /**
+ * This method is used by OTM & PDM to remove device information with device state.
+ *
+ * @param[in] state device state to be removed.
+ *
+ * @return OC_STACK_OK in case of success and other value otherwise.
+ */
+OCStackResult PDMDeleteDeviceWithState(const PdmDeviceState_t state);
+
+/**
  * This method is used by provisioning manager to get owned devices' Device IDs.
  *
  * @param[out] uuidList information about the list of owned devices' uuids.
index f828606..a66f546 100644 (file)
@@ -111,7 +111,7 @@ OCStackResult SRPSaveTrustCertChain(uint8_t *trustCertChain, size_t chainSize,
  * @param[out] credId CredId of saved trust certificate chain in Cred of SVR.
  * @return  OC_STACK_OK in case of success and other value otherwise.
  */
-OCStackResult SRPSaveOwnCertChain(OicSecCert_t * cert, OicSecKey_t * key, uint16_t *credId);
+OCStackResult SRPSaveOwnCertChain(OicSecKey_t * cert, OicSecKey_t * key, uint16_t *credId);
 
 /**
  * function to register callback, for getting notification for TrustCertChain change.
index 7cf06a1..b76512c 100644 (file)
 \r
 #include "octypes.h"\r
 #include "pmtypes.h"\r
+#include "casecurityinterface.h"\r
 #include "ownershiptransfermanager.h"\r
-#ifdef _ENABLE_MULTIPLE_OWNER_\r
+#ifdef MULTIPLE_OWNER\r
 #include "securevirtualresourcetypes.h"\r
-#endif //_ENABLE_MULTIPLE_OWNER_\r
+#endif //MULTIPLE_OWNER\r
 \r
 #ifdef __cplusplus\r
 extern "C" {\r
@@ -45,6 +46,19 @@ extern "C" {
 OCStackResult OCInitPM(const char* dbPath);\r
 \r
 /**\r
+ * API to termiante the provisioning manager\r
+ */\r
+void OCTerminatePM();\r
+\r
+/**\r
+ * API to cleanup PDM in case of timeout.\r
+ * It will remove the PDM_DEVICE_INIT state devices from PDM.\r
+ *\r
+ * @return OC_STACK_OK in case of success and other value otherwise.\r
+ */\r
+OCStackResult OCPDMCleanupForTimeout();\r
+\r
+/**\r
  * The function is responsible for discovery of owned/unowned device is specified endpoint/deviceID.\r
  * It will return the found device even though timeout is not exceeded.\r
  *\r
@@ -58,6 +72,23 @@ OCStackResult OCDiscoverSingleDevice(unsigned short timeout, const OicUuid_t* de
                              OCProvisionDev_t **ppFoundDevice);\r
 \r
 /**\r
+ * The function is responsible for discovery of owned/unowned device is specified endpoint/MAC\r
+ * address.\r
+ * It will return the found device even though timeout is not exceeded.\r
+ *\r
+ * @param[in] timeout Timeout in seconds, value till which function will listen to responses from\r
+ *                    server before returning the device.\r
+ * @param[in] deviceID         deviceID of target device.\r
+ * @param[in] hostAddress       MAC address of target device.\r
+ * @param[in] connType       ConnectivityType for discovery.\r
+ * @param[out] ppFoundDevice     OCProvisionDev_t of found device.\r
+ * @return OTM_SUCCESS in case of success and other value otherwise.\r
+ */\r
+OCStackResult OCDiscoverSingleDeviceInUnicast(unsigned short timeout, const OicUuid_t* deviceID,\r
+                             const char* hostAddress, OCConnectivityType connType,\r
+                             OCProvisionDev_t **ppFoundDevice);\r
+\r
+/**\r
  * The function is responsible for discovery of device is current subnet. It will list\r
  * all the device in subnet which are not yet owned. Please call OCInit with OC_CLIENT_SERVER as\r
  * OCMode.\r
@@ -91,7 +122,8 @@ OCStackResult OCDoOwnershipTransfer(void* ctx,
  */\r
 OCStackResult OCSetOxmAllowStatus(const OicSecOxm_t oxm, const bool allowStatus);\r
 \r
-#ifdef _ENABLE_MULTIPLE_OWNER_\r
+\r
+#ifdef MULTIPLE_OWNER\r
 /**\r
  * API to perfrom multiple ownership transfer for MOT enabled device.\r
  *\r
@@ -103,7 +135,36 @@ OCStackResult OCSetOxmAllowStatus(const OicSecOxm_t oxm, const bool allowStatus)
 OCStackResult OCDoMultipleOwnershipTransfer(void* ctx,\r
                                       OCProvisionDev_t *targetDevices,\r
                                       OCProvisionResultCB resultCallback);\r
-#endif //_ENABLE_MULTIPLE_OWNER_\r
+\r
+/**\r
+ * API to remove sub-owner from resource server\r
+ *\r
+ * @param[in] ctx Application context would be returned in result callback\r
+ * @param[in] targetDeviceInfo Selected target device.\r
+ * @param[in] subOwner sub-owner UUID to be removed\r
+ * @param[in] resultCallback callback provided by API user, callback will be invoked when\r
+ *            DELETE 'subowneruuid' request recieves a response from resource server.\r
+ * @return OC_STACK_OK in case of success and other value otherwise.\r
+ */\r
+OCStackResult OCRemoveSubOwner(void* ctx,\r
+                                const OCProvisionDev_t *targetDeviceInfo,\r
+                                const OicUuid_t* subOwner,\r
+                                OCProvisionResultCB resultCallback);\r
+\r
+/**\r
+ * API to remove all sub-owner from resource server\r
+ *\r
+ * @param[in] ctx Application context would be returned in result callback\r
+ * @param[in] targetDeviceInfo Selected target device.\r
+ * @param[in] resultCallback callback provided by API user, callback will be invoked when\r
+ *            DELETE 'subowneruuid' request recieves a response from resource server.\r
+ * @return OC_STACK_OK in case of success and other value otherwise.\r
+ */\r
+OCStackResult OCRemoveAllSubOwner(void* ctx,\r
+                                const OCProvisionDev_t *targetDeviceInfo,\r
+                                OCProvisionResultCB resultCallback);\r
+\r
+#endif //MULTIPLE_OWNER\r
 \r
 /**\r
  * API to register for particular OxM.\r
@@ -125,7 +186,7 @@ OCStackResult OCSetOwnerTransferCallbackData(OicSecOxm_t oxm, OTMCallbackData_t*
  */\r
 OCStackResult OCDiscoverOwnedDevices(unsigned short timeout, OCProvisionDev_t **ppList);\r
 \r
-#ifdef _ENABLE_MULTIPLE_OWNER_\r
+#ifdef MULTIPLE_OWNER\r
 /**\r
  * The function is responsible for discovery of MOT enabled device is current subnet.\r
  *\r
@@ -145,7 +206,7 @@ OCStackResult OCDiscoverMultipleOwnerEnabledDevices(unsigned short timeout, OCPr
  * @return OC_STACK_OK in case of success and other value otherwise.\r
  */\r
 OCStackResult OCDiscoverMultipleOwnedDevices(unsigned short timeout, OCProvisionDev_t **ppList);\r
-#endif //_ENABLE_MULTIPLE_OWNER_\r
+#endif //MULTIPLE_OWNER\r
 \r
 /**\r
  * API to provision credentials between two devices and ACLs for the devices who act as a server.\r
@@ -239,7 +300,7 @@ OCStackResult OCProvisionCredentials(void *ctx, OicSecCredType_t type, size_t ke
                                       const OCProvisionDev_t *pDev2,\r
                                       OCProvisionResultCB resultCallback);\r
 \r
-#ifdef _ENABLE_MULTIPLE_OWNER_\r
+#ifdef MULTIPLE_OWNER\r
 /**\r
  * API to provision preconfigured PIN to device(NOT LIST).\r
  * If device does not support the Preconfigured PIN OxM,\r
@@ -295,7 +356,7 @@ OCStackResult OCChangeMOTMode(void *ctx, const OCProvisionDev_t *targetDeviceInf
  */\r
 OCStackResult OCSelectMOTMethod(void *ctx, const OCProvisionDev_t *targetDeviceInfo,\r
                                  const OicSecOxm_t oxmSelValue, OCProvisionResultCB resultCallback);\r
-#endif //_ENABLE_MULTIPLE_OWNER_\r
+#endif //MULTIPLE_OWNER\r
 \r
 /**\r
  * Function to unlink devices.\r
@@ -363,6 +424,20 @@ OCStackResult OCResetDevice(void* ctx, unsigned short waitTimeForOwnedDeviceDisc
                             OCProvisionResultCB resultCallback);\r
 \r
 /**\r
+ * This function resets SVR DB to its factory setting.\r
+ *\r
+ *@return OC_STACK_OK in case of successful reset and other value otherwise.\r
+ */\r
+OCStackResult OCResetSVRDB(void);\r
+\r
+/**\r
+ * This function configures SVR DB as self-ownership.\r
+ *\r
+ *@return OC_STACK_OK in case of successful configue and other value otherwise.\r
+ */\r
+OCStackResult OCConfigSelfOwnership(void);\r
+\r
+/**\r
  * API to get status of all the devices in current subnet. The status include endpoint information\r
  * and doxm information which can be extracted duing owned and unowned discovery. Along with this\r
  * information. The API will provide information about devices' status\r
@@ -424,19 +499,6 @@ void OCDeletePdAclList(OicSecPdAcl_t* pPdAcl);
 \r
 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)\r
 /**\r
- * this function sends CRL information to resource.\r
- *\r
- * @param[in] ctx Application context would be returned in result callback.\r
- * @param[in] selectedDeviceInfo Selected target device.\r
- * @param[in] crl CRL to provision.\r
- * @param[in] resultCallback callback provided by API user, callback will be called when provisioning\r
-              request recieves a response from resource server.\r
- * @return  OC_STACK_OK in case of success and other value otherwise.\r
- */\r
-OCStackResult OCProvisionCRL(void* ctx, const OCProvisionDev_t *selectedDeviceInfo, OicSecCrl_t *crl,\r
-                             OCProvisionResultCB resultCallback);\r
-\r
-/**\r
  * function to provision Trust certificate chain to devices.\r
  *\r
  * @param[in] ctx Application context would be returned in result callback.\r
@@ -485,6 +547,23 @@ void OCRemoveTrustCertChainNotifier(void);
 OCStackResult OCReadTrustCertChain(uint16_t credId, uint8_t **trustCertChain,\r
                                      size_t *chainSize);\r
 \r
+/**\r
+ * Function to select appropriate security provisioning method.\r
+ *\r
+ * @param[in] supportedMethods   Array of supported methods\r
+ * @param[in] numberOfMethods   number of supported methods\r
+ * @param[out]  selectedMethod         Selected methods\r
+ * @param[in] ownerType type of owner device (SUPER_OWNER or SUB_OWNER)\r
+ * @return  OC_STACK_OK on success\r
+ */\r
+OCStackResult OCSelectOwnershipTransferMethod(const OicSecOxm_t *supportedMethods,\r
+        size_t numberOfMethods, OicSecOxm_t *selectedMethod, OwnerType_t ownerType);\r
+\r
+/**\r
+ * This function sets the callback to utilize peer certificate information\r
+ */\r
+OCStackResult OCSetPeerCertCallback(void *ctx, PeerCertCallback peerCertCallback);\r
+\r
 #endif // __WITH_DTLS__ || __WITH_TLS__\r
 \r
 \r
index 0b9f81e..f2fc932 100644 (file)
@@ -74,6 +74,20 @@ OCStackResult CreateJustWorksSelectOxmPayload(OTMContext_t *otmCtx, uint8_t **cb
  */
 OCStackResult CreateJustWorksOwnerTransferPayload(OTMContext_t *otmCtx, uint8_t **cborPayload,
                                                   size_t *cborSize);
+
+/**
+ * Generate payload for select OxM request for Mutual Verified Just-Works.
+ *
+ * @param otmCtx Context of OTM, It includes current device information.
+ * @param cborPayload is the DOXM CBOR payload including the selected OxM.
+ * @note Returned memory should be deallocated by caller.
+ * @param cborSize is the size of the cborPayload.
+ *
+ * @return ::OC_STACK_SUCCESS in case of success and other value otherwise.
+ */
+OCStackResult CreateMVJustWorksSelectOxmPayload(OTMContext_t *otmCtx, uint8_t **cborPayload,
+                                             size_t *cborSize);
+
 #ifdef __cplusplus
 }
 #endif
index 0a9bca7..cff6467 100644 (file)
@@ -62,6 +62,19 @@ OCStackResult CreateMCertificateBasedSelectOxmPayload(OTMContext_t *otmCtx, uint
                                              size_t *cborSize);
 
 /**
+ * Generate payload for select OxM request for confirmed manufactrer certificate method.
+ *
+ * @param otmCtx Context of OTM, It includes current device information.
+ * @param cborPayload is the DOXM CBOR payload including the selected OxM.
+ * @note Returned memory should be deallocated by caller.
+ * @param cborSize is the size of the cborPayload.
+ *
+ * @return ::OC_STACK_SUCCESS in case of success and other value otherwise.
+ */
+OCStackResult CreateConMCertificateBasedSelectOxmPayload(OTMContext_t *otmCtx, uint8_t **cborPayload,
+                                             size_t *cborSize);
+
+/**
  * Generate payload for owner transfer request.
  *
  * @param otmCtx Context of OTM, It includes current device information.
index 1a5f8cb..6a46dd6 100644 (file)
@@ -70,7 +70,7 @@ typedef struct OCProvisionDev
 #ifdef WITH_TCP
     uint16_t        tcpPort;         /**< tcp port **/
 #endif
-    char             secVer[MAX_VERSION_LEN];         /**< security version **/
+    char             secVer[OIC_SEC_MAX_VER_LEN];         /**< security version **/
     DeviceStatus    devStatus;       /**< status of device **/
     OCDoHandle    handle;
     struct OCProvisionDev  *next;    /**< Next pointer. **/
@@ -101,6 +101,31 @@ typedef struct OCPMResult{
 }OCProvisionResult_t;
 
 /**
+ * Owner device type
+ */
+typedef enum OwnerType{
+    SUPER_OWNER = 0,
+    SUB_OWNER = 1
+}OwnerType_t;
+
+/**
+ * Index value to access OxM allow table
+ */
+typedef enum OxmAllowTableIdx {
+    OXM_IDX_JUST_WORKS = 0,
+    OXM_IDX_MV_JUST_WORKS,
+#ifdef MULTIPLE_OWNER
+    OXM_IDX_PRECONFIG_PIN,
+#endif
+    OXM_IDX_RANDOM_DEVICE_PIN,
+    OXM_IDX_MANUFACTURER_CERTIFICATE,
+    OXM_IDX_CON_MFG_CERT,
+    OXM_IDX_DECENTRALIZED_PUBLIC_KEY,
+    OXM_IDX_COUNT,
+    OXM_IDX_UNKNOWN
+}OxmAllowTableIdx_t;
+
+/**
  * Callback function definition of provisioning API
  *
  * @param[OUT] ctx - If user set his/her context, it will be returned here.
index 897ee94..f192d8c 100644 (file)
@@ -57,6 +57,23 @@ OCStackResult PMSingleDeviceDiscovery(unsigned short waittime, const OicUuid_t*
                                  OCProvisionDev_t **ppFoundDevice);
 
 /**
+ * Discover owned/unowned device in the specified endpoint/MAC address.
+ * It will return the found device even though timeout is not exceeded.
+ *
+ * @param[in] waittime           Timeout in seconds.
+ * @param[in] deviceID           deviceID of target device.
+ * @param[in] hostAddress       MAC address of target device.
+ * @param[in] connType       ConnectivityType for discovery.
+ * @param[out] ppFoundDevice     OCProvisionDev_t of found device.
+ *
+ * @return OC_STACK_OK on success otherwise error.
+ *         OC_STACK_INVALID_PARAM when deviceID is NULL or ppFoundDevice is not initailized.
+ */
+OCStackResult PMSingleDeviceDiscoveryInUnicast(unsigned short waittime, const OicUuid_t* deviceID,
+                        const char* hostAddress, OCConnectivityType connType,
+                        OCProvisionDev_t **ppFoundDevice);
+
+/**
  * Discover owned/unowned devices in the same IP subnet. .
  *
  * @param[in] waittime      Timeout in seconds.
@@ -67,7 +84,7 @@ OCStackResult PMSingleDeviceDiscovery(unsigned short waittime, const OicUuid_t*
  */
 OCStackResult PMDeviceDiscovery(unsigned short waittime, bool isOwned, OCProvisionDev_t **ppList);
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 /**
  * Discover multiple OTM enabled devices in the same IP subnet.
  *
@@ -78,7 +95,7 @@ OCStackResult PMDeviceDiscovery(unsigned short waittime, bool isOwned, OCProvisi
  * @return OC_STACK_OK on success otherwise error.
  */
 OCStackResult PMMultipleOwnerDeviceDiscovery(unsigned short waittime, bool isMultipleOwned, OCProvisionDev_t **ppDevicesList);
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
 /**
  * This function deletes list of provision target devices
index 1ec4546..bfdfba7 100644 (file)
@@ -49,14 +49,15 @@ provisioning_env.AppendUnique(CPPPATH = [
                '../include/oxm',
                '../include/cloud',
                '../../include',
-               '../../../../../extlibs/tinydtls',
                '../../../../../extlibs/cjson',
                '../../../../../extlibs/base64',
+               '../../../../../extlibs/mbedtls/mbedtls/include',
                '../../../connectivity/inc',
                '../../../connectivity/inc/pkix',
                '../../../connectivity/common/inc',
                '../../../connectivity/api',
-               'cloud'
+               'cloud',
+               'hw_emul'
                ])
 
 target_os = env.get('TARGET_OS')
@@ -87,7 +88,7 @@ if env.get('SECURED') == '1':
 
 
 if env.get('MULTIPLE_OWNER') == '1':
-       provisioning_env.AppendUnique(CPPDEFINES = ['_ENABLE_MULTIPLE_OWNER_'])
+       provisioning_env.AppendUnique(CPPDEFINES = ['MULTIPLE_OWNER'])
 
 provisioning_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
 
@@ -100,13 +101,19 @@ if target_os in ['linux', 'tizen']:
 # Source files and Targets
 ######################################################################
 
-provisioningclient = provisioning_env.Program('provisioningclient', 'provisioningclient.c')
+hwemul_src = [
+       'hw_emul/hw_interface.c',
+       'hw_emul/ss_emul.c']
+provisioningclient = provisioning_env.Program('provisioningclient', hwemul_src + ['provisioningclient.c'])
 sampleserver_justworks = provisioning_env.Program('sampleserver_justworks', 'sampleserver_justworks.cpp')
+sampleserver_justworks_protectedDB = provisioning_env.Program('sampleserver_justworks_protectedDB', 'sampleserver_justworks_protectedDB.cpp')
 sampleserver_randompin = provisioning_env.Program('sampleserver_randompin', 'sampleserver_randompin.cpp')
-sampleserver_mfg = provisioning_env.Program('sampleserver_mfg', 'sampleserver_mfg.cpp')
+sampleserver_mfg = provisioning_env.Program('sampleserver_mfg', hwemul_src + ['sampleserver_mfg.cpp'])
+sampleserver_mvjustworks = provisioning_env.Program('sampleserver_mvjustworks', 'sampleserver_mvjustworks.cpp')
 
 if provisioning_env.get('MULTIPLE_OWNER') == '1':
        subownerclient = provisioning_env.Program('subownerclient', 'subownerclient.c')
+       sampleserver_preconfpin = provisioning_env.Program('sampleserver_preconfpin', 'sampleserver_preconfpin.cpp')
 
 if provisioning_env.get('WITH_TCP') == True:
     cloud_src = [
@@ -114,8 +121,8 @@ if provisioning_env.get('WITH_TCP') == True:
         'cloud/cloudCommon.c',
         'cloud/cloudWrapper.c',
         'cloud/cloudDiscovery.c']
-    cloudClient = provisioning_env.Program('cloudClient', cloud_src + ['cloudClient.c'])
-    cloudServer = provisioning_env.Program('cloudServer', cloud_src + ['cloudServer.c', 'cloud/cloudResource.c'])
+    cloudClient = provisioning_env.Program('cloudClient', hwemul_src + cloud_src + ['cloudClient.c'])
+    cloudServer = provisioning_env.Program('cloudServer', hwemul_src + cloud_src + ['cloudServer.c', 'cloud/cloudResource.c'])
 
 src_dir = provisioning_env.get('SRC_DIR')
 sec_provisioning_src_dir = src_dir + '/resource/csdk/security/provisioning/sample/'
@@ -126,16 +133,25 @@ clientdat = provisioning_env.Install(sec_provisioning_build_dir,
                                         sec_provisioning_src_dir + 'oic_svr_db_client.dat')
 justworksdat = provisioning_env.Install(sec_provisioning_build_dir,
                                     sec_provisioning_src_dir + 'oic_svr_db_server_justworks.dat')
+justworksDefaultdat = provisioning_env.Install(sec_provisioning_build_dir,
+                                    sec_provisioning_src_dir + 'oic_svr_db_server_justworks_default.dat')
+justworksProtectedDBdat_plain = provisioning_env.Install(sec_provisioning_build_dir,
+                                    sec_provisioning_src_dir + 'oic_svr_db_server_justworks_protectedDB_plain.dat')
+
 randompindat = provisioning_env.Install(sec_provisioning_build_dir,
                                     sec_provisioning_src_dir+ 'oic_svr_db_server_randompin.dat')
 mfgdat = provisioning_env.Install(sec_provisioning_build_dir,
                                     sec_provisioning_src_dir+ 'oic_svr_db_server_mfg.dat')
 randompin_with_emptyuuid_dat = provisioning_env.Install(sec_provisioning_build_dir,
                                     sec_provisioning_src_dir+ 'oic_svr_db_randompin_with_empty_deviceid.dat')
+mvjustworksdat = provisioning_env.Install(sec_provisioning_build_dir,
+                                                                       sec_provisioning_src_dir + 'oic_svr_db_server_mvjustworks.dat')
 
 if provisioning_env.get('MULTIPLE_OWNER') == '1':
        subownerclientdat = provisioning_env.Install(sec_provisioning_build_dir,
                                                sec_provisioning_src_dir + 'oic_svr_db_subowner_client.dat')
+       preconfserverdat = provisioning_env.Install(sec_provisioning_build_dir,
+                                               sec_provisioning_src_dir + 'oic_svr_db_server_preconfpin.dat')
 
 if provisioning_env.get('WITH_TCP') == True:
     clouddat = provisioning_env.Install(sec_provisioning_build_dir,
@@ -149,15 +165,18 @@ if provisioning_env.get('MULTIPLE_OWNER') == '1':
        Alias("samples", [
                                        provisioningclient, subownerclient,
                                        sampleserver_justworks, sampleserver_randompin, sampleserver_mfg,
-                                       clientdat, subownerclientdat,
-                                       justworksdat, randompindat, mfgdat, randompin_with_emptyuuid_dat
+                                       sampleserver_preconfpin,sampleserver_justworks_protectedDB,
+                                       clientdat, subownerclientdat, preconfserverdat,
+                                       justworksdat, randompindat, mfgdat, randompin_with_emptyuuid_dat,
+                                       mvjustworksdat, justworksDefaultdat, justworksProtectedDBdat_plain
                                ])
 else:
        Alias("samples", [
                                        provisioningclient,
                                        sampleserver_justworks, sampleserver_randompin, sampleserver_mfg,
-                                       clientdat,
-                                       justworksdat, randompindat, mfgdat, randompin_with_emptyuuid_dat
+                                       clientdat,sampleserver_justworks_protectedDB,
+                                       justworksdat, randompindat, mfgdat, randompin_with_emptyuuid_dat,
+                                       mvjustworksdat, justworksDefaultdat, justworksProtectedDBdat_plain
                                ])
 
 provisioning_env.AppendTarget('samples')
index a14a7e5..46524d6 100644 (file)
@@ -200,6 +200,8 @@ OCStackResult CloudSignUp(const OCDevAddr *endPoint,
     OCRepPayloadSetPropString(payload, OC_RSRVD_AUTHPROVIDER, authProvider);
     OCRepPayloadSetPropString(payload, OC_RSRVD_AUTHCODE, authToken);
 
+    OICFree(deviceId);
+
     return OCDoResource(NULL, OC_REST_POST, uri, NULL, (OCPayload *)payload,
                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
 }
@@ -301,6 +303,8 @@ static OCStackResult CloudSign(const OCDevAddr *endPoint, bool signIn)
     OCRepPayloadSetPropString(payload, OC_RSRVD_ACCESS_TOKEN, sessionObject.accesstoken);
     OCRepPayloadSetPropBool(payload, OC_RSRVD_LOGIN, signIn);
 
+    OICFree(deviceId);
+
     char uri[MAX_URI_QUERY] = { 0 };
     snprintf(uri, MAX_URI_QUERY, DEFAULT_QUERY,
              endPoint->addr, endPoint->port,
index ce7f7e1..d4913b5 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <pthread.h>
 
 #include "ocstack.h"
 #include "logger.h"
-#include "camutex.h"
+#include "octhread.h"
 #include "cathreadpool.h"
 #include "ocpayload.h"
 #include "payload_logging.h"
@@ -32,6 +33,8 @@
 #include "ocprovisioningmanager.h"
 #include "casecurityinterface.h"
 #include "mbedtls/ssl_ciphersuites.h"
+#include "pkix_interface.h"
+#include "../hw_emul/hw_interface.h"
 
 #include "utils.h"
 #include "cloudAuth.h"
@@ -65,8 +68,8 @@ static char *fname = DEFAULT_DB_FILE;
 static uint64_t timeout;
 static uint16_t g_credId = 0;
 
-static ca_cond cond;
-static ca_mutex mutex;
+static oc_cond cond;
+static oc_mutex mutex;
 
 typedef enum {
     SIGN_UP       = 1,
@@ -80,6 +83,8 @@ typedef enum {
     USE_RSA = 8,
     SAVE_TRUST_CERT = 9,
     USE_SECURE_CONN = 10,
+    CONFIG_SELF_OWNERSHIP = 11,
+    SECURE_STORAGE_HW_EMULATION = 12,
 
     DISCOVERY     = 13,
     GET           = 14,
@@ -144,6 +149,8 @@ static void printMenu(OCMode mode)
     printf("** %d - Change TLS cipher suite (ECDSA/RSA)\n", USE_RSA);
     printf("** %d - Save Trust Cert. Chain into Cred of SVR\n", SAVE_TRUST_CERT);
     printf("** %d - Change Protocol type (CoAP/CoAPs)\n", USE_SECURE_CONN);
+    printf("** %d - Configure SVRdb as Self-OwnerShip\n", CONFIG_SELF_OWNERSHIP);
+    printf("** %d - Configure Secure Storage HW Emulation\n", SECURE_STORAGE_HW_EMULATION);
 
     if (OC_CLIENT == mode)
     {
@@ -205,9 +212,9 @@ void unlockMenu(void *data)
 
     if (!fExit)
     {
-        ca_mutex_lock(mutex);
-        ca_cond_signal(cond);
-        ca_mutex_unlock(mutex);
+        oc_mutex_lock(mutex);
+        oc_cond_signal(cond);
+        oc_mutex_unlock(mutex);
     }
 }
 
@@ -334,18 +341,18 @@ static OCStackResult saveTrustCert(void)
     OCStackResult res = OC_STACK_ERROR;
     OIC_LOG(INFO, TAG, "Save Trust Cert. Chain into Cred of SVR");
 
-    ByteArray_t trustCertChainArray = {0, 0};
+    OCByteString trustCertChainArray = {0, 0};
     const char *filename = "rootca.crt";
 
-    if (!readFile(filename, (OCByteString *)&trustCertChainArray))
+    if (!readFile(filename, &trustCertChainArray))
     {
         OIC_LOG_V(ERROR, TAG, "Can't read %s file", filename);
-        OICFree(((OCByteString *)&trustCertChainArray)->bytes);
+        OICFree(trustCertChainArray.bytes);
         return OC_STACK_ERROR;
     }
-    OIC_LOG_BUFFER(DEBUG, TAG, trustCertChainArray.data, trustCertChainArray.len);
+    OIC_LOG_BUFFER(DEBUG, TAG, trustCertChainArray.bytes, trustCertChainArray.len);
 
-    res = OCSaveTrustCertChain(trustCertChainArray.data, trustCertChainArray.len, OIC_ENCODING_PEM,&g_credId);
+    res = OCSaveTrustCertChain(trustCertChainArray.bytes, trustCertChainArray.len, OIC_ENCODING_PEM,&g_credId);
 
     if (OC_STACK_OK != res)
     {
@@ -355,11 +362,86 @@ static OCStackResult saveTrustCert(void)
     {
         OIC_LOG_V(INFO, TAG, "CredId of Saved Trust Cert. Chain into Cred of SVR : %d.\n", g_credId);
     }
-    OICFree(trustCertChainArray.data);
+    OICFree(trustCertChainArray.bytes);
 
     return res;
 }
 
+static OCStackResult configSelfOwnership(void)
+{
+    OCStackResult res = OC_STACK_ERROR;
+    OIC_LOG(INFO, TAG, "Configures SVR DB as self-ownership.");
+
+    res = OCConfigSelfOwnership();
+
+    if (OC_STACK_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "OCConfigSelfOwnership API error. Please check SVR DB");
+    }
+    else
+    {
+        OIC_LOG(INFO, TAG, "Success to configures SVR DB as self-ownership");
+    }
+
+    return res;
+}
+
+static void configSecureStorageHwEmulation()
+{
+    OIC_LOG(INFO, TAG, "Enable Secure Storage HW Emulation");
+
+    printf("         Enter Own Certificate File Path[~4095]: ");
+    char cert_filepath[4096] = {0,};
+    for(int ret=0; 1!=ret; )
+    {
+        ret = scanf("%255s", cert_filepath);
+        for( ; 0x20<=getchar(); );  // for removing overflow garbages
+                                    // '0x20<=code' is character region
+    }
+
+    printf("         Enter Private Key File Path[~4095]: ");
+    char key_filepath[4096] = {0,};
+    for(int ret=0; 1!=ret; )
+    {
+        ret = scanf("%255s", key_filepath);
+        for( ; 0x20<=getchar(); );  // for removing overflow garbages
+                                    // '0x20<=code' is character region
+    }
+
+    printf("         Enter Password for Key Password[~31][Press (Enter) to not set]: ");
+    char pwd[32] = {0,};
+    for(int i=0; i < 31; i++)
+    {
+        pwd[i] = (char)getchar();
+        if (0x20 <= pwd[i])
+        {
+            pwd[i--] = '\0';
+            continue;
+        }
+        if (0x0A == pwd[i])
+        {
+            pwd[i] = '\0';
+            break;
+        }
+    }
+
+    if (0 != SSemulSetCertkeyFilepath(cert_filepath, key_filepath, pwd))
+    {
+        OIC_LOG(ERROR, TAG, "    Fail to set cert/key file path");
+        return;
+    }
+
+    if (0 != SetHwPkixCallbacks(HWGetKeyContext,
+                                                  HWFreeKeyContext,
+                                                  HWGetOwnCertificateChain,
+                                                  HWSetupPkContext))
+    {
+        OIC_LOG(ERROR, TAG, "    Fail to regist HW Pkix Callbacks");
+        return;
+    }
+    OIC_LOG(INFO, TAG, "    Success to regist HW Pkix Callbacks");
+}
+
 static void wrongRequest()
 {
     printf(">> Entered Wrong Menu Number. Please Enter Again\n\n");
@@ -379,8 +461,8 @@ static void userRequests(void *data)
     strncpy(endPoint.addr, DEFAULT_HOST, sizeof(endPoint.addr));
     endPoint.port = DEFAULT_PORT;
 
-    mutex = ca_mutex_new();
-    cond = ca_cond_new();
+    mutex = oc_mutex_new();
+    cond = oc_cond_new();
 
     while (false == fExit)
     {
@@ -522,7 +604,7 @@ static void userRequests(void *data)
         {
             int tmp = 0;
             readInteger(&tmp, "Select Cipher Suite", "0 - ECDSA, other - RSA");
-            uint16_t cipher = tmp? MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA:
+            uint16_t cipher = tmp? MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256:
                                    MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8;
             if (CA_STATUS_OK != CASelectCipherSuite(cipher, CA_ADAPTER_TCP))
             {
@@ -543,9 +625,17 @@ static void userRequests(void *data)
             sendDataToServer = false;
         }
             break;
+        case CONFIG_SELF_OWNERSHIP:
+            configSelfOwnership();
+            sendDataToServer = false;
+            break;
+        case SECURE_STORAGE_HW_EMULATION:
+            configSecureStorageHwEmulation();
+            sendDataToServer = false;
+            break;
         case EXIT:
-            ca_mutex_free(mutex);
-            ca_cond_free(cond);
+            oc_mutex_free(mutex);
+            oc_cond_free(cond);
             fExit = true;
             sendDataToServer = false;
             break;
@@ -560,9 +650,9 @@ static void userRequests(void *data)
         {
             if (OC_STACK_OK == res)
             {
-                ca_mutex_lock(mutex);
-                ca_cond_wait_for(cond, mutex, timeout);
-                ca_mutex_unlock(mutex);
+                oc_mutex_lock(mutex);
+                oc_cond_wait_for(cond, mutex, timeout);
+                oc_mutex_unlock(mutex);
             }
             else
             {
@@ -627,7 +717,7 @@ bool parseCommandLineArguments(int argc, char *argv[])
 OCStackResult initPersistentStorage()
 {
     //Initialize Persistent Storage for SVR database
-    static OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink};
+    static OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink, NULL, NULL};
 
     return OCRegisterPersistentStorageHandler(&ps);
 }
@@ -641,7 +731,7 @@ OCStackResult startRequestsThread(OCMode *mode)
         return res;
     }
 
-    res = ca_thread_pool_add_task(g_threadPoolHandle, userRequests, mode);
+    res = ca_thread_pool_add_task(g_threadPoolHandle, userRequests, mode, NULL);
     if (CA_STATUS_OK != res)
     {
         OIC_LOG(ERROR, TAG, "thread pool add task error.");
@@ -657,6 +747,10 @@ OCStackResult initProcess(OCMode mode)
 
 void startProcess()
 {
+    struct timespec timeout;
+    timeout.tv_sec  = 0;
+    timeout.tv_nsec = 100000000L;
+
     while(false == fExit)
     {
         if (OCProcess() != OC_STACK_OK)
@@ -664,6 +758,7 @@ void startProcess()
             OIC_LOG(ERROR, TAG,"OCProcess process error, exit\n");
             break;
         }
+        nanosleep(&timeout, NULL);
     }
 
     if (OCStop() != OC_STACK_OK)
index 4e8878a..f55f967 100644 (file)
@@ -1,24 +1,24 @@
-/*
- * //******************************************************************
- * //
- * // Copyright 2016 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.
- * //
- * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
+/* *****************************************************************
+ *
+ * Copyright 2016 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 "ocstack.h"
 #include "logger.h"
 #include "ocpayload.h"
index f044be7..7702c3d 100644 (file)
@@ -67,12 +67,16 @@ static bool readOptional(const char* description)
     }
 
     printf("Do you want to Enter %s (y/n):\n", description);
-    char choice = 0;
+    char temp, choice = 0;
 
     while(1)
     {
-        scanf("%c", &choice);
-        skipSpecialCharacters();
+        for(int ret = 0; 1 != ret; )
+        {
+            ret = scanf("%c", &temp);
+            skipSpecialCharacters();
+        }
+        choice = temp;
 
         switch (choice)
         {
@@ -86,11 +90,24 @@ static bool readOptional(const char* description)
 
 void readString(char* item, int length, const char* description, const char* example)
 {
+    char *temp = (char*)OICCalloc(length, sizeof(char));
+    if (NULL == temp)
+    {
+        OIC_LOG(INFO, TAG, "temp is NULL");
+        return;
+    }
+
     printf("Enter %s (f.e. %s):\n", description, example);
     char template[8] = { 0 };
     snprintf(template, sizeof(template), "%%%ds", length - 1);
-    scanf(template, item);
-    skipSpecialCharacters();
+
+    for(int ret = 0; 1 != ret; )
+    {
+        ret = scanf(template, temp);
+        skipSpecialCharacters();
+    }
+    strncpy(item, temp, length);
+    OICFree(temp);
 }
 
 /**
@@ -111,9 +128,16 @@ static void readOptionalString(char* item, int length, const char* description,
 
 void readInteger(int* item, const char* description, const char* example)
 {
+    int temp;
+
     printf("Enter %s (f.e. %s):\n", description, example);
-    scanf("%d", item);
-    skipSpecialCharacters();
+
+    for(int ret = 0; 1 != ret; )
+    {
+        ret = scanf("%d", &temp);
+        skipSpecialCharacters();
+    }
+    *item = temp;
 }
 
 /**
diff --git a/resource/csdk/security/provisioning/sample/hw_emul/hw_interface.c b/resource/csdk/security/provisioning/sample/hw_emul/hw_interface.c
new file mode 100644 (file)
index 0000000..3f87c0c
--- /dev/null
@@ -0,0 +1,348 @@
+/* *****************************************************************\r
+ *\r
+ * Copyright 2017 Samsung Electronics All Rights Reserved.\r
+ *\r
+ *\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * *****************************************************************/\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+#include "ocstack.h"\r
+#include "oic_malloc.h"\r
+#include "logger.h"\r
+#include "mbedtls/pk_internal.h"\r
+#include "hw_interface.h"\r
+\r
+\r
+#define TAG "OIC_HWIF"\r
+\r
+#define HWIF_KEY_DEFAULT_ALIAS "HW_KEY_DEFAULT"\r
+#define HWIF_KEY_CONTEXT HWIF_KEY_DEFAULT_ALIAS\r
+#define HWIF_RSA_ALIAS HWIF_KEY_DEFAULT_ALIAS\r
+\r
+// own cert chain cache\r
+uint8_t* g_ownCert = NULL;\r
+size_t g_ownCertLen = 0;\r
+\r
+/********************************************\r
+ * RSA alternative functions\r
+ */\r
+\r
+static int RsaDecryptAlt(void *ctx, int mode, size_t *olen,\r
+                                    const unsigned char *input, unsigned char *output,\r
+                                    size_t output_max_len )\r
+{\r
+    (void)ctx;\r
+    (void)mode;\r
+    (void)olen;\r
+    (void)input;\r
+    (void)output;\r
+    (void)output_max_len;\r
+\r
+    OIC_LOG_V(INFO, TAG, "In %s", __func__);\r
+    OIC_LOG_V(INFO, TAG, "Out %s", __func__);\r
+    return 0;\r
+}\r
+\r
+static int RsaSignAlt(void *ctx,\r
+                                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,\r
+                                    int mode, mbedtls_md_type_t md_alg, unsigned int hashlen,\r
+                                    const unsigned char *hash, unsigned char *sig )\r
+{\r
+    OIC_LOG_V(INFO, TAG, "In %s", __func__);\r
+\r
+    if(!ctx || 0 != strncmp((const char*)(ctx), HWIF_RSA_ALIAS, strlen(HWIF_RSA_ALIAS)))\r
+    {\r
+        OIC_LOG(ERROR, TAG, "Invalid paramters, ctx must has same key id");\r
+        OIC_LOG_V(INFO, TAG, "Out %s", __func__);\r
+        return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;\r
+    }\r
+\r
+    if(mode != MBEDTLS_RSA_PRIVATE)\r
+    {\r
+        OIC_LOG(ERROR, TAG, "Invalid mode requested");\r
+        OIC_LOG_V(INFO, TAG, "Out %s", __func__);\r
+        return MBEDTLS_ERR_PK_BAD_INPUT_DATA;\r
+    }\r
+\r
+    // RSA encryption with hw stored private key\r
+    int ret = SSemulRsaSign(ctx, f_rng, p_rng, mode, md_alg, hashlen, hash, sig);\r
+    if(0 != ret )\r
+    {\r
+        OIC_LOG_V(ERROR, TAG, "Fail to RSA sign [0x%x]", ret);\r
+        goto exit;\r
+    }\r
+    OIC_LOG_V(INFO, TAG, "Success to RSA sign");\r
+\r
+exit:\r
+    OIC_LOG_V(INFO, TAG, "Out %s", __func__);\r
+    return ret;\r
+}\r
+\r
+static size_t RsaKeyLen( void *ctx )\r
+{\r
+    OIC_LOG_V(INFO, TAG, "In %s", __func__);\r
+\r
+    if(!ctx || 0 != strncmp((const char*)(ctx), HWIF_RSA_ALIAS, strlen(HWIF_RSA_ALIAS)))\r
+    {\r
+        OIC_LOG(ERROR, TAG, "Invalid paramters, ctx must has same key id");\r
+        OIC_LOG_V(INFO, TAG, "Out %s", __func__);\r
+        return 0;\r
+    }\r
+\r
+    // Load private key length from HW Secure Storage\r
+    int ret = SSemulGetKeylen(ctx);\r
+    if (0 >= ret)\r
+    {\r
+        OIC_LOG_V(ERROR, TAG, "Fail to load key length [0x%x]", ret);\r
+        goto exit;\r
+    }\r
+\r
+    OIC_LOG_V(INFO, TAG, "key length : %d", ret);\r
+\r
+exit:\r
+    OIC_LOG_V(INFO, TAG, "Out %s", __func__);\r
+    return (size_t)ret;\r
+}\r
+\r
+\r
+/********************************************\r
+ * ECDSA alternative functions\r
+ */\r
+\r
+static int EcdsaSignAlt( void *ctx, mbedtls_md_type_t md_alg,\r
+                   const unsigned char *hash, size_t hash_len,\r
+                   unsigned char *sig, size_t *sig_len,\r
+                   int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )\r
+{\r
+    (void)ctx;\r
+    OIC_LOG_V(INFO, TAG, "In %s", __func__);\r
+\r
+    OIC_LOG_V(ERROR, TAG, "hash_len : %zu md_alg : %d", hash_len, md_alg);\r
+\r
+    // ECDSA signing with hw stored private key\r
+    int ret = SSemulEcdsaSign(ctx, md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng);\r
+    if(0 != ret )\r
+    {\r
+        OIC_LOG_V(ERROR, TAG, "Fail to ECDSA sign [0x%x]", ret);\r
+        goto exit;\r
+    }\r
+    OIC_LOG_V(INFO, TAG, "Success to ECDSA sign");\r
+\r
+    OIC_LOG_V(DEBUG, TAG, "# [hash - %zu bytes] #", hash_len);\r
+    OIC_LOG_BUFFER(DEBUG, TAG, hash, hash_len);\r
+    OIC_LOG_V(DEBUG, TAG, "# [signature - %zu bytes] #", *sig_len);\r
+    OIC_LOG_BUFFER(DEBUG, TAG, sig, *sig_len);\r
+\r
+exit:\r
+    OIC_LOG_V(INFO, TAG, "Out %s", __func__);\r
+    return ret;\r
+}\r
+\r
+\r
+/********************************************\r
+ * mbedtls pk setup fucntions\r
+ */\r
+\r
+int SetupRSAContext(mbedtls_pk_context* ctx, void* key_context)\r
+{\r
+    OIC_LOG_V(INFO, TAG, "In %s", __func__);\r
+    int ret = HWIF_SUCCESS;\r
+\r
+    if(NULL == ctx || NULL == key_context)\r
+    {\r
+        OIC_LOG(ERROR, TAG, "Invalid input parameters.");\r
+        ret = HWIF_ERR_INVALID_PARAM;\r
+        goto exit;\r
+    }\r
+\r
+    ret = mbedtls_pk_setup_rsa_alt( ctx, HWIF_RSA_ALIAS,\r
+                            RsaDecryptAlt, RsaSignAlt, RsaKeyLen);\r
+    if(0 != ret)\r
+    {\r
+        OIC_LOG_V(ERROR, TAG, "Failed to setup rsa alt [%d]", ret);\r
+        ret = HWIF_ERROR;\r
+        goto exit;\r
+    }\r
+\r
+    OIC_LOG(INFO, TAG, "Success to setup RSA alt");\r
+\r
+exit:\r
+    OIC_LOG_V(INFO, TAG, "Out %s", __func__);\r
+    return ret;\r
+}\r
+\r
+int SetupECDSAContext(mbedtls_pk_context* ctx, void* key_context)\r
+{\r
+    OIC_LOG_V(INFO, TAG, "In %s", __func__);\r
+    int ret = HWIF_SUCCESS;\r
+\r
+    if(NULL == ctx || NULL == key_context)\r
+    {\r
+        OIC_LOG(ERROR, TAG, "Invalid input parameters.");\r
+        ret = HWIF_ERR_INVALID_PARAM;\r
+        goto exit;\r
+    }\r
+\r
+    // get mbedtls ecdsa structure\r
+    const mbedtls_pk_info_t *mbedtls_ec_info;\r
+    static mbedtls_pk_info_t ec_info;\r
+\r
+    mbedtls_ec_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY);\r
+    if (NULL == mbedtls_ec_info)\r
+    {\r
+        OIC_LOG(ERROR, TAG, "mbedtls_pk_info_from_type error");\r
+        ret = HWIF_ERROR;\r
+        goto exit;\r
+    }\r
+\r
+    // set hw sign function\r
+    ec_info = *mbedtls_ec_info;\r
+    ec_info.sign_func = EcdsaSignAlt;\r
+    if (0 != mbedtls_pk_setup(ctx, &ec_info))\r
+    {\r
+        OIC_LOG(ERROR, TAG, "mbedtls_pk_setup error");\r
+        ret = HWIF_ERROR;\r
+        goto exit;\r
+    }\r
+\r
+    OIC_LOG(INFO, TAG, "Success to setup ECDSA alt");\r
+\r
+exit:\r
+    OIC_LOG_V(INFO, TAG, "Out %s", __func__);\r
+    return ret;\r
+}\r
+\r
+/********************************************\r
+ * HW interface callback functions\r
+ */\r
+\r
+void* HWGetKeyContext(const char* service, const char* usage, const char* keytype)\r
+{\r
+    (void)keytype;\r
+\r
+    OIC_LOG_V(INFO, TAG, "In %s", __func__);\r
+    if(NULL == service || NULL == usage)\r
+    {\r
+        OIC_LOG(ERROR, TAG, "Invalid input parameters. service and usage should be not NULL.");\r
+        return NULL;\r
+    }\r
+\r
+    // Implementation should return allocated key context depend on hw library\r
+    // key context is related to service, usage and keytype(optional), which is same with alias name.\r
+    // As for now, Iotivity stack is defining following the service and the usage as a default.\r
+    // Refer to pkix_interface.h file\r
+      // #define HWKEY_SVC_IOTIVITY "iotivity"\r
+      // #define HWKEY_USAGE_PRIMARY "primary"\r
+\r
+    OIC_LOG_V(INFO, TAG, "Out %s", __func__);\r
+    return (void*)HWIF_KEY_CONTEXT;\r
+}\r
+\r
+int HWFreeKeyContext(void* keyContext)\r
+{\r
+    OIC_LOG_V(INFO, TAG, "In %s", __func__);\r
+    if(NULL == keyContext)\r
+    {\r
+        OIC_LOG(ERROR, TAG, "key context value is NULL.");\r
+        return HWIF_ERR_INVALID_PARAM;\r
+    }\r
+\r
+    // Implementation should free key context memory if allocated\r
+    if (g_ownCert)\r
+    {\r
+        OICFree(g_ownCert);\r
+        g_ownCert = NULL;\r
+    }\r
+    g_ownCertLen = 0;\r
+\r
+    OIC_LOG_V(INFO, TAG, "Out %s", __func__);\r
+    return HWIF_SUCCESS;\r
+}\r
+\r
+int HWGetOwnCertificateChain(const void* keyContext,\r
+                    uint8_t** cert_chain, size_t* cert_chain_len)\r
+{\r
+    OIC_LOG_V(INFO, TAG, "In %s", __func__);\r
+    int ret = HWIF_SUCCESS;\r
+\r
+    if(NULL == keyContext || NULL == cert_chain || NULL == cert_chain_len)\r
+    {\r
+        OIC_LOG(ERROR, TAG, "Invalid input parameters.");\r
+        ret = HWIF_ERR_INVALID_PARAM;\r
+        goto exit;\r
+    }\r
+\r
+    if (g_ownCert && 0 < g_ownCertLen)\r
+    {\r
+        // Load own certificate from cache\r
+        *cert_chain = g_ownCert;\r
+        *cert_chain_len = g_ownCertLen;\r
+        OIC_LOG(DEBUG, TAG, "Load from the cache");\r
+    }\r
+    else\r
+    {\r
+        // Load own certificate from HW Secure Storage\r
+        ret = SSemulLoadOwncert(keyContext, cert_chain, cert_chain_len);\r
+        if (0 != ret)\r
+        {\r
+            OIC_LOG(ERROR, TAG, "Failed to load the own certificate from Secure Storage");\r
+            ret = HWIF_ERROR;\r
+            goto exit;\r
+        }\r
+\r
+        // Save to cache\r
+        g_ownCert = *cert_chain;\r
+        g_ownCertLen = *cert_chain_len;\r
+    }\r
+\r
+    OIC_LOG_V(DEBUG, TAG, "cert chain size : %zu", *cert_chain_len);\r
+\r
+exit:\r
+    OIC_LOG_V(INFO, TAG, "Out %s", __func__);\r
+    return ret;\r
+}\r
+\r
+int HWSetupPkContext(mbedtls_pk_context* ctx, void* key_context)\r
+{\r
+    OIC_LOG_V(INFO, TAG, "In %s", __func__);\r
+    int ret = HWIF_SUCCESS;\r
+\r
+    if(NULL == ctx || NULL == key_context)\r
+    {\r
+        OIC_LOG(ERROR, TAG, "Invalid input parameters.");\r
+        ret = HWIF_ERR_INVALID_PARAM;\r
+        goto exit;\r
+    }\r
+\r
+    int keytype = SSemulGetKeytype(key_context);\r
+    if (KEYTYPE_RSA == keytype)\r
+    {\r
+        ret = SetupRSAContext(ctx, key_context);\r
+    }\r
+    else if (KEYTYPE_ECC == keytype)\r
+    {\r
+        ret = SetupECDSAContext(ctx, key_context);\r
+    }\r
+\r
+exit:\r
+    OIC_LOG_V(INFO, TAG, "Out %s", __func__);\r
+    return ret;\r
+}\r
+\r
+\r
+\r
diff --git a/resource/csdk/security/provisioning/sample/hw_emul/hw_interface.h b/resource/csdk/security/provisioning/sample/hw_emul/hw_interface.h
new file mode 100644 (file)
index 0000000..8a7befe
--- /dev/null
@@ -0,0 +1,93 @@
+/* *****************************************************************\r
+ *\r
+ * Copyright 2017 Samsung Electronics All Rights Reserved.\r
+ *\r
+ *\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * *****************************************************************/\r
+#ifndef HW_INTERFACE_H\r
+#define HW_INTERFACE_H\r
+\r
+#include <mbedtls/ssl.h>\r
+#include "ss_emul.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+\r
+/**\r
+ * Error-definition for hw interface\r
+ */\r
+\r
+typedef enum HwifResult\r
+{\r
+    HWIF_ERR_INVALID_PARAM    = -100, /**< Invalid Paramter */\r
+    HWIF_ERR_OUT_OF_MEMORY   = -99,  /**< Out of memory */\r
+    HWIF_ERR_NO_DATA                = -98,  /**< No data found */\r
+    HWIF_ERROR         = -1,  /**< Internal Error */\r
+    HWIF_SUCCESS     = 0,    /**< No Error */\r
+} HwifResult_t;\r
+\r
+\r
+/**\r
+ * This callback will be invoked to get a key context based on specific name indication\r
+ * (service name, key usage, key type). The key context may be same with the alias name.\r
+ *\r
+ * @param[in] service  service name indicates first category name\r
+ * @param[in] usage  usage name indicates sub-category name\r
+ * @param[in] keytype  (optional) key type name indication if any, otherwise it usually will be NULL\r
+ * @return  void type pointer value on success, otherwise NULL\r
+ */\r
+void* HWGetKeyContext(const char* service, const char* usage, const char* keytype);\r
+\r
+/**\r
+ * This callback will deallocate the key context that was retrieved from TZ\r
+ * by calling GetHwKeyContext callback.\r
+ *\r
+ * @param[in] keyContext  key context object to be deallocated,\r
+ *                   which was obtained from GetHwKeyContext callback function\r
+ * @return  0 on success, otherwise a negative value\r
+ */\r
+int HWFreeKeyContext(void* keyContext);\r
+\r
+/**\r
+ * This callback will be invoked to load own(i.e., pre-injected) certificate from HW(e.g., TZ, eSE)\r
+ *\r
+ * @param[in] keyContext  key context object that identifies proper certificate chain\r
+ * @param[out] cert_chain  certificate chain in binary\r
+ * @param[out] cert_chain_len  total length of certificate chain\r
+ * @return  0 on success, otherwise a negative value\r
+ */\r
+int HWGetOwnCertificateChain(const void* keyContext,\r
+                    unsigned char** cert_chain, size_t* cert_chain_len);\r
+\r
+/**\r
+ * This callback should provide setting up alternative functions (e.g., rsa_sign, key_len, etc)\r
+ * of which HW(e.g., TZ, eSE) management library to the specified mbedtls context\r
+ * that will be used during handshake.\r
+ *\r
+ * @param[in] ctx  pointer of pk context of mbedtls\r
+ * @param[in] keyContext  key context object that identifies proper public/private key\r
+ * @return  0 on success, otherwise a negative value\r
+ */\r
+int HWSetupPkContext(mbedtls_pk_context* ctx, void* key_context);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif // HW_INTERFACE_H\r
+\r
diff --git a/resource/csdk/security/provisioning/sample/hw_emul/ss_emul.c b/resource/csdk/security/provisioning/sample/hw_emul/ss_emul.c
new file mode 100644 (file)
index 0000000..8c8134f
--- /dev/null
@@ -0,0 +1,366 @@
+/* *****************************************************************\r
+ *\r
+ * Copyright 2017 Samsung Electronics All Rights Reserved.\r
+ *\r
+ *\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * *****************************************************************/\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+#include "oic_malloc.h"\r
+#include "logger.h"\r
+#include "ss_emul.h"\r
+\r
+\r
+#define TAG "OIC_SSEMUL"\r
+\r
+#define HWIF_MAXPATH (4096)\r
+static char HWIF_OWNCERT_FILE_NAME[HWIF_MAXPATH] = {0,};\r
+static char HWIF_KEY_FILE_NAME[HWIF_MAXPATH] = {0,};\r
+static char HWIF_KEY_PASS[HWIF_MAXPATH] = {0,};\r
+\r
+\r
+/********************************************\r
+ * utility functions\r
+ */\r
+\r
+int LoadCertFile(const char* filepath, uint8_t** cert_chain, size_t* cert_chain_len)\r
+{\r
+    if (NULL == filepath || NULL == cert_chain || NULL == cert_chain_len)\r
+    {\r
+        OIC_LOG(ERROR, TAG, "Invalid parameters");\r
+        return -1;\r
+    }\r
+\r
+    uint8_t *certchain;\r
+    size_t certLen;\r
+\r
+    FILE *fp = fopen(filepath, "rb");\r
+    if (fp)\r
+    {\r
+        char buffer[1024];\r
+        size_t fsize = 0;\r
+        size_t bytesRead = 0;\r
+        do\r
+        {\r
+            bytesRead = fread(buffer, 1, sizeof(buffer), fp);\r
+            fsize += bytesRead;\r
+        } while (bytesRead);\r
+\r
+        if (!fsize)\r
+        {\r
+            OIC_LOG(ERROR,TAG,"File is empty");\r
+            fclose(fp);\r
+            return -1;\r
+        }\r
+\r
+        certchain = (uint8_t*)OICCalloc(1, fsize);\r
+        certLen = fsize;\r
+        if (NULL == certchain)\r
+        {\r
+            OIC_LOG(ERROR,TAG,"Failed to allocate memory");\r
+            fclose(fp);\r
+            return -1;\r
+        }\r
+\r
+        rewind(fp);\r
+        if (fsize != fread(certchain, 1, fsize, fp))\r
+        {\r
+            OIC_LOG(ERROR, TAG, "Certiface was not read completely");\r
+        }\r
+        fclose(fp);\r
+    }\r
+    else\r
+    {\r
+        OIC_LOG_V(ERROR,TAG,"Failed to open cert file : %s", filepath);\r
+        return -1;\r
+    }\r
+\r
+    *cert_chain = certchain;\r
+    *cert_chain_len = certLen;\r
+\r
+    OIC_LOG_V(INFO, TAG, "Loading cert success [%s]", filepath);\r
+    OIC_LOG_BUFFER(DEBUG, TAG, certchain, certLen);\r
+    return 0;\r
+}\r
+\r
+\r
+int LoadKeyFile(mbedtls_pk_context *pkey, const char* filepath, const char* password)\r
+{\r
+    if(!filepath)\r
+    {\r
+        OIC_LOG(ERROR, TAG, "Invalid key file path" );\r
+        return -1;\r
+    }\r
+\r
+    int ret = mbedtls_pk_parse_keyfile(pkey, filepath, password);\r
+    if( ret != 0 )\r
+    {\r
+        OIC_LOG_V(ERROR, TAG, "Faile to parse key file [0x%x]", ret );\r
+        return ret;\r
+    }\r
+\r
+    OIC_LOG_V(INFO, TAG, "Loading key success [%s]", filepath);\r
+    return ret;\r
+}\r
+\r
+\r
+/********************************************\r
+ * HW Secure Storage emulation functions\r
+ */\r
+int SSemulSetCertkeyFilepath(const char* cert_filepath,\r
+                                            const char* key_filepath, const char* pwd)\r
+{\r
+    if (NULL == cert_filepath || NULL == key_filepath)\r
+    {\r
+        OIC_LOG(ERROR, TAG, "Invalid parameters");\r
+        return -1;\r
+    }\r
+\r
+    if (HWIF_MAXPATH <= strlen(cert_filepath) || !strlen(cert_filepath)\r
+        || HWIF_MAXPATH <= strlen(key_filepath) || !strlen(key_filepath)\r
+        || (pwd && (HWIF_MAXPATH <= strlen(pwd))))\r
+    {\r
+        OIC_LOG(ERROR, TAG, "Invalid large path length");\r
+        return -1;\r
+    }\r
+\r
+    memset(HWIF_OWNCERT_FILE_NAME, 0, HWIF_MAXPATH);\r
+    memset(HWIF_KEY_FILE_NAME, 0, HWIF_MAXPATH);\r
+    memset(HWIF_KEY_PASS, 0, HWIF_MAXPATH);\r
+\r
+    strncpy(HWIF_OWNCERT_FILE_NAME, cert_filepath, strlen(cert_filepath));\r
+    strncpy(HWIF_KEY_FILE_NAME, key_filepath, strlen(key_filepath));\r
+    if (pwd)\r
+    {\r
+        strncpy(HWIF_KEY_PASS, pwd, strlen(pwd) + 1);\r
+    }\r
+\r
+    OIC_LOG(INFO, TAG, "[Configure Secure Storage Emulation files]");\r
+    OIC_LOG_V(INFO, TAG, "OwnCert file[%zu]: %s", strlen(cert_filepath), cert_filepath);\r
+    OIC_LOG_V(INFO, TAG, "Key file[%zu]: %s", strlen(key_filepath), key_filepath);\r
+    if (pwd)\r
+    {\r
+        OIC_LOG_V(INFO, TAG, "Password[%zu]: %s", strlen(pwd), pwd);\r
+    }\r
+    return 0;\r
+}\r
+\r
+int SSemulGetKeytype(const void* keyContext)\r
+{\r
+    (void)keyContext;\r
+    if (0 == strlen(HWIF_KEY_FILE_NAME))\r
+    {\r
+        OIC_LOG(ERROR, TAG, "Need to set key file name");\r
+        return KEYTYPE_NONE;\r
+    }\r
+\r
+    int ret = KEYTYPE_NONE;\r
+    mbedtls_pk_context pk;\r
+    mbedtls_pk_init(&pk);\r
+\r
+    // 1. load key\r
+    const char* key_file = HWIF_KEY_FILE_NAME;\r
+    const char* key_pass = !strlen(HWIF_KEY_PASS) ? NULL : HWIF_KEY_PASS;\r
+    if (0 > LoadKeyFile(&pk, key_file, key_pass))\r
+    {\r
+        OIC_LOG(ERROR, TAG, "Fail to load key file");\r
+        goto exit;\r
+    }\r
+\r
+    // 2. get key type\r
+    mbedtls_pk_type_t keytype = mbedtls_pk_get_type(&pk);\r
+    if(MBEDTLS_PK_RSA == keytype)\r
+    {\r
+        ret = KEYTYPE_RSA;\r
+    }\r
+    else if(MBEDTLS_PK_ECKEY == keytype ||\r
+               MBEDTLS_PK_ECKEY_DH == keytype)\r
+    {\r
+        ret = KEYTYPE_ECC;\r
+    }\r
+\r
+exit:\r
+    mbedtls_pk_free(&pk);\r
+    return ret;\r
+}\r
+\r
+int SSemulLoadOwncert(const void* keyContext,\r
+                                           uint8_t** cert_chain, size_t* cert_chain_len)\r
+{\r
+    (void)keyContext;\r
+    if (0 == strlen(HWIF_OWNCERT_FILE_NAME))\r
+    {\r
+        OIC_LOG(ERROR, TAG, "Need to set owncert file name");\r
+        return -1;\r
+    }\r
+\r
+    if (0 != LoadCertFile(HWIF_OWNCERT_FILE_NAME, cert_chain, cert_chain_len))\r
+    {\r
+        OIC_LOG(ERROR, TAG, "Faile to load the own certificate file");\r
+        return -1;\r
+    }\r
+\r
+    return 0;\r
+}\r
+\r
+int SSemulGetKeylen(const void* keyContext)\r
+{\r
+    (void)keyContext;\r
+    if (0 == strlen(HWIF_KEY_FILE_NAME))\r
+    {\r
+        OIC_LOG(ERROR, TAG, "Need to set private key file name");\r
+        return -1;\r
+    }\r
+\r
+    int ret = -1;\r
+    size_t key_len = 0;\r
+    mbedtls_pk_context pk;\r
+    mbedtls_pk_init(&pk);\r
+\r
+    // 1. load key\r
+    const char* key_file = HWIF_KEY_FILE_NAME;\r
+    const char* key_pass = !strlen(HWIF_KEY_PASS) ? NULL : HWIF_KEY_PASS;\r
+    ret = LoadKeyFile(&pk, key_file, key_pass);\r
+    if (0 > ret)\r
+    {\r
+        OIC_LOG_V(ERROR, TAG, "Fail to load key file [0x%x]", ret);\r
+        goto exit;\r
+    }\r
+\r
+    key_len = ( 8 * ((const mbedtls_rsa_context *) pk.pk_ctx)->len );\r
+    if(0 >= key_len)\r
+    {\r
+        OIC_LOG(ERROR, TAG, "Invalid key length");\r
+        goto exit;\r
+    }\r
+\r
+exit:\r
+    mbedtls_pk_free(&pk);\r
+    return key_len;\r
+}\r
+\r
+int SSemulRsaSign(const void *keyContext,\r
+                            int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,\r
+                            int mode, mbedtls_md_type_t md_alg, unsigned int hashlen,\r
+                            const unsigned char *hash, unsigned char *sig )\r
+{\r
+    if (0 == strlen(HWIF_KEY_FILE_NAME))\r
+    {\r
+        OIC_LOG(ERROR, TAG, "Need to set private key file name");\r
+        return -1;\r
+    }\r
+\r
+    // workaround for test under sw - 1. load key, 2. sign\r
+\r
+    int ret;\r
+    size_t key_len;\r
+    mbedtls_pk_context pk;\r
+    mbedtls_pk_init(&pk);\r
+\r
+    // 1. load key\r
+    const char* key_file = HWIF_KEY_FILE_NAME;\r
+    const char* key_pass = !strlen(HWIF_KEY_PASS) ? NULL : HWIF_KEY_PASS;\r
+    ret = LoadKeyFile(&pk, key_file, key_pass);\r
+    if (0 > ret)\r
+    {\r
+        OIC_LOG_V(ERROR, TAG, "Fail to load key file [0x%x]", ret);\r
+        goto exit;\r
+    }\r
+\r
+    key_len = ( 8 * ((const mbedtls_rsa_context *) pk.pk_ctx)->len );\r
+    if(0 >= key_len)\r
+    {\r
+        OIC_LOG(ERROR, TAG, "Invalid key length");\r
+        ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;\r
+        goto exit;\r
+    }\r
+    OIC_LOG_V(INFO, TAG, "key name : %s, mode : %d hashlen : %u md_alg : %d keylen : %zu",\r
+            (const char*)(keyContext), mode, hashlen, md_alg, key_len);\r
+\r
+    // 2. sign\r
+    ret = mbedtls_rsa_pkcs1_sign( (mbedtls_rsa_context *)pk.pk_ctx, f_rng, p_rng,\r
+                        MBEDTLS_RSA_PRIVATE, md_alg, (unsigned int) hashlen, hash, sig);\r
+    if(0 != ret )\r
+    {\r
+        OIC_LOG_V(ERROR, TAG, "Fail to sign [0x%x]", ret);\r
+        goto exit;\r
+    }\r
+\r
+exit:\r
+    mbedtls_pk_free(&pk);\r
+    return ret;\r
+}\r
+\r
+int SSemulEcdsaSign( void *ctx, mbedtls_md_type_t md_alg,\r
+                   const unsigned char *hash, size_t hash_len,\r
+                   unsigned char *sig, size_t *sig_len,\r
+                   int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )\r
+{\r
+    (void)ctx;\r
+    if (0 == strlen(HWIF_KEY_FILE_NAME))\r
+    {\r
+        OIC_LOG(ERROR, TAG, "Need to set private key file name");\r
+        return -1;\r
+    }\r
+\r
+    // workaround for test under sw  - 1. load key, 2. set temp ctx, 3.sign\r
+\r
+    int ret;\r
+    mbedtls_pk_context pk;\r
+    mbedtls_ecdsa_context ecdsa;\r
+    mbedtls_ecp_keypair *eckey;\r
+    mbedtls_pk_init(&pk);\r
+    mbedtls_ecdsa_init( &ecdsa );\r
+\r
+    // 1. load key\r
+    const char* key_file = HWIF_KEY_FILE_NAME;\r
+    const char* key_pass = !strlen(HWIF_KEY_PASS) ? NULL : HWIF_KEY_PASS;\r
+    ret = LoadKeyFile(&pk, key_file, key_pass);\r
+    if (0 > ret)\r
+    {\r
+        OIC_LOG_V(ERROR, TAG, "Fail to load key file [0x%x]", ret);\r
+        goto exit;\r
+    }\r
+\r
+    // 2. set temp ctx\r
+    eckey = (mbedtls_ecp_keypair*)pk.pk_ctx;\r
+    ret = mbedtls_ecdsa_from_keypair(&ecdsa, eckey);\r
+    if(0 != ret )\r
+    {\r
+        OIC_LOG_V(ERROR, TAG, "Fail to copy key pair [0x%x]", ret);\r
+        goto exit;\r
+    }\r
+\r
+    // 3. sign\r
+    ret = mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) &ecdsa,\r
+                md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng );\r
+    if(0 != ret )\r
+    {\r
+        OIC_LOG_V(ERROR, TAG, "Fail to sign [0x%x]", ret);\r
+        goto exit;\r
+    }\r
+    OIC_LOG_V(INFO, TAG, "Success to sign");\r
+\r
+exit:\r
+    mbedtls_ecdsa_free( &ecdsa );\r
+    mbedtls_pk_free(&pk);\r
+    OIC_LOG_V(INFO, TAG, "Out %s", __func__);\r
+    return ret;\r
+}\r
+\r
+\r
diff --git a/resource/csdk/security/provisioning/sample/hw_emul/ss_emul.h b/resource/csdk/security/provisioning/sample/hw_emul/ss_emul.h
new file mode 100644 (file)
index 0000000..f1c1e06
--- /dev/null
@@ -0,0 +1,119 @@
+/* *****************************************************************\r
+ *\r
+ * Copyright 2017 Samsung Electronics All Rights Reserved.\r
+ *\r
+ *\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ * *****************************************************************/\r
+#ifndef SS_EMUL_H\r
+#define SS_EMUL_H\r
+\r
+#include <mbedtls/ssl.h>\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/**\r
+ * Type define\r
+ */\r
+ enum SSE_KEY_TYPE\r
+ {\r
+     KEYTYPE_NONE = -1,\r
+     KEYTYPE_RSA,\r
+     KEYTYPE_ECC\r
+ };\r
+\r
+/**\r
+ * This function set own certificate file and key file path to use hw emulation\r
+ *\r
+ * @param[in] cert_filepath  path for own certificate file\r
+ * @param[in] key_filepath  path for private key file\r
+ * @param[in] pwd  password for private key file\r
+ * @return  0 on success, otherwise a negative value\r
+ */\r
+int SSemulSetCertkeyFilepath(const char* cert_filepath,\r
+                                            const char* key_filepath, const char* pwd);\r
+\r
+/**\r
+ * This function get type of stored key from hw emulation\r
+ *\r
+ * @param[in] keyContext  key context object that identifies proper certificate chain\r
+ * @return  SSE_KEY_TYPE\r
+ */\r
+int SSemulGetKeytype(const void* keyContext);\r
+\r
+/**\r
+ * This function load own certificate data from hw emulation\r
+ *\r
+ * @param[in] keyContext  key context object that identifies proper certificate chain\r
+ * @param[out] cert_chain  certificate chain in binary\r
+ * @param[out] cert_chain_len  total length of certificate chain\r
+ * @return  0 on success, otherwise a negative value\r
+ */\r
+int SSemulLoadOwncert(const void* keyContext,\r
+                                           uint8_t** cert_chain, size_t* cert_chain_len);\r
+\r
+/**\r
+ * This function get private key length from hw emulation\r
+ *\r
+ * @param[in] keyContext  key context object that identifies proper certificate chain\r
+ * @return  positive value on success, otherwise a negative value or zero\r
+ */\r
+int SSemulGetKeylen(const void* keyContext);\r
+\r
+/**\r
+ * This function sign hash data with RSA private key from hw emulation\r
+ *\r
+ * @param[in] keyContext  key context object that identifies proper certificate chain\r
+ * @param[in] f_rng  RNG function\r
+ * @param[in] p_rng  RNG parameter\r
+ * @param[in] mode  RSA key mode\r
+ * @param[in] md_alg  md algorithm\r
+ * @param[in] hashlen  length of hash\r
+ * @param[in] hash  hash data to be signed\r
+ * @param[in] sig  signature of hash\r
+ * @return  0 on success, otherwise a negative value\r
+ */\r
+int SSemulRsaSign(const void *keyContext,\r
+                            int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,\r
+                            int mode, mbedtls_md_type_t md_alg, unsigned int hashlen,\r
+                            const unsigned char *hash, unsigned char *sig );\r
+\r
+/**\r
+ * This function sign hash data with ECC private key from hw emulation\r
+ *\r
+ * @param[in] ctx  key context poniter of mbedtls_pk_context\r
+ * @param[in] md_alg  md algorithm\r
+ * @param[in] hash  hash data to be signed\r
+ * @param[in] hashlen  length of hash\r
+ * @param[in] sig  signature of hash\r
+ * @param[in] sig_len  length of signature\r
+ * @param[in] f_rng  RNG function\r
+ * @param[in] p_rng  RNG parameter\r
+ * @return  0 on success, otherwise a negative value\r
+ */\r
+int SSemulEcdsaSign( void *ctx, mbedtls_md_type_t md_alg,\r
+                   const unsigned char *hash, size_t hash_len,\r
+                   unsigned char *sig, size_t *sig_len,\r
+                   int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif // SS_EMUL_H\r
+\r
+\r
index a7549d1..c47fe43 100644 (file)
Binary files a/resource/csdk/security/provisioning/sample/oic_svr_db_client.dat and b/resource/csdk/security/provisioning/sample/oic_svr_db_client.dat differ
index 04bec34..0951580 100644 (file)
Binary files a/resource/csdk/security/provisioning/sample/oic_svr_db_randompin_with_empty_deviceid.dat and b/resource/csdk/security/provisioning/sample/oic_svr_db_randompin_with_empty_deviceid.dat differ
index 2bd928a..244ee83 100644 (file)
                             "if": ["oic.if.baseline"]
                         },
                         {
-                            "href": "/oic/sec/acl",
-                            "rel": "",
-                            "rt": ["oic.r.acl"],
-                            "if": ["oic.if.baseline"]
-                        },
-                        {
                             "href": "/oic/sec/cred",
                             "rel": "",
                             "rt": ["oic.r.cred"],
index 135d7b3..e02d465 100644 (file)
Binary files a/resource/csdk/security/provisioning/sample/oic_svr_db_server_justworks.dat and b/resource/csdk/security/provisioning/sample/oic_svr_db_server_justworks.dat differ
index 6786580..92b63cc 100644 (file)
                             "if": ["oic.if.baseline"]\r
                         },\r
                         {\r
-                            "href": "/oic/sec/acl",\r
-                            "rel": "",\r
-                            "rt": ["oic.r.acl"],\r
-                            "if": ["oic.if.baseline"]\r
-                        },\r
-                        {\r
                             "href": "/oic/sec/cred",\r
                             "rel": "",\r
                             "rt": ["oic.r.cred"],\r
diff --git a/resource/csdk/security/provisioning/sample/oic_svr_db_server_justworks_default.dat b/resource/csdk/security/provisioning/sample/oic_svr_db_server_justworks_default.dat
new file mode 100644 (file)
index 0000000..e02d465
Binary files /dev/null and b/resource/csdk/security/provisioning/sample/oic_svr_db_server_justworks_default.dat differ
diff --git a/resource/csdk/security/provisioning/sample/oic_svr_db_server_justworks_protectedDB_plain.dat b/resource/csdk/security/provisioning/sample/oic_svr_db_server_justworks_protectedDB_plain.dat
new file mode 100644 (file)
index 0000000..e02d465
Binary files /dev/null and b/resource/csdk/security/provisioning/sample/oic_svr_db_server_justworks_protectedDB_plain.dat differ
diff --git a/resource/csdk/security/provisioning/sample/oic_svr_db_server_mvjustworks.dat b/resource/csdk/security/provisioning/sample/oic_svr_db_server_mvjustworks.dat
new file mode 100644 (file)
index 0000000..2391448
Binary files /dev/null and b/resource/csdk/security/provisioning/sample/oic_svr_db_server_mvjustworks.dat differ
diff --git a/resource/csdk/security/provisioning/sample/oic_svr_db_server_mvjustworks.json b/resource/csdk/security/provisioning/sample/oic_svr_db_server_mvjustworks.json
new file mode 100644 (file)
index 0000000..dd811fb
--- /dev/null
@@ -0,0 +1,73 @@
+{\r
+    "acl": {\r
+        "aclist": {\r
+            "aces": [\r
+                {\r
+                    "subjectuuid": "*",\r
+                    "resources": [\r
+                        {\r
+                            "href": "/oic/res",\r
+                            "rel": "",\r
+                            "rt": ["oic.wk.res"],\r
+                            "if": ["oic.if.ll"]\r
+                        },{\r
+                            "href": "/oic/d",\r
+                            "rel": "",\r
+                            "rt": ["oic.wk.d"],\r
+                            "if": ["oic.if.baseline", "oic.if.r"]\r
+                        },{\r
+                            "href": "/oic/p",\r
+                            "rel": "",\r
+                            "rt": ["oic.wk.p"],\r
+                            "if": ["oic.if.baseline", "oic.if.r"]\r
+                        }\r
+                    ],\r
+                    "permission": 2\r
+                },\r
+                {\r
+                    "subjectuuid": "*",\r
+                    "resources": [\r
+                        {\r
+                            "href": "/oic/sec/doxm",\r
+                            "rel": "",\r
+                            "rt": ["oic.r.doxm"],\r
+                            "if": ["oic.if.baseline"]\r
+                        },\r
+                        {\r
+                            "href": "/oic/sec/pstat",\r
+                            "rel": "",\r
+                            "rt": ["oic.r.pstat"],\r
+                            "if": ["oic.if.baseline"]\r
+                        },\r
+                        {\r
+                            "href": "/oic/sec/cred",\r
+                            "rel": "",\r
+                            "rt": ["oic.r.cred"],\r
+                            "if": ["oic.if.baseline"]\r
+                        }\r
+                    ],\r
+                    "permission": 6\r
+                }\r
+            ]\r
+        },\r
+        "rowneruuid" : "6D766A75-7374-776F-726B-735575696430"\r
+    },\r
+    "pstat": {\r
+        "isop": false,\r
+        "deviceuuid": "6D766A75-7374-776F-726B-735575696430",\r
+        "rowneruuid": "6D766A75-7374-776F-726B-735575696430",\r
+        "cm": 2,\r
+        "tm": 0,\r
+        "om": 4,\r
+        "sm": 4\r
+        },\r
+    "doxm": {\r
+        "oxms": [0, 65281],\r
+        "oxmsel": 0,\r
+        "sct": 1,\r
+        "owned": false,\r
+        "deviceuuid": "6D766A75-7374-776F-726B-735575696430",\r
+        "devowneruuid": "",\r
+        "rowneruuid": "6D766A75-7374-776F-726B-735575696430"\r
+    }\r
+}\r
diff --git a/resource/csdk/security/provisioning/sample/oic_svr_db_server_preconfpin.dat b/resource/csdk/security/provisioning/sample/oic_svr_db_server_preconfpin.dat
new file mode 100644 (file)
index 0000000..472ef8e
Binary files /dev/null and b/resource/csdk/security/provisioning/sample/oic_svr_db_server_preconfpin.dat differ
diff --git a/resource/csdk/security/provisioning/sample/oic_svr_db_server_preconfpin.json b/resource/csdk/security/provisioning/sample/oic_svr_db_server_preconfpin.json
new file mode 100644 (file)
index 0000000..89b960c
--- /dev/null
@@ -0,0 +1,73 @@
+{\r
+    "acl": {\r
+        "aclist": {\r
+            "aces": [\r
+                {\r
+                    "subjectuuid": "*",\r
+                    "resources": [\r
+                        {\r
+                            "href": "/oic/res",\r
+                            "rel": "",\r
+                            "rt": ["oic.wk.res"],\r
+                            "if": ["oic.if.ll"]\r
+                        },{\r
+                            "href": "/oic/d",\r
+                            "rel": "",\r
+                            "rt": ["oic.wk.d"],\r
+                            "if": ["oic.if.baseline", "oic.if.r"]\r
+                        },{\r
+                            "href": "/oic/p",\r
+                            "rel": "",\r
+                            "rt": ["oic.wk.p"],\r
+                            "if": ["oic.if.baseline", "oic.if.r"]\r
+                        }\r
+                    ],\r
+                    "permission": 2\r
+                },\r
+                {\r
+                    "subjectuuid": "*",\r
+                    "resources": [\r
+                        {\r
+                            "href": "/oic/sec/doxm",\r
+                            "rel": "",\r
+                            "rt": ["oic.r.doxm"],\r
+                            "if": ["oic.if.baseline"]\r
+                        },\r
+                        {\r
+                            "href": "/oic/sec/pstat",\r
+                            "rel": "",\r
+                            "rt": ["oic.r.pstat"],\r
+                            "if": ["oic.if.baseline"]\r
+                        },\r
+                        {\r
+                            "href": "/oic/sec/cred",\r
+                            "rel": "",\r
+                            "rt": ["oic.r.cred"],\r
+                            "if": ["oic.if.baseline"]\r
+                        }\r
+                    ],\r
+                    "permission": 6\r
+                }\r
+            ]\r
+        },\r
+        "rowneruuid" : "50726563-6F6E-6669-6775-72656450494E"\r
+    },\r
+    "pstat": {\r
+        "isop": false,\r
+        "deviceuuid": "50726563-6F6E-6669-6775-72656450494E",\r
+        "rowneruuid": "50726563-6F6E-6669-6775-72656450494E",\r
+        "cm": 2,\r
+        "tm": 0,\r
+        "om": 4,\r
+        "sm": 4\r
+        },\r
+    "doxm": {\r
+        "oxms": [0, 65280],\r
+        "oxmsel": 0,\r
+        "sct": 1,\r
+        "owned": false,\r
+        "deviceuuid": "50726563-6F6E-6669-6775-72656450494E",\r
+        "devowneruuid": "",\r
+        "rowneruuid": "50726563-6F6E-6669-6775-72656450494E"\r
+    }\r
+}\r
index 725a56e..e2a16d7 100644 (file)
Binary files a/resource/csdk/security/provisioning/sample/oic_svr_db_server_randompin.dat and b/resource/csdk/security/provisioning/sample/oic_svr_db_server_randompin.dat differ
index f39b06c..90863b1 100644 (file)
                             "if": ["oic.if.baseline"]\r
                         },\r
                         {\r
-                            "href": "/oic/sec/acl",\r
-                            "rel": "",\r
-                            "rt": ["oic.r.acl"],\r
-                            "if": ["oic.if.baseline"]\r
-                        },\r
-                        {\r
                             "href": "/oic/sec/cred",\r
                             "rel": "",\r
                             "rt": ["oic.r.cred"],\r
index e1f4e4b..55e7db7 100644 (file)
 #include "securevirtualresourcetypes.h"
 #include "srmutility.h"
 #include "pmtypes.h"
+#include "oxmverifycommon.h"
+#include "pkix_interface.h"
+#include "hw_emul/hw_interface.h"
+#include "mbedtls/x509_crt.h"
 
 #ifdef __cplusplus
 extern "C"
@@ -44,32 +48,37 @@ extern "C"
 
 // declaration(s) for provisioning client using C-level provisioning API
 // user input definition for main loop on provisioning client
-#define _10_DISCOV_ALL_DEVS_        10
-#define _11_DISCOV_UNOWN_DEVS_      11
-#define _12_DISCOV_OWN_DEVS_        12
-#ifdef _ENABLE_MULTIPLE_OWNER_
-#define _13_MOT_DISCOV_DEV_         13
-#endif //_ENABLE_MULTIPLE_OWNER_
-#define _20_REGIST_DEVS_            20
-#define _30_PROVIS_PAIR_DEVS_       30
-#define _31_PROVIS_CRED_            31
-#define _32_PROVIS_ACL_             32
-#define _33_PROVIS_DP_              33
-#define _34_CHECK_LINK_STATUS_      34
-#define _35_SAVE_ACL_               35
-#define _40_UNLINK_PAIR_DEVS_       40
-#define _50_REMOVE_SELEC_DEV_       50
-#define _51_REMOVE_DEV_WITH_UUID_   51
-#define _52_RESET_SELEC_DEV_        52
-#define _60_GET_CRED_               60
-#define _61_GET_ACL_                61
-#ifdef _ENABLE_MULTIPLE_OWNER_
-#define _70_MOT_CHANGE_MOM_         70
-#define _71_MOT_PROV_PRECONF_PIN_   71
-#define _72_MOT_OXM_SEL_            72
-#endif //_ENABLE_MULTIPLE_OWNER_
-#define _80_SELECT_PROTOCOL_        80
-#define _99_EXIT_PRVN_CLT_          99
+#define _10_DISCOV_ALL_DEVS_            10
+#define _11_DISCOV_UNOWN_DEVS_          11
+#define _12_DISCOV_OWN_DEVS_            12
+#ifdef MULTIPLE_OWNER
+#define _13_MOT_DISCOV_DEV_             13
+#endif //MULTIPLE_OWNER
+#define _20_REGIST_DEVS_                20
+#define _30_PROVIS_PAIR_DEVS_           30
+#define _31_PROVIS_CRED_                31
+#define _32_PROVIS_ACL_                 32
+#define _33_PROVIS_DP_                  33
+#define _34_CHECK_LINK_STATUS_          34
+#define _35_SAVE_ACL_                   35
+#define _40_UNLINK_PAIR_DEVS_           40
+#define _50_REMOVE_SELEC_DEV_           50
+#define _51_REMOVE_DEV_WITH_UUID_       51
+#define _52_RESET_SELEC_DEV_            52
+#define _53_RESET_SVR_DB_               53
+#define _60_GET_CRED_                   60
+#define _61_GET_ACL_                    61
+#ifdef MULTIPLE_OWNER
+#define _70_MOT_CHANGE_MOM_             70
+#define _71_MOT_PROV_PRECONF_PIN_       71
+#define _72_MOT_OXM_SEL_                72
+#define _73_MOT_REMOVE_SUBOWNER_        73
+#define _74_MOT_REMOVE_ALL_SUBOWNER_        74
+#endif //MULTIPLE_OWNER
+#define _80_SELECT_PROTOCOL_            80
+#define _81_SELECT_VERIF_METHOD_        81
+#define _82_SECURE_STORAGE_HW_EMULATION_    82
+#define _99_EXIT_PRVN_CLT_              99
 
 #define ACL_RESRC_MAX_NUM   16
 #define ACL_RESRC_ARRAY_SIZE   3 //This value is used only for sample (not OCF spec)
@@ -98,10 +107,10 @@ static OCProvisionDev_t* g_own_list;
 static OCProvisionDev_t* g_unown_list;
 static int g_own_cnt;
 static int g_unown_cnt;
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 static OCProvisionDev_t* g_mot_enable_list;
 static int g_mot_enable_cnt;
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
 static bool g_doneCB;
 #ifdef __WITH_TLS__
@@ -262,7 +271,7 @@ static void syncDeviceCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool h
     g_doneCB = true;
 }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 static void updateDoxmForMOTCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
 {
     if(!hasError)
@@ -276,7 +285,22 @@ static void updateDoxmForMOTCB(void* ctx, int nOfRes, OCProvisionResult_t* arr,
     }
     g_doneCB = true;
 }
-#endif //_ENABLE_MULTIPLE_OWNER_
+
+static void deleteDoxmForMOTCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
+{
+    if(!hasError)
+    {
+        OIC_LOG_V(INFO, TAG, "DELETE 'doxm' SUCCEEDED - ctx: %s", (char*) ctx);
+    }
+    else
+    {
+        OIC_LOG_V(ERROR, TAG, "DELETE 'doxm'  FAILED - ctx: %s", (char*) ctx);
+        printResultList((const OCProvisionResult_t*) arr, nOfRes);
+    }
+    g_doneCB = true;
+}
+
+#endif //MULTIPLE_OWNER
 
 static void inputPinCB(char* pin, size_t len)
 {
@@ -431,7 +455,7 @@ static int discoverOwnedDevices(void)
     return 0;
 }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 static int discoverMOTEnabledDevices(void)
 {
     // delete owned device list before updating it
@@ -455,7 +479,7 @@ static int discoverMOTEnabledDevices(void)
 
     return 0;
 }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
 static int registerDevices(void)
 {
@@ -1206,7 +1230,65 @@ static int removeDeviceWithUuid(void)
     return 0;
 }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+OCStackResult displayNumCB(void * ctx, uint8_t mutualVerifNum[MUTUAL_VERIF_NUM_LEN])
+{
+    OIC_LOG(INFO, TAG, "IN displayMutualVerifNumCB");
+    OC_UNUSED(ctx);
+    if (NULL != mutualVerifNum)
+    {
+        OIC_LOG(INFO, TAG, "############ mutualVerifNum ############");
+        OIC_LOG_BUFFER(INFO, TAG, mutualVerifNum, MUTUAL_VERIF_NUM_LEN);
+        OIC_LOG(INFO, TAG, "############ mutualVerifNum ############");
+        OIC_LOG(INFO, TAG, "OUT displayMutualVerifNumCB");
+    }
+    else
+    {
+        OIC_LOG(INFO, TAG, "############ Confirm on the Server side ############");
+    }
+    return OC_STACK_OK;
+}
+
+OCStackResult confirmNumCB(void * ctx)
+{
+    OC_UNUSED(ctx);
+    for (;;)
+    {
+        int userConfirm;
+
+        printf("   > Press 1 if the mutual verification numbers are the same\n");
+        printf("   > Press 0 if the mutual verification numbers are not the same\n");
+
+        for (int ret=0; 1!=ret; )
+        {
+            ret = scanf("%d", &userConfirm);
+            for (; 0x20<=getchar(); );  // for removing overflow garbage
+                                        // '0x20<=code' is character region
+        }
+        if (1 == userConfirm)
+        {
+            break;
+        }
+        else if (0 == userConfirm)
+        {
+            return OC_STACK_USER_DENIED_REQ;
+        }
+        printf("   Entered Wrong Number. Please Enter Again\n");
+    }
+    return OC_STACK_OK;
+}
+
+OCStackResult notifyInputStateCB(void * ctx)
+{
+    OC_UNUSED(ctx);
+
+    OIC_LOG(DEBUG, TAG, "IN notifyInputStateCB");
+    OIC_LOG(DEBUG, TAG, "User input Callback in progress");
+    OIC_LOG(DEBUG, TAG, "OUT notifyInputStateCB");
+
+    return OC_STACK_OK;
+}
+
+#ifdef MULTIPLE_OWNER
 static int changeMultipleOwnershipTrnasferMode(void)
 {
     // check |own_list| for removing device
@@ -1402,7 +1484,149 @@ static int provisionPreconfigPIN()
 
     return 0;
 }
-#endif //_ENABLE_MULTIPLE_OWNER_
+
+static int removeSubOwner(void)
+{
+    // check |g_mot_enable_list| for removing sub-owner
+    if (!g_mot_enable_list || 1 > g_mot_enable_cnt)
+    {
+        printf("   > Multiple Ownership Transfer Enabled Device List is Empty\n");
+        printf("   > Please Discover the Multiple Ownership Transfer Enabled Devices, with [13] Menu\n");
+        return 0;  // normal case
+    }
+
+    // select resource server for removing sub-owner
+    int dev_num = 0;
+    for ( ; ; )
+    {
+        printf("   > Enter Device Number to remove sub-owner: ");
+        for (int ret = 0; 1 != ret; )
+        {
+            ret = scanf("%d", &dev_num);
+            for( ; 0x20 <= getchar(); );  // for removing overflow garbages
+                                        // '0x20<=code' is character region
+        }
+        if (0 < dev_num && g_mot_enable_cnt >= dev_num)
+        {
+            break;
+        }
+        printf("     Entered Wrong Number. Please Enter Again\n");
+    }
+
+    OCProvisionDev_t* motDev = getDevInst(g_mot_enable_list, dev_num);
+    if (motDev && motDev->doxm && motDev->doxm->subOwners)
+    {
+        OicSecSubOwner_t* subOwner = motDev->doxm->subOwners;
+        int so_cnt = 0;
+        while(subOwner)
+        {
+            printf("     [%zu] ", ++so_cnt);
+            printUuid(&subOwner->uuid);
+            printf("\n");
+            subOwner = subOwner->next;
+        }
+
+        int so_num = 0;
+        for ( ; ; )
+        {
+            printf("   > Enter SubOwner Number to be removed : ");
+            for (int ret = 0; 1 != ret; )
+            {
+                ret = scanf("%d", &so_num);
+                for( ; 0x20<=getchar(); );  // for removing overflow garbages
+                                            // '0x20<=code' is character region
+            }
+            if (0 < so_num && so_cnt >= so_num)
+            {
+                int target_num = 0;
+                subOwner = motDev->doxm->subOwners;
+                while (subOwner)
+                {
+                    if(so_num == ++target_num)
+                    {
+                        if (OC_STACK_OK != OCRemoveSubOwner(NULL, motDev, &subOwner->uuid, deleteDoxmForMOTCB))
+                        {
+                            return -1;
+                        }
+
+                        g_doneCB = false;
+
+                        if(waitCallbackRet())  // input |g_doneCB| flag implicitly
+                        {
+                            OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
+                            return -1;
+                        }
+                        return 0;
+                    }
+                    subOwner = subOwner->next;
+                }
+                break;
+            }
+            printf("     Entered Wrong Number. Please Enter Again\n");
+        }
+    }
+    else
+    {
+        printf("     SubOwner list is empty.\n");
+    }
+
+    return 0;
+}
+
+static int removeAllSubOwner(void)
+{
+    // check |g_mot_enable_list| for removing sub-owner
+    if (!g_mot_enable_list || 1 > g_mot_enable_cnt)
+    {
+        printf("   > Multiple Ownership Transfer Enabled Device List is Empty\n");
+        printf("   > Please Discover the Multiple Ownership Transfer Enabled Devices, with [13] Menu\n");
+        return 0;  // normal case
+    }
+
+    // select resource server for removing sub-owner
+    int dev_num = 0;
+    for ( ; ; )
+    {
+        printf("   > Enter Device Number to remove sub-owner: ");
+        for (int ret = 0; 1 != ret; )
+        {
+            ret = scanf("%d", &dev_num);
+            for( ; 0x20 <= getchar(); );  // for removing overflow garbages
+                                        // '0x20<=code' is character region
+        }
+        if (0 < dev_num && g_mot_enable_cnt >= dev_num)
+        {
+            break;
+        }
+        printf("     Entered Wrong Number. Please Enter Again\n");
+    }
+
+    OCProvisionDev_t* motDev = getDevInst(g_mot_enable_list, dev_num);
+    if (motDev && motDev->doxm && motDev->doxm->subOwners)
+    {
+        if (OC_STACK_OK != OCRemoveAllSubOwner(NULL, motDev, deleteDoxmForMOTCB))
+        {
+            return -1;
+        }
+
+        g_doneCB = false;
+
+        if(waitCallbackRet())  // input |g_doneCB| flag implicitly
+        {
+            OIC_LOG(ERROR, TAG, "waitCallbackRet callback error");
+            return -1;
+        }
+        return 0;
+    }
+    else
+    {
+        printf("     SubOwner list is empty.\n");
+    }
+
+    return 0;
+}
+
+#endif //MULTIPLE_OWNER
 
 static int resetDevice(void)
 {
@@ -1456,6 +1680,18 @@ static int resetDevice(void)
     return 0;
 }
 
+static int resetSVRDB(void)
+{
+    printf("   Resetting SVR DB..\n");
+    OCStackResult rst = OCResetSVRDB();
+    if (OC_STACK_OK != rst)
+    {
+        OIC_LOG_V(ERROR, TAG, "OCResetSVRDB API error: %d", rst);
+        return -1;
+    }
+    return 0;
+}
+
 static OicSecAcl_t* createAcl(const int dev_num)
 {
     if(0>=dev_num || g_own_cnt<dev_num)
@@ -1561,7 +1797,7 @@ static OicSecAcl_t* createAcl(const int dev_num)
             printf("         Enter Number of resource type for [%s] : ", rsrc->href);
             for(int ret=0; 1!=ret; )
             {
-                ret = scanf("%d", &arrLen);
+                ret = scanf("%zu", &arrLen);
                 for( ; 0x20<=getchar(); );  // for removing overflow garbages
                                             // '0x20<=code' is character region
             }
@@ -1580,9 +1816,9 @@ static OicSecAcl_t* createAcl(const int dev_num)
             goto CRACL_ERROR;
         }
 
-        for(int i = 0; i < arrLen; i++)
+        for(size_t i = 0; i < arrLen; i++)
         {
-            printf("         Enter ResourceType[%d] Name (e.g. core.led): ", i+1);
+            printf("         Enter ResourceType[%zu] Name (e.g. core.led): ", i+1);
             for(int ret=0; 1!=ret; )
             {
                 ret = scanf("%128s", rsrc_in);  // '128' is ACL_RESRC_MAX_LEN
@@ -1602,7 +1838,7 @@ static OicSecAcl_t* createAcl(const int dev_num)
             printf("         Enter Number of interface for [%s]: ", rsrc->href);
             for(int ret=0; 1!=ret; )
             {
-                ret = scanf("%d", &arrLen);
+                ret = scanf("%zu", &arrLen);
                 for( ; 0x20<=getchar(); );  // for removing overflow garbages
                                             // '0x20<=code' is character region
             }
@@ -1621,9 +1857,9 @@ static OicSecAcl_t* createAcl(const int dev_num)
             goto CRACL_ERROR;
         }
 
-        for(int i = 0; i < arrLen; i++)
+        for(size_t i = 0; i < arrLen; i++)
         {
-            printf("         Enter Interface[%d] Name (e.g. oic.if.baseline): ", i+1);
+            printf("         Enter Interface[%zu] Name (e.g. oic.if.baseline): ", i+1);
             for(int ret=0; 1!=ret; )
             {
                 ret = scanf("%128s", rsrc_in);  // '128' is ACL_RESRC_MAX_LEN
@@ -1909,6 +2145,20 @@ static FILE* fopen_prvnMng(const char* path, const char* mode)
     return fopen(SVR_DB_FILE_NAME, mode);
 }
 
+static int peerCertCallback(void *ctx, const mbedtls_x509_crt *cert, int depth)
+{
+    (void)ctx;
+
+    OIC_LOG_V(DEBUG, TAG, "Depth : %d", depth);
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+    OIC_LOG(DEBUG, TAG, "***** Serial number of certificate is below *****");
+    OIC_LOG_BUFFER(DEBUG, TAG, cert->serial.p, cert->serial.len);
+    OIC_LOG(DEBUG, TAG, "***** Serial number of certificate is above *****");
+    OIC_LOG_V(DEBUG, TAG, "OUT%s", __func__);
+
+    return 0;
+}
+
 static int waitCallbackRet(void)
 {
     for(int i=0; !g_doneCB && CALLBACK_TIMEOUT>i; ++i)
@@ -1921,6 +2171,11 @@ static int waitCallbackRet(void)
         }
     }
 
+    if(!g_doneCB)
+    {
+        OCPDMCleanupForTimeout();
+    }
+
     return 0;
 }
 
@@ -2009,6 +2264,86 @@ static void selectSecureProtocol()
 }
 #endif
 
+static void secureStorageHwEmulation()
+{
+    printf("   Enable Secure Storage HW Emulation\n");
+
+    printf("         Enter Own Certificate File Path[~4095]: ");
+    char cert_filepath[4096] = {0,};
+    for(int ret=0; 1!=ret; )
+    {
+        ret = scanf("%255s", cert_filepath);
+        for( ; 0x20<=getchar(); );  // for removing overflow garbages
+                                    // '0x20<=code' is character region
+    }
+
+    printf("         Enter Private Key File Path[~4095]: ");
+    char key_filepath[4096] = {0,};
+    for(int ret=0; 1!=ret; )
+    {
+        ret = scanf("%255s", key_filepath);
+        for( ; 0x20<=getchar(); );  // for removing overflow garbages
+                                    // '0x20<=code' is character region
+    }
+
+    printf("         Enter Password for Key Password[~31][Press (Enter) to not set]: ");
+    char pwd[32] = {0,};
+    for(int i=0; i < 31; i++)
+    {
+        pwd[i] = (char)getchar();
+        if (0x20 <= pwd[i])
+        {
+            pwd[i--] = '\0';
+            continue;
+        }
+        if (0x0A == pwd[i])
+        {
+            pwd[i] = '\0';
+            break;
+        }
+    }
+
+    if (0 != SSemulSetCertkeyFilepath(cert_filepath, key_filepath, pwd))
+    {
+        printf("    Fail to set cert/key file path");
+        return;
+    }
+
+    if (0 != SetHwPkixCallbacks(HWGetKeyContext,
+                                                  HWFreeKeyContext,
+                                                  HWGetOwnCertificateChain,
+                                                  HWSetupPkContext))
+    {
+        printf("    Fail to regist HW Pkix Callbacks");
+        return;
+    }
+    printf("    Success to regist HW Pkix Callbacks");
+}
+
+static void selectVerifMethod()
+{
+    int option;
+    printf("   Select verification method for ownership transfer\n");
+    printf("   0 - No verification\n");
+    printf("   1 - Display only\n");
+    printf("   2 - Confirm only\n");
+    printf("   3 - Both Display and Confirm\n");
+
+    for(int ret=0; 1!=ret; )
+    {
+        ret = scanf("%d",&option);
+        for( ; 0x20<=getchar(); );  // for removing overflow garbages
+        // '0x20<=code' is character region
+    }
+
+    if(0 > option || 3 < option)
+    {
+        printf("Invalid option!");
+    }
+    SetVerifyOption((VerifyOptionBitmask_t) option);
+    printf("Option %d chosen!", option);
+}
+
 static void printMenu(void)
 {
     printf("************************************************************\n");
@@ -2018,12 +2353,12 @@ static void printMenu(void)
     printf("** [A] DISCOVER DEVICES ON NETWORK\n");
     printf("** 10. Discover All Un/Owned Devices on Network\n");
     printf("** 11. Discover Only Unowned Devices on Network\n");
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
     printf("** 12. Discover Only Owned Devices on Network\n");
     printf("** 13. Discover Multiple Ownership Transfer Enabled Devices on Network\n\n");
 #else
     printf("** 12. Discover Only Owned Devices on Network\n\n");
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
     printf("** [B] REGISTER/OWN ALL DISCOVERED UNOWNED DEVICES\n");
     printf("** 20. Register/Own All Discovered Unowned Devices\n\n");
@@ -2042,27 +2377,32 @@ static void printMenu(void)
     printf("** [E] REMOVE THE SELECTED DEVICE\n");
     printf("** 50. Remove the Selected Device\n");
     printf("** 51. Remove Device with UUID (UUID input is required)\n");
-    printf("** 52. Reset the Selected Device\n\n");
+    printf("** 52. Reset the Selected Device\n");
+    printf("** 53. Reset SVR DB\n\n");
 
     printf("** [F] GET SECURITY RESOURCE FOR DEBUGGING ONLY\n");
     printf("** 60. Get the Credential resources of the Selected Device\n");
     printf("** 61. Get the ACL resources of the Selected Device\n\n");
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
     printf("** [G] UPDATE THE MULTIPLE OWNERSHIP TRANSFER RELATED VALUE\n");
     printf("** 70. Change the Multiple Ownership transfer MODE(update mom)\n");
     printf("** 71. Provision Preconfigured PIN\n");
-    printf("** 72. Change the Multiple Ownership transfer METHOD(update oxmsel)\n\n");
-#endif //_ENABLE_MULTIPLE_OWNER_
+    printf("** 72. Change the Multiple Ownership transfer METHOD(update oxmsel)\n");
+    printf("** 73. Remove Sub-Owner from Resource Server\n");
+    printf("** 74. Remove All Sub-Owner from Resource Server\n\n");
+#endif //MULTIPLE_OWNER
 
 #ifdef __WITH_TLS__
-    printf("** [H] SELECT SECURE PROTOCOL DTLS/TLS\n");
-    printf("** 80. Select secure protocol(default DTLS)\n\n");
-
-    printf("** [I] EXIT PROVISIONING CLIENT\n");
+    printf("** [H] SELECT SECURE PROTOCOL DTLS/TLS AND OTHERS\n");
+    printf("** 80. Select secure protocol(default DTLS)\n");
+    printf("** 81. Select verification method\n");
+    printf("** 82. Enable secure storage hw emulation\n\n");
 #else
-    printf("** [H] EXIT PROVISIONING CLIENT\n");
+    printf("** [H] SELECT VERIFICATION OPTION\n");
+    printf("** 81. Select verification method\n\n");
 #endif
+    printf("** [I] EXIT PROVISIONING CLIENT\n");
 
     printf("** 99. Exit Provisionong Client\n\n");
 
@@ -2089,6 +2429,35 @@ static void printUsage(void)
 }
 #endif
 
+/**
+ * Sample implementation of Export key block and master secret
+ *
+ * @param[in] p_expkey  Context for the callback
+ * @aram[in] ms        Pointer to master secret (fixed length: 48 bytes)
+ * @param[in] kb        Pointer to key block, see RFC 5246 section 6.3
+ *                  (variable length: 2 * maclen + 2 * keylen + 2 * ivlen).
+ * @param[in] maclen    MAC length
+ * @param[in] keylen    Key length
+ * @param[in] ivlen     IV length
+ */
+static void SslExportKeysCallback(const unsigned char* masterSecret,
+                                  const unsigned char* keyBlock,
+                                  size_t macLen, size_t keyLen, size_t ivLen)
+{
+    OIC_LOG_V(INFO, TAG, "In %s ", __func__);
+
+    OIC_LOG(INFO, TAG, "[MASTER SECRET] : ");
+    OIC_LOG_BUFFER(INFO, TAG, masterSecret, 48);
+
+    OIC_LOG(INFO, TAG, "[KEY BLOCK] : ");
+    OIC_LOG_BUFFER(INFO, TAG, keyBlock, (2 * macLen) + (2 * keyLen) + (2 * ivLen));
+
+    OIC_LOG_V(INFO, TAG, "Mac Length = %zu, Key Length = %zu, IV Length = %zu",
+            macLen, keyLen, ivLen);
+
+    OIC_LOG_V(INFO, TAG, "Out %s ", __func__);
+}
+
 // main function for provisioning client using C-level provisioning API
 int main()
 {
@@ -2099,15 +2468,30 @@ int main()
         goto PMCLT_ERROR;
     }
 
+    if (CA_STATUS_OK !=
+        CASetSslExportKeysCallback(SslExportKeysCallback, CA_SSL_EKCB_DTLS, CA_SSL_EKCB_CLIENT))
+    {
+        OIC_LOG(ERROR, TAG, "Failed to register the (D)TLS export Key Callback!");
+        goto PMCLT_ERROR;
+    }
+
     // Client can choose a allowed/not-allowed OxM method.
     if(OC_STACK_OK != OCSetOxmAllowStatus(OIC_DECENTRALIZED_PUBLIC_KEY, false))
     {
         OIC_LOG(WARNING, TAG, "Failed to disable OIC_DECENTRALIZED_PUBLIC_KEY OxM");
     }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+    // set callbacks for verification options
+    SetDisplayNumCB(NULL, displayNumCB);
+    SetUserConfirmCB(NULL, confirmNumCB);
+    SetInputStateCB(NULL, notifyInputStateCB);
+
+    // set callback for checking peer certificate information
+    OCSetPeerCertCallback(NULL, peerCertCallback);
+
+#ifdef MULTIPLE_OWNER
     SetPreconfigPin("12341234", 8);
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
     // main loop for provisioning manager
     int mn_num = 0;
@@ -2143,14 +2527,14 @@ int main()
                 OIC_LOG(ERROR, TAG, "_12_DISCOV_OWN_DEVS_: error");
             }
             break;
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
         case _13_MOT_DISCOV_DEV_:
             if(discoverMOTEnabledDevices())
             {
                 OIC_LOG(ERROR, TAG, "_13_MOT_DISCOV_DEV_: error");
             }
             break;
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
         case _20_REGIST_DEVS_:
             if(registerDevices())
             {
@@ -2217,6 +2601,12 @@ int main()
                 OIC_LOG(ERROR, TAG, "_52_RESET_SELEC_DEV_: error");
             }
             break;
+        case _53_RESET_SVR_DB_:
+            if(resetSVRDB())
+            {
+                OIC_LOG(ERROR, TAG, "_53_RESET_SVR_DB_: error");
+            }
+            break;
         case _60_GET_CRED_:
             if(getCred())
             {
@@ -2229,7 +2619,7 @@ int main()
                 OIC_LOG(ERROR, TAG, "_61_GET_ACL_: error");
             }
             break;
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
         case _70_MOT_CHANGE_MOM_:
             if(changeMultipleOwnershipTrnasferMode())
             {
@@ -2248,12 +2638,30 @@ int main()
                 OIC_LOG(ERROR, TAG, "_72_MOT_OXM_SEL_: error");
             }
             break;
-#endif //_ENABLE_MULTIPLE_OWNER_
+        case _73_MOT_REMOVE_SUBOWNER_:
+            if(removeSubOwner())
+            {
+                OIC_LOG(ERROR, TAG, "_73_MOT_REMOVE_SUBOWNER_ : error");
+            }
+            break;
+        case _74_MOT_REMOVE_ALL_SUBOWNER_:
+            if(removeAllSubOwner())
+            {
+                OIC_LOG(ERROR, TAG, "_74_MOT_REMOVE_ALL_SUBOWNER_ : error");
+            }
+            break;
+#endif //MULTIPLE_OWNER
 #ifdef __WITH_TLS__
         case  _80_SELECT_PROTOCOL_:
             selectSecureProtocol();
             break;
 #endif
+        case _81_SELECT_VERIF_METHOD_:
+            selectVerifMethod();
+            break;
+        case _82_SECURE_STORAGE_HW_EMULATION_:
+            secureStorageHwEmulation();
+            break;
         case _99_EXIT_PRVN_CLT_:
             goto PMCLT_ERROR;
         default:
@@ -2269,9 +2677,9 @@ PMCLT_ERROR:
     }
     OCDeleteDiscoveredDevices(g_own_list);  // after here |g_own_list| points nothing
     OCDeleteDiscoveredDevices(g_unown_list);  // after here |g_unown_list| points nothing
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
     OCDeleteDiscoveredDevices(g_mot_enable_list);  // after here |g_motdev_list| points nothing
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
     if(g_svr_fname)
     {
index 54ec780..ee80fa4 100644 (file)
@@ -1,19 +1,21 @@
 -----BEGIN CERTIFICATE-----
-MIIC/jCCAeYCAQEwDQYJKoZIhvcNAQELBQAwRTELMAkGA1UEBhMCQVUxEzARBgNV
-BAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0
-ZDAeFw0xNjA2MjgwNTMzNThaFw0yNjA2MjYwNTMzNThaMEUxCzAJBgNVBAYTAkFV
-MRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRz
-IFB0eSBMdGQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC1HHkfMG9c
-BJ7ZeCIBKe7pSjpptvi+hzpdV72W7szpWDlTQdUaRxKL9aoNxbyuF5OL8xAQ9s28
-IqIxdPW7X3JAmkLigzMCo2xtXHz/OyvomU6fhibneQw5De+iUoD68zdG+/k1NcAW
-xx+VEAMw4fvZvYSVEQ1aKFnjtrQ8o6Zfe5+MRTvBq+G0+jwZWJEoKbpxIPpNWPGx
-AV17tEpe+lg27jEYDYG1QUiL2TG80ZjQQL95OjETYf8EIxoqrKHvHCvDin0zdd+E
-qPN0Y+Rhkl3PYoxWm7d8z0p1mD7lcwOMvy1KgEgtJ7SHy0D2SIW/KaDox/kRPC1P
-ksFeAS2B0Z9zAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAAtHjimMywXn893Ifu1v
-tNnL9ITMpQhsHAlg1QBVEyjGZLIjUgMhsWljVwTC1PdBrO7V0ElYbeV+LKYGwDk6
-fjBJogCLgZiUw18F8TjHC/qDsoWEsm1iB4KcTZkk0nm/2vidHK0TMLzCohR71/vN
-KS2rtiQDYGKe9EzjNSO3GlCWkVTYtJNhALa/BfDza5keRkwmldJYhlx4rQH5yVRn
-t5k87vjX0h7m8MzIwiAb2s/b9XBlM1FuFx3FxcVjBl7KtUAU7twU8v5LenjWDSH1
-D1jnKiZUUspgovhosPRqmxGNXldaX1E+RJmxdtqUVg4co/zjAbTY7C+7ZYIZBo46
-Ll0=
+MIIDjDCCAnQCAQEwDQYJKoZIhvcNAQELBQAwgYsxCzAJBgNVBAYTAktSMQ4wDAYD
+VQQIDAVTZW91bDEPMA0GA1UEBwwGVW15ZW9uMREwDwYDVQQKDAhTYW1zdW5nIDEU
+MBIGA1UECwwLT0NGIFJvb3QgQ0ExMjAwBgNVBAMMKXV1aWQ6MzEzMTMxMzEtMzEz
+MS0zMTMxLTMxMzEtMzEzMTMxMzEzMTMxMB4XDTE2MTAyODA0MjEyMloXDTI2MTAy
+NjA0MjEyMlowgYsxCzAJBgNVBAYTAktSMQ4wDAYDVQQIDAVTZW91bDEPMA0GA1UE
+BwwGVW15ZW9uMREwDwYDVQQKDAhTYW1zdW5nIDEUMBIGA1UECwwLT0NGIFJvb3Qg
+Q0ExMjAwBgNVBAMMKXV1aWQ6MzEzMTMxMzEtMzEzMS0zMTMxLTMxMzEtMzEzMTMx
+MzEzMTMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3EJwn+NfeW9Y
+RLDoOUSg45AvkqsMeNBv8ZTqWyY5nAeyESQsDejacm6dSpzMP/p5y1KBWYszKOXr
+CUtrkch8VxOtt4egiv3Tschl16W1W7ril8EEbX8zoEcuExfoLdPZhDtRl8ROdG3t
+NE0r/Fv5ubTEwW0K3JgIwykB4OAsO2aQtCuZ32cZlg5UcW3LAXpxJ7cEkMR2xhcN
+xbg0dgbyy5BiWit3grXXJBkopq/ADCRUIVzpLjxeFTVshWw9+AA1IUZaG64fkbLG
+pzdYFVsuRvMlyEwWrMm23/hT8x0eywvPX5k/N1s6I0KiE8FitVi5bgUph3iCNLE/
+1a/oLrtWyQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQDHq9X9YofW3IN8R61r0raN
+tacYMumZFZfPOEcHHGvTkPrMygUNfTM+g6XEzOvlBB4dd6UE5EsVnRkQP0wvaaJx
+3Js/zQMkAXeVRzDg/YowynuG+t4VvoQl/1uNDUKjU9z+yv+vQjNctzeKhvAJxWGO
+ZtpgIslUhMtGBjWQDNd2APf8yOcD50yVwUpcp4WGbqaaKxn+rixu8jk1NEas0EHD
+XBytAgEdOeBQplv6W+W1fG3j0PMolkWaPIvjSvMk0m11h4GR5Kyx3gRQS74gurG/
+DboAZ+DJMe7hMh4coOwnOuS8euPtxEPD3IkYVAT4aFPIvTkiri0EYimgtQd+M45f
 -----END CERTIFICATE-----
index 94d79d0..a06bc03 100644 (file)
@@ -34,6 +34,7 @@
 #include "ocstack.h"
 #include "ocpayload.h"
 #include "pinoxmcommon.h"
+#include "srmutility.h"
 
 #ifdef HAVE_WINDOWS_H
 #include <windows.h>
@@ -411,14 +412,48 @@ FILE* server_fopen(const char *path, const char *mode)
     return fopen(CRED_FILE, mode);
 }
 
+static void OtmEventHandler(void *ctx, const char *addr, uint16_t port,
+        const char* ownerId, OCOtmEvent_t event)
+{
+    (void)ctx;
+    printf("--------------------------------------\n");
+    printf("Get OTM event.\n");
+    printf("Address : %s\n", addr);
+    printf("Port : %d\n", port);
+    printf("Owner ID : %s\n", ownerId);
+
+    switch (event)
+    {
+        case OIC_OTM_READY:
+            printf("State : OIC_OTM_READY\n");
+            break;
+        case OIC_OTM_STARTED:
+            printf("State : OIC_OTM_STARTED\n");
+            break;
+        case OIC_OTM_DONE:
+            printf("State : OIC_OTM_DONE\n");
+            break;
+        case OIC_OTM_ERROR:
+            printf("State : OIC_OTM_ERROR\n");
+            break;
+        default:
+            printf("State : Unknown state.\n");
+            break;
+    }
+    printf("--------------------------------------\n");
+}
+
 int main()
 {
     struct timespec timeout;
 
     OIC_LOG(DEBUG, TAG, "OCServer is starting...");
 
+    //This function should be invoked before invoke OCInit
+    OCSetOtmEventHandler(NULL, OtmEventHandler);
+
     // Initialize Persistent Storage for SVR database
-    OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink};
+    OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink, NULL, NULL};
 
     OCRegisterPersistentStorageHandler(&ps);
 
diff --git a/resource/csdk/security/provisioning/sample/sampleserver_justworks_protectedDB.cpp b/resource/csdk/security/provisioning/sample/sampleserver_justworks_protectedDB.cpp
new file mode 100644 (file)
index 0000000..71dfdf1
--- /dev/null
@@ -0,0 +1,528 @@
+/******************************************************************
+*
+* 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.
+*
+******************************************************************/
+///////////////////////////////////////////////////////////////////////
+//NOTE :  This sample server is generated based on ocserverbasicops.cpp
+///////////////////////////////////////////////////////////////////////
+#include "iotivity_config.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+#include <signal.h>
+#include "ocstack.h"
+#include "ocpayload.h"
+#include "pinoxmcommon.h"
+
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+/** @todo stop-gap for naming issue. Windows.h does not like us to use ERROR */
+#ifdef ERROR
+#undef ERROR
+#endif //ERROR
+#endif //HAVE_WINDOWS_H
+#include "platform_features.h"
+#include "logger.h"
+
+
+#define TAG "SAMPLE_JUSTWORKS"
+
+int gQuitFlag = 0;
+
+/* Structure to represent a LED resource */
+typedef struct LEDRESOURCE{
+    OCResourceHandle handle;
+    bool state;
+    int power;
+} LEDResource;
+
+static LEDResource LED;
+// This variable determines instance number of the LED resource.
+// Used by POST method to create a new instance of LED resource.
+static int gCurrLedInstance = 0;
+#define SAMPLE_MAX_NUM_POST_INSTANCE  2
+static LEDResource gLedInstance[SAMPLE_MAX_NUM_POST_INSTANCE];
+
+char *gResourceUri= (char *)"/a/led";
+
+//Secure Virtual Resource database for Iotivity Server
+//It contains Server's Identity and the PSK credentials
+//of other devices which the server trusts
+//static char CRED_FILE[] = "oic_svr_db_server_justworks_protectedDB.dat";
+static char RESCUE_FILE[] = "oic_svr_db_server_justworks_default.dat";
+static char SVR_DB_PLAIN_FILE[] = "oic_svr_db_server_justworks_protectedDB_plain.dat";
+static char SVR_DB_ENCRYPTED_FILE[] = "oic_svr_db_server_justworks_protectedDB_encrypted.dat";
+
+/* Function that creates a new LED resource by calling the
+ * OCCreateResource() method.
+ */
+int createLEDResource (char *uri, LEDResource *ledResource, bool resourceState, int resourcePower);
+
+/* This method converts the payload to JSON format */
+OCRepPayload* constructResponse (OCEntityHandlerRequest *ehRequest);
+
+/* Following methods process the PUT, GET, POST
+ * requests
+ */
+OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
+                                         OCRepPayload **payload);
+OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
+                                         OCRepPayload **payload);
+OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
+                                        OCEntityHandlerResponse *response,
+                                        OCRepPayload **payload);
+// Initialize Persistent Storage for SVR database
+OCPersistentStorage *ps = NULL;
+
+
+/* Entity Handler callback functions */
+OCEntityHandlerResult
+OCEntityHandlerCb (OCEntityHandlerFlag flag,
+        OCEntityHandlerRequest *entityHandlerRequest,
+        void* callbackParam);
+
+unsigned char key[32] =  { 0xa5, 0x84, 0x99, 0x8d, 0x0d, 0xbd, 0xb1, 0x54,
+                           0xbb, 0xc5, 0x4f, 0xed, 0x86, 0x9a, 0x66, 0x11,
+                           0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
+                           0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5
+                         };
+
+const char *getResult(OCStackResult result) {
+    switch (result) {
+    case OC_STACK_OK:
+        return "OC_STACK_OK";
+    case OC_STACK_RESOURCE_CREATED:
+        return "OC_STACK_RESOURCE_CREATED";
+    case OC_STACK_RESOURCE_DELETED:
+        return "OC_STACK_RESOURCE_DELETED";
+    case OC_STACK_INVALID_URI:
+        return "OC_STACK_INVALID_URI";
+    case OC_STACK_INVALID_QUERY:
+        return "OC_STACK_INVALID_QUERY";
+    case OC_STACK_INVALID_IP:
+        return "OC_STACK_INVALID_IP";
+    case OC_STACK_INVALID_PORT:
+        return "OC_STACK_INVALID_PORT";
+    case OC_STACK_INVALID_CALLBACK:
+        return "OC_STACK_INVALID_CALLBACK";
+    case OC_STACK_INVALID_METHOD:
+        return "OC_STACK_INVALID_METHOD";
+    case OC_STACK_NO_MEMORY:
+        return "OC_STACK_NO_MEMORY";
+    case OC_STACK_COMM_ERROR:
+        return "OC_STACK_COMM_ERROR";
+    case OC_STACK_INVALID_PARAM:
+        return "OC_STACK_INVALID_PARAM";
+    case OC_STACK_NOTIMPL:
+        return "OC_STACK_NOTIMPL";
+    case OC_STACK_NO_RESOURCE:
+        return "OC_STACK_NO_RESOURCE";
+    case OC_STACK_RESOURCE_ERROR:
+        return "OC_STACK_RESOURCE_ERROR";
+    case OC_STACK_SLOW_RESOURCE:
+        return "OC_STACK_SLOW_RESOURCE";
+    case OC_STACK_NO_OBSERVERS:
+        return "OC_STACK_NO_OBSERVERS";
+    #ifdef WITH_PRESENCE
+    case OC_STACK_PRESENCE_STOPPED:
+        return "OC_STACK_PRESENCE_STOPPED";
+    #endif
+    case OC_STACK_ERROR:
+        return "OC_STACK_ERROR";
+    default:
+        return "UNKNOWN";
+    }
+}
+
+OCRepPayload* getPayload(const char* uri, int64_t power, bool state)
+{
+    OCRepPayload* payload = OCRepPayloadCreate();
+    if(!payload)
+    {
+        OIC_LOG(ERROR, TAG, "Failed to allocate Payload");
+        return NULL;
+    }
+
+    OCRepPayloadSetUri(payload, uri);
+    OCRepPayloadSetPropBool(payload, "state", state);
+    OCRepPayloadSetPropInt(payload, "power", power);
+
+    return payload;
+}
+
+//This function takes the request as an input and returns the response
+OCRepPayload* constructResponse (OCEntityHandlerRequest *ehRequest)
+{
+    if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
+    {
+        OIC_LOG(ERROR, TAG, "Incoming payload not a representation");
+        return NULL;
+    }
+
+    OCRepPayload* input = (OCRepPayload*)(ehRequest->payload);
+
+    LEDResource *currLEDResource = &LED;
+
+    if (ehRequest->resource == gLedInstance[0].handle)
+    {
+        currLEDResource = &gLedInstance[0];
+        gResourceUri = (char *) "/a/led/0";
+    }
+    else if (ehRequest->resource == gLedInstance[1].handle)
+    {
+        currLEDResource = &gLedInstance[1];
+        gResourceUri = (char *) "/a/led/1";
+    }
+
+    if(OC_REST_PUT == ehRequest->method)
+    {
+        // Get pointer to query
+        int64_t pow;
+        if(OCRepPayloadGetPropInt(input, "power", &pow))
+        {
+            currLEDResource->power =pow;
+        }
+
+        bool state;
+        if(OCRepPayloadGetPropBool(input, "state", &state))
+        {
+            currLEDResource->state = state;
+        }
+    }
+
+    return getPayload(gResourceUri, currLEDResource->power, currLEDResource->state);
+}
+
+OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
+        OCRepPayload **payload)
+{
+    OCEntityHandlerResult ehResult;
+
+    OCRepPayload *getResp = constructResponse(ehRequest);
+
+    if(getResp)
+    {
+        *payload = getResp;
+        ehResult = OC_EH_OK;
+    }
+    else
+    {
+        ehResult = OC_EH_ERROR;
+    }
+
+    return ehResult;
+}
+
+OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
+        OCRepPayload **payload)
+{
+    OCEntityHandlerResult ehResult;
+
+    OCRepPayload *putResp = constructResponse(ehRequest);
+
+    if(putResp)
+    {
+        *payload = putResp;
+        ehResult = OC_EH_OK;
+    }
+    else
+    {
+        ehResult = OC_EH_ERROR;
+    }
+
+    return ehResult;
+}
+
+OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
+        OCEntityHandlerResponse *response, OCRepPayload **payload)
+{
+    OCRepPayload *respPLPost_led = NULL;
+    OCEntityHandlerResult ehResult = OC_EH_OK;
+
+    /*
+     * The entity handler determines how to process a POST request.
+     * Per the REST paradigm, POST can also be used to update representation of existing
+     * resource or create a new resource.
+     * In the sample below, if the POST is for /a/led then a new instance of the LED
+     * resource is created with default representation (if representation is included in
+     * POST payload it can be used as initial values) as long as the instance is
+     * lesser than max new instance count. Once max instance count is reached, POST on
+     * /a/led updated the representation of /a/led (just like PUT)
+     */
+
+    if (ehRequest->resource == LED.handle)
+    {
+        if (gCurrLedInstance < SAMPLE_MAX_NUM_POST_INSTANCE)
+        {
+            // Create new LED instance
+            char newLedUri[15] = "/a/led/";
+            int newLedUriLength = strlen(newLedUri);
+            snprintf (newLedUri + newLedUriLength, sizeof(newLedUri)-newLedUriLength, "%d", gCurrLedInstance);
+
+            respPLPost_led = OCRepPayloadCreate();
+            OCRepPayloadSetUri(respPLPost_led, gResourceUri);
+            OCRepPayloadSetPropString(respPLPost_led, "createduri", newLedUri);
+
+            if (0 == createLEDResource (newLedUri, &gLedInstance[gCurrLedInstance], false, 0))
+            {
+                OIC_LOG (INFO, TAG, "Created new LED instance");
+                gLedInstance[gCurrLedInstance].state = 0;
+                gLedInstance[gCurrLedInstance].power = 0;
+                gCurrLedInstance++;
+                strncpy ((char *)response->resourceUri, newLedUri, sizeof(response->resourceUri));
+                ehResult = OC_EH_RESOURCE_CREATED;
+            }
+        }
+        else
+        {
+            respPLPost_led = constructResponse(ehRequest);
+        }
+    }
+    else
+    {
+        for (int i = 0; i < SAMPLE_MAX_NUM_POST_INSTANCE; i++)
+        {
+            if (ehRequest->resource == gLedInstance[i].handle)
+            {
+                if (i == 0)
+                {
+                    respPLPost_led = constructResponse(ehRequest);
+                    break;
+                }
+                else if (i == 1)
+                {
+                    respPLPost_led = constructResponse(ehRequest);
+                }
+            }
+        }
+    }
+
+    if (respPLPost_led != NULL)
+    {
+        *payload = respPLPost_led;
+        ehResult = OC_EH_OK;
+    }
+    else
+    {
+        OIC_LOG_V (INFO, TAG, "Payload was NULL");
+        ehResult = OC_EH_ERROR;
+    }
+
+    return ehResult;
+}
+
+OCEntityHandlerResult
+OCEntityHandlerCb (OCEntityHandlerFlag flag,
+        OCEntityHandlerRequest *entityHandlerRequest,
+        void* callbackParam)
+{
+    OIC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag);
+    (void)callbackParam;
+    OCEntityHandlerResult ehResult = OC_EH_ERROR;
+
+    OCEntityHandlerResponse response;
+    memset(&response, 0, sizeof(response));
+
+    // Validate pointer
+    if (!entityHandlerRequest)
+    {
+        OIC_LOG (ERROR, TAG, "Invalid request pointer");
+        return OC_EH_ERROR;
+    }
+
+    OCRepPayload* payload = NULL;
+
+    if (flag & OC_REQUEST_FLAG)
+    {
+        OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
+        if (entityHandlerRequest)
+        {
+            if (OC_REST_GET == entityHandlerRequest->method)
+            {
+                OIC_LOG (INFO, TAG, "Received OC_REST_GET from client");
+                ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
+            }
+            else if (OC_REST_PUT == entityHandlerRequest->method)
+            {
+                OIC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
+                ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
+            }
+            else if (OC_REST_POST == entityHandlerRequest->method)
+            {
+                OIC_LOG (INFO, TAG, "Received OC_REST_POST from client");
+                ehResult = ProcessPostRequest (entityHandlerRequest, &response, &payload);
+            }
+            else
+            {
+                OIC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
+                        entityHandlerRequest->method);
+                ehResult = OC_EH_ERROR;
+            }
+
+            if (ehResult == OC_EH_OK && ehResult != OC_EH_FORBIDDEN)
+            {
+                // Format the response.  Note this requires some info about the request
+                response.requestHandle = entityHandlerRequest->requestHandle;
+                response.resourceHandle = entityHandlerRequest->resource;
+                response.ehResult = ehResult;
+                response.payload = (OCPayload*)(payload);
+                response.numSendVendorSpecificHeaderOptions = 0;
+                memset(response.sendVendorSpecificHeaderOptions, 0,
+                       sizeof(response.sendVendorSpecificHeaderOptions));
+                memset(response.resourceUri, 0, sizeof(response.resourceUri));
+                // Indicate that response is NOT in a persistent buffer
+                response.persistentBufferFlag = 0;
+
+                // Send the response
+                if (OCDoResponse(&response) != OC_STACK_OK)
+                {
+                    OIC_LOG(ERROR, TAG, "Error sending response");
+                    ehResult = OC_EH_ERROR;
+                }
+            }
+        }
+    }
+
+    OCPayloadDestroy(response.payload);
+    return ehResult;
+}
+
+/* SIGINT handler: set gQuitFlag to 1 for graceful termination */
+void handleSigInt(int signum)
+{
+    if (signum == SIGINT)
+    {
+        gQuitFlag = 1;
+    }
+}
+
+FILE* plain_fopen(const char *path, const char *mode)
+{
+    (void)path;
+    return fopen(SVR_DB_PLAIN_FILE, mode);
+}
+
+int plain_unlink(const char *path)
+{
+    OIC_LOG(INFO, TAG, "plain DB is removed");
+    (void)path;
+    return unlink(SVR_DB_PLAIN_FILE);
+}
+
+FILE* encrypted_fopen(const char *path, const char *mode)
+{
+    (void)path;
+    return fopen(SVR_DB_ENCRYPTED_FILE, mode);
+}
+
+FILE* rescue_fopen(const char *path, const char *mode)
+{
+    (void)path;
+    return fopen(RESCUE_FILE, mode);
+}
+
+int main()
+{
+    OCStackResult ret;
+    struct timespec timeout;
+
+    OIC_LOG(DEBUG, TAG, "OCServer is starting...");
+
+    OCPersistentStorage psPlain = {plain_fopen, fread, NULL, fclose, plain_unlink, NULL, NULL};
+    OCPersistentStorage psEnc = {encrypted_fopen, fread, fwrite, fclose,
+        unlink, OCEncrypt, OCDecrypt};
+    OCPersistentStorage psRescue = {rescue_fopen, fread, NULL, fclose, NULL, NULL, NULL};
+
+    ret = OCSetSecurePSI(key, &psPlain, &psEnc, &psRescue);
+    if (OC_STACK_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "OCSetSecurePSI() error");
+        return 1;
+    }
+
+    ret = OCRegisterPersistentStorageHandler(&psEnc);
+    if (OC_STACK_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "OCRegisterPersistentStorageHandler() error");
+        return 1;
+    }
+
+    if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
+    {
+        OIC_LOG(ERROR, TAG, "OCStack init error");
+        return 1;
+    }
+
+    /*
+     * Declare and create the example resource: LED
+     */
+    createLEDResource(gResourceUri, &LED, false, 0);
+
+    timeout.tv_sec  = 0;
+    timeout.tv_nsec = 100000000L;
+
+    // Break from loop with Ctrl-C
+    OIC_LOG(INFO, TAG, "Entering ocserver main loop...");
+    signal(SIGINT, handleSigInt);
+    while (!gQuitFlag)
+    {
+        if (OCProcess() != OC_STACK_OK)
+        {
+            OIC_LOG(ERROR, TAG, "OCStack process error");
+            return 1;
+        }
+        nanosleep(&timeout, NULL);
+    }
+
+    OIC_LOG(INFO, TAG, "Exiting ocserver main loop...");
+
+    if (OCStop() != OC_STACK_OK)
+    {
+        OIC_LOG(ERROR, TAG, "OCStack process error");
+    }
+
+    return 0;
+}
+
+int createLEDResource (char *uri, LEDResource *ledResource, bool resourceState, int resourcePower)
+{
+    if (!uri)
+    {
+        OIC_LOG(ERROR, TAG, "Resource URI cannot be NULL");
+        return -1;
+    }
+
+    ledResource->state = resourceState;
+    ledResource->power= resourcePower;
+    OCStackResult res = OCCreateResource(&(ledResource->handle),
+            "core.led",
+            OC_RSRVD_INTERFACE_DEFAULT,
+            uri,
+            OCEntityHandlerCb,
+            NULL,
+            OC_DISCOVERABLE|OC_OBSERVABLE | OC_SECURE);
+    OIC_LOG_V(INFO, TAG, "Created LED resource with result: %s", getResult(res));
+
+    return 0;
+}
index c347a42..90ed672 100644 (file)
@@ -43,7 +43,9 @@
 #endif //HAVE_WINDOWS_H
 #include "platform_features.h"
 #include "logger.h"
-
+#include "pkix_interface.h"
+#include "hw_emul/hw_interface.h"
+#include "oxmverifycommon.h"
 
 #define TAG "SAMPLE_MANUFACTURER_CERT"
 
@@ -403,20 +405,78 @@ void handleSigInt(int signum)
     }
 }
 
+OCStackResult confirmCB(void * ctx)
+{
+    OC_UNUSED(ctx);
+    for (;;)
+    {
+        int userConfirm;
+
+        printf("   > Press 1 for confirmation\n");
+        printf("   > Press 0 otherwise\n");
+
+        for (int ret=0; 1!=ret; )
+        {
+            ret = scanf("%d", &userConfirm);
+            for (; 0x20<=getchar(); );  // for removing overflow garbage
+                                        // '0x20<=code' is character region
+        }
+        if (1 == userConfirm)
+        {
+            break;
+        }
+        else if (0 == userConfirm)
+        {
+            return OC_STACK_USER_DENIED_REQ;
+        }
+        printf("   Entered Wrong Number. Please Enter Again\n");
+    }
+    return OC_STACK_OK;
+}
+
 FILE* server_fopen(const char *path, const char *mode)
 {
     (void)path;
     return fopen(CRED_FILE, mode);
 }
 
-int main()
+int main(int argc, char **argv)
 {
     struct timespec timeout;
 
     OIC_LOG(DEBUG, TAG, "OCServer is starting...");
 
+    int opt;
+    char cert_file[4096] = {0,};
+    char key_file[4096] = {0,};
+    char key_pass[32] = {0,};
+
+    // Set options
+    while ((opt = getopt(argc, argv, "c:k:p:")) != -1)
+    {
+        switch (opt)
+        {
+            case 'c':
+                strncpy(cert_file, optarg, sizeof(cert_file) - 1);
+                printf("Set own certificate file : %s\n", cert_file);
+                break;
+            case 'k':
+                strncpy(key_file, optarg, sizeof(key_file) - 1);
+                printf("Set private key file : %s\n", key_file);
+                break;
+            case 'p':
+                strncpy(key_pass, optarg, sizeof(key_pass) - 1);
+                printf("Set private key password : %s\n", key_pass);
+                break;
+            default:
+                printf("Not set any options\n");
+        }
+    }
+
     // Initialize Persistent Storage for SVR database
-    OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink};
+    OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink, NULL, NULL};
+
+    SetUserConfirmCB(NULL, confirmCB);
 
     OCRegisterPersistentStorageHandler(&ps);
 
@@ -426,6 +486,31 @@ int main()
         return 0;
     }
 
+    // Register HW secure storage callback
+    if (0 < strlen(cert_file) && 0 < strlen(key_file))
+    {
+        if (0 == SSemulSetCertkeyFilepath(cert_file, key_file, key_pass))
+        {
+            if (0 != SetHwPkixCallbacks(HWGetKeyContext,
+                                                          HWFreeKeyContext,
+                                                          HWGetOwnCertificateChain,
+                                                          HWSetupPkContext))
+            {
+                printf("Fail to regist HW Pkix Callbacks");
+            }
+        }
+        else
+        {
+            printf("Fail to set cert/key file path");
+        }
+    }
+    else
+    {
+        printf("\n    [ Not set any mfg cert options ]\n");
+        printf("    Possible options: %s [-c certificate file path]"
+                " [-k key file path] [-p key password]\n\n", argv[0]);
+    }
+
     /*
      * Declare and create the example resource: LED
      */
diff --git a/resource/csdk/security/provisioning/sample/sampleserver_mvjustworks.cpp b/resource/csdk/security/provisioning/sample/sampleserver_mvjustworks.cpp
new file mode 100644 (file)
index 0000000..f4f2a1f
--- /dev/null
@@ -0,0 +1,531 @@
+/******************************************************************
+*
+* 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.
+*
+******************************************************************/
+///////////////////////////////////////////////////////////////////////
+//NOTE :  This sample server is generated based on ocserverbasicops.cpp
+///////////////////////////////////////////////////////////////////////
+#include "iotivity_config.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+#include <signal.h>
+#include "ocstack.h"
+#include "ocpayload.h"
+#include "pinoxmcommon.h"
+#include "oxmverifycommon.h"
+
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+/** @todo stop-gap for naming issue. Windows.h does not like us to use ERROR */
+#ifdef ERROR
+#undef ERROR
+#endif //ERROR
+#endif //HAVE_WINDOWS_H
+#include "platform_features.h"
+#include "logger.h"
+
+
+#define TAG "SAMPLE_MV_JUSTWORKS"
+
+int gQuitFlag = 0;
+
+/* Structure to represent a LED resource */
+typedef struct LEDRESOURCE{
+    OCResourceHandle handle;
+    bool state;
+    int power;
+} LEDResource;
+
+static LEDResource LED;
+// This variable determines instance number of the LED resource.
+// Used by POST method to create a new instance of LED resource.
+static int gCurrLedInstance = 0;
+#define SAMPLE_MAX_NUM_POST_INSTANCE  2
+static LEDResource gLedInstance[SAMPLE_MAX_NUM_POST_INSTANCE];
+
+char *gResourceUri= (char *)"/a/led";
+
+//Secure Virtual Resource database for Iotivity Server
+//It contains Server's Identity and the PSK credentials
+//of other devices which the server trusts
+static char CRED_FILE[] = "oic_svr_db_server_mvjustworks.dat";
+
+/* Function that creates a new LED resource by calling the
+ * OCCreateResource() method.
+ */
+int createLEDResource (char *uri, LEDResource *ledResource, bool resourceState, int resourcePower);
+
+/* This method converts the payload to JSON format */
+OCRepPayload* constructResponse (OCEntityHandlerRequest *ehRequest);
+
+/* Following methods process the PUT, GET, POST
+ * requests
+ */
+OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
+                                         OCRepPayload **payload);
+OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
+                                         OCRepPayload **payload);
+OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
+                                        OCEntityHandlerResponse *response,
+                                        OCRepPayload **payload);
+
+/* Entity Handler callback functions */
+OCEntityHandlerResult
+OCEntityHandlerCb (OCEntityHandlerFlag flag,
+        OCEntityHandlerRequest *entityHandlerRequest,
+        void* callbackParam);
+
+const char *getResult(OCStackResult result) {
+    switch (result) {
+    case OC_STACK_OK:
+        return "OC_STACK_OK";
+    case OC_STACK_RESOURCE_CREATED:
+        return "OC_STACK_RESOURCE_CREATED";
+    case OC_STACK_RESOURCE_DELETED:
+        return "OC_STACK_RESOURCE_DELETED";
+    case OC_STACK_INVALID_URI:
+        return "OC_STACK_INVALID_URI";
+    case OC_STACK_INVALID_QUERY:
+        return "OC_STACK_INVALID_QUERY";
+    case OC_STACK_INVALID_IP:
+        return "OC_STACK_INVALID_IP";
+    case OC_STACK_INVALID_PORT:
+        return "OC_STACK_INVALID_PORT";
+    case OC_STACK_INVALID_CALLBACK:
+        return "OC_STACK_INVALID_CALLBACK";
+    case OC_STACK_INVALID_METHOD:
+        return "OC_STACK_INVALID_METHOD";
+    case OC_STACK_NO_MEMORY:
+        return "OC_STACK_NO_MEMORY";
+    case OC_STACK_COMM_ERROR:
+        return "OC_STACK_COMM_ERROR";
+    case OC_STACK_INVALID_PARAM:
+        return "OC_STACK_INVALID_PARAM";
+    case OC_STACK_NOTIMPL:
+        return "OC_STACK_NOTIMPL";
+    case OC_STACK_NO_RESOURCE:
+        return "OC_STACK_NO_RESOURCE";
+    case OC_STACK_RESOURCE_ERROR:
+        return "OC_STACK_RESOURCE_ERROR";
+    case OC_STACK_SLOW_RESOURCE:
+        return "OC_STACK_SLOW_RESOURCE";
+    case OC_STACK_NO_OBSERVERS:
+        return "OC_STACK_NO_OBSERVERS";
+    #ifdef WITH_PRESENCE
+    case OC_STACK_PRESENCE_STOPPED:
+        return "OC_STACK_PRESENCE_STOPPED";
+    #endif
+    case OC_STACK_ERROR:
+        return "OC_STACK_ERROR";
+    default:
+        return "UNKNOWN";
+    }
+}
+
+OCRepPayload* getPayload(const char* uri, int64_t power, bool state)
+{
+    OCRepPayload* payload = OCRepPayloadCreate();
+    if(!payload)
+    {
+        OIC_LOG(ERROR, TAG, "Failed to allocate Payload");
+        return NULL;
+    }
+
+    OCRepPayloadSetUri(payload, uri);
+    OCRepPayloadSetPropBool(payload, "state", state);
+    OCRepPayloadSetPropInt(payload, "power", power);
+
+    return payload;
+}
+
+//This function takes the request as an input and returns the response
+OCRepPayload* constructResponse (OCEntityHandlerRequest *ehRequest)
+{
+    if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
+    {
+        OIC_LOG(ERROR, TAG, "Incoming payload not a representation");
+        return NULL;
+    }
+
+    OCRepPayload* input = (OCRepPayload*)(ehRequest->payload);
+
+    LEDResource *currLEDResource = &LED;
+
+    if (ehRequest->resource == gLedInstance[0].handle)
+    {
+        currLEDResource = &gLedInstance[0];
+        gResourceUri = (char *) "/a/led/0";
+    }
+    else if (ehRequest->resource == gLedInstance[1].handle)
+    {
+        currLEDResource = &gLedInstance[1];
+        gResourceUri = (char *) "/a/led/1";
+    }
+
+    if(OC_REST_PUT == ehRequest->method)
+    {
+        // Get pointer to query
+        int64_t pow;
+        if(OCRepPayloadGetPropInt(input, "power", &pow))
+        {
+            currLEDResource->power =pow;
+        }
+
+        bool state;
+        if(OCRepPayloadGetPropBool(input, "state", &state))
+        {
+            currLEDResource->state = state;
+        }
+    }
+
+    return getPayload(gResourceUri, currLEDResource->power, currLEDResource->state);
+}
+
+OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
+        OCRepPayload **payload)
+{
+    OCEntityHandlerResult ehResult;
+
+    OCRepPayload *getResp = constructResponse(ehRequest);
+
+    if(getResp)
+    {
+        *payload = getResp;
+        ehResult = OC_EH_OK;
+    }
+    else
+    {
+        ehResult = OC_EH_ERROR;
+    }
+
+    return ehResult;
+}
+
+OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
+        OCRepPayload **payload)
+{
+    OCEntityHandlerResult ehResult;
+
+    OCRepPayload *putResp = constructResponse(ehRequest);
+
+    if(putResp)
+    {
+        *payload = putResp;
+        ehResult = OC_EH_OK;
+    }
+    else
+    {
+        ehResult = OC_EH_ERROR;
+    }
+
+    return ehResult;
+}
+
+OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
+        OCEntityHandlerResponse *response, OCRepPayload **payload)
+{
+    OCRepPayload *respPLPost_led = NULL;
+    OCEntityHandlerResult ehResult = OC_EH_OK;
+
+    /*
+     * The entity handler determines how to process a POST request.
+     * Per the REST paradigm, POST can also be used to update representation of existing
+     * resource or create a new resource.
+     * In the sample below, if the POST is for /a/led then a new instance of the LED
+     * resource is created with default representation (if representation is included in
+     * POST payload it can be used as initial values) as long as the instance is
+     * lesser than max new instance count. Once max instance count is reached, POST on
+     * /a/led updated the representation of /a/led (just like PUT)
+     */
+
+    if (ehRequest->resource == LED.handle)
+    {
+        if (gCurrLedInstance < SAMPLE_MAX_NUM_POST_INSTANCE)
+        {
+            // Create new LED instance
+            char newLedUri[15] = "/a/led/";
+            int newLedUriLength = strlen(newLedUri);
+            snprintf (newLedUri + newLedUriLength, sizeof(newLedUri)-newLedUriLength, "%d", gCurrLedInstance);
+
+            respPLPost_led = OCRepPayloadCreate();
+            OCRepPayloadSetUri(respPLPost_led, gResourceUri);
+            OCRepPayloadSetPropString(respPLPost_led, "createduri", newLedUri);
+
+            if (0 == createLEDResource (newLedUri, &gLedInstance[gCurrLedInstance], false, 0))
+            {
+                OIC_LOG (INFO, TAG, "Created new LED instance");
+                gLedInstance[gCurrLedInstance].state = 0;
+                gLedInstance[gCurrLedInstance].power = 0;
+                gCurrLedInstance++;
+                strncpy ((char *)response->resourceUri, newLedUri, MAX_URI_LENGTH);
+                ehResult = OC_EH_RESOURCE_CREATED;
+            }
+        }
+        else
+        {
+            respPLPost_led = constructResponse(ehRequest);
+        }
+    }
+    else
+    {
+        for (int i = 0; i < SAMPLE_MAX_NUM_POST_INSTANCE; i++)
+        {
+            if (ehRequest->resource == gLedInstance[i].handle)
+            {
+                if (i == 0)
+                {
+                    respPLPost_led = constructResponse(ehRequest);
+                    break;
+                }
+                else if (i == 1)
+                {
+                    respPLPost_led = constructResponse(ehRequest);
+                }
+            }
+        }
+    }
+
+    if (respPLPost_led != NULL)
+    {
+        *payload = respPLPost_led;
+        ehResult = OC_EH_OK;
+    }
+    else
+    {
+        OIC_LOG_V (INFO, TAG, "Payload was NULL");
+        ehResult = OC_EH_ERROR;
+    }
+
+    return ehResult;
+}
+
+OCEntityHandlerResult
+OCEntityHandlerCb (OCEntityHandlerFlag flag,
+        OCEntityHandlerRequest *entityHandlerRequest,
+        void* callbackParam)
+{
+    OIC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag);
+    (void)callbackParam;
+    OCEntityHandlerResult ehResult = OC_EH_ERROR;
+
+    OCEntityHandlerResponse response;
+    memset(&response, 0, sizeof(response));
+
+    // Validate pointer
+    if (!entityHandlerRequest)
+    {
+        OIC_LOG (ERROR, TAG, "Invalid request pointer");
+        return OC_EH_ERROR;
+    }
+
+    OCRepPayload* payload = NULL;
+
+    if (flag & OC_REQUEST_FLAG)
+    {
+        OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
+        if (entityHandlerRequest)
+        {
+            if (OC_REST_GET == entityHandlerRequest->method)
+            {
+                OIC_LOG (INFO, TAG, "Received OC_REST_GET from client");
+                ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
+            }
+            else if (OC_REST_PUT == entityHandlerRequest->method)
+            {
+                OIC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
+                ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
+            }
+            else if (OC_REST_POST == entityHandlerRequest->method)
+            {
+                OIC_LOG (INFO, TAG, "Received OC_REST_POST from client");
+                ehResult = ProcessPostRequest (entityHandlerRequest, &response, &payload);
+            }
+            else
+            {
+                OIC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
+                        entityHandlerRequest->method);
+                ehResult = OC_EH_ERROR;
+            }
+
+            if (ehResult == OC_EH_OK && ehResult != OC_EH_FORBIDDEN)
+            {
+                // Format the response.  Note this requires some info about the request
+                response.requestHandle = entityHandlerRequest->requestHandle;
+                response.resourceHandle = entityHandlerRequest->resource;
+                response.ehResult = ehResult;
+                response.payload = (OCPayload*)(payload);
+                response.numSendVendorSpecificHeaderOptions = 0;
+                memset(response.sendVendorSpecificHeaderOptions, 0,
+                       sizeof(response.sendVendorSpecificHeaderOptions));
+                memset(response.resourceUri, 0, sizeof(response.resourceUri));
+                // Indicate that response is NOT in a persistent buffer
+                response.persistentBufferFlag = 0;
+
+                // Send the response
+                if (OCDoResponse(&response) != OC_STACK_OK)
+                {
+                    OIC_LOG(ERROR, TAG, "Error sending response");
+                    ehResult = OC_EH_ERROR;
+                }
+            }
+        }
+    }
+
+    OCPayloadDestroy(response.payload);
+    return ehResult;
+}
+
+OCStackResult displayNumCB(void * ctx, uint8_t mutualVerifNum[MUTUAL_VERIF_NUM_LEN])
+{
+    OC_UNUSED(ctx);
+    OIC_LOG(INFO, TAG, "IN displayNumCB");
+    OIC_LOG(INFO, TAG, "############ mutualVerifNum ############");
+    OIC_LOG_BUFFER(INFO, TAG, mutualVerifNum, MUTUAL_VERIF_NUM_LEN);
+    OIC_LOG(INFO, TAG, "############ mutualVerifNum ############");
+    OIC_LOG(INFO, TAG, "OUT displayNumCB");
+    return OC_STACK_OK;
+}
+
+OCStackResult confirmNumCB(void * ctx)
+{
+    OC_UNUSED(ctx);
+    for (;;)
+    {
+        int userConfirm;
+
+        printf("   > Press 1 for confirmation\n");
+        printf("   > Press 0 otherwise\n");
+
+        for (int ret=0; 1!=ret; )
+        {
+            ret = scanf("%d", &userConfirm);
+            for (; 0x20<=getchar(); );  // for removing overflow garbage
+                                        // '0x20<=code' is character region
+        }
+        if (1 == userConfirm)
+        {
+            break;
+        }
+        else if (0 == userConfirm)
+        {
+            return OC_STACK_ERROR;
+        }
+        printf("   Entered Wrong Number. Please Enter Again\n");
+    }
+    return OC_STACK_OK;
+}
+
+/* SIGINT handler: set gQuitFlag to 1 for graceful termination */
+void handleSigInt(int signum)
+{
+    if (signum == SIGINT)
+    {
+        gQuitFlag = 1;
+    }
+}
+
+FILE* server_fopen(const char *path, const char *mode)
+{
+    (void)path;
+    return fopen(CRED_FILE, mode);
+}
+
+int main()
+{
+    struct timespec timeout;
+
+    OIC_LOG(DEBUG, TAG, "OCServer is starting...");
+
+    // Set callbacks for verification
+    SetDisplayNumCB(NULL, displayNumCB);
+    SetUserConfirmCB(NULL, confirmNumCB);
+
+    // Set Verification Option for ownership transfer
+    // Currently, BOTH display AND confirm
+    SetVerifyOption((VerifyOptionBitmask_t)(DISPLAY_NUM | USER_CONFIRM));
+
+    // Initialize Persistent Storage for SVR database
+    OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink, NULL, NULL};
+
+    OCRegisterPersistentStorageHandler(&ps);
+
+    if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
+    {
+        OIC_LOG(ERROR, TAG, "OCStack init error");
+        return 0;
+    }
+
+    /*
+     * Declare and create the example resource: LED
+     */
+    createLEDResource(gResourceUri, &LED, false, 0);
+
+    timeout.tv_sec  = 0;
+    timeout.tv_nsec = 100000000L;
+
+    // Break from loop with Ctrl-C
+    OIC_LOG(INFO, TAG, "Entering ocserver main loop...");
+    signal(SIGINT, handleSigInt);
+    while (!gQuitFlag)
+    {
+        if (OCProcess() != OC_STACK_OK)
+        {
+            OIC_LOG(ERROR, TAG, "OCStack process error");
+            return 0;
+        }
+        nanosleep(&timeout, NULL);
+    }
+
+    OIC_LOG(INFO, TAG, "Exiting ocserver main loop...");
+
+    if (OCStop() != OC_STACK_OK)
+    {
+        OIC_LOG(ERROR, TAG, "OCStack process error");
+    }
+
+    return 0;
+}
+
+int createLEDResource (char *uri, LEDResource *ledResource, bool resourceState, int resourcePower)
+{
+    if (!uri)
+    {
+        OIC_LOG(ERROR, TAG, "Resource URI cannot be NULL");
+        return -1;
+    }
+
+    ledResource->state = resourceState;
+    ledResource->power= resourcePower;
+    OCStackResult res = OCCreateResource(&(ledResource->handle),
+            "core.led",
+            OC_RSRVD_INTERFACE_DEFAULT,
+            uri,
+            OCEntityHandlerCb,
+            NULL,
+            OC_DISCOVERABLE|OC_OBSERVABLE | OC_SECURE);
+    OIC_LOG_V(INFO, TAG, "Created LED resource with result: %s", getResult(res));
+
+    return 0;
+}
diff --git a/resource/csdk/security/provisioning/sample/sampleserver_preconfpin.cpp b/resource/csdk/security/provisioning/sample/sampleserver_preconfpin.cpp
new file mode 100644 (file)
index 0000000..0e315ec
--- /dev/null
@@ -0,0 +1,482 @@
+/******************************************************************
+*
+* 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.
+*
+******************************************************************/
+///////////////////////////////////////////////////////////////////////
+//NOTE :  This sample server is generated based on ocserverbasicops.cpp
+///////////////////////////////////////////////////////////////////////
+#include "iotivity_config.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+#include <signal.h>
+#include "ocstack.h"
+#include "ocpayload.h"
+#include "pinoxmcommon.h"
+
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+/** @todo stop-gap for naming issue. Windows.h does not like us to use ERROR */
+#ifdef ERROR
+#undef ERROR
+#endif //ERROR
+#endif //HAVE_WINDOWS_H
+#include "platform_features.h"
+#include "logger.h"
+
+
+#define TAG "SAMPLE_PRECONF_PIN"
+
+int gQuitFlag = 0;
+
+/* Structure to represent a LED resource */
+typedef struct LEDRESOURCE{
+    OCResourceHandle handle;
+    bool state;
+    int power;
+} LEDResource;
+
+static LEDResource LED;
+// This variable determines instance number of the LED resource.
+// Used by POST method to create a new instance of LED resource.
+static int gCurrLedInstance = 0;
+#define SAMPLE_MAX_NUM_POST_INSTANCE  2
+static LEDResource gLedInstance[SAMPLE_MAX_NUM_POST_INSTANCE];
+
+char *gResourceUri= (char *)"/a/led";
+
+//Secure Virtual Resource database for Iotivity Server
+//It contains Server's Identity and the PSK credentials
+//of other devices which the server trusts
+static char CRED_FILE[] = "oic_svr_db_server_preconfpin.dat";
+
+/* Function that creates a new LED resource by calling the
+ * OCCreateResource() method.
+ */
+int createLEDResource (char *uri, LEDResource *ledResource, bool resourceState, int resourcePower);
+
+/* This method converts the payload to JSON format */
+OCRepPayload* constructResponse (OCEntityHandlerRequest *ehRequest);
+
+/* Following methods process the PUT, GET, POST
+ * requests
+ */
+OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
+                                         OCRepPayload **payload);
+OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
+                                         OCRepPayload **payload);
+OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
+                                        OCEntityHandlerResponse *response,
+                                        OCRepPayload **payload);
+
+/* Entity Handler callback functions */
+OCEntityHandlerResult
+OCEntityHandlerCb (OCEntityHandlerFlag flag,
+        OCEntityHandlerRequest *entityHandlerRequest,
+        void* callbackParam);
+
+const char *getResult(OCStackResult result) {
+    switch (result) {
+    case OC_STACK_OK:
+        return "OC_STACK_OK";
+    case OC_STACK_RESOURCE_CREATED:
+        return "OC_STACK_RESOURCE_CREATED";
+    case OC_STACK_RESOURCE_DELETED:
+        return "OC_STACK_RESOURCE_DELETED";
+    case OC_STACK_INVALID_URI:
+        return "OC_STACK_INVALID_URI";
+    case OC_STACK_INVALID_QUERY:
+        return "OC_STACK_INVALID_QUERY";
+    case OC_STACK_INVALID_IP:
+        return "OC_STACK_INVALID_IP";
+    case OC_STACK_INVALID_PORT:
+        return "OC_STACK_INVALID_PORT";
+    case OC_STACK_INVALID_CALLBACK:
+        return "OC_STACK_INVALID_CALLBACK";
+    case OC_STACK_INVALID_METHOD:
+        return "OC_STACK_INVALID_METHOD";
+    case OC_STACK_NO_MEMORY:
+        return "OC_STACK_NO_MEMORY";
+    case OC_STACK_COMM_ERROR:
+        return "OC_STACK_COMM_ERROR";
+    case OC_STACK_INVALID_PARAM:
+        return "OC_STACK_INVALID_PARAM";
+    case OC_STACK_NOTIMPL:
+        return "OC_STACK_NOTIMPL";
+    case OC_STACK_NO_RESOURCE:
+        return "OC_STACK_NO_RESOURCE";
+    case OC_STACK_RESOURCE_ERROR:
+        return "OC_STACK_RESOURCE_ERROR";
+    case OC_STACK_SLOW_RESOURCE:
+        return "OC_STACK_SLOW_RESOURCE";
+    case OC_STACK_NO_OBSERVERS:
+        return "OC_STACK_NO_OBSERVERS";
+    #ifdef WITH_PRESENCE
+    case OC_STACK_PRESENCE_STOPPED:
+        return "OC_STACK_PRESENCE_STOPPED";
+    #endif
+    case OC_STACK_ERROR:
+        return "OC_STACK_ERROR";
+    default:
+        return "UNKNOWN";
+    }
+}
+
+OCRepPayload* getPayload(const char* uri, int64_t power, bool state)
+{
+    OCRepPayload* payload = OCRepPayloadCreate();
+    if(!payload)
+    {
+        OIC_LOG(ERROR, TAG, "Failed to allocate Payload");
+        return NULL;
+    }
+
+    OCRepPayloadSetUri(payload, uri);
+    OCRepPayloadSetPropBool(payload, "state", state);
+    OCRepPayloadSetPropInt(payload, "power", power);
+
+    return payload;
+}
+
+//This function takes the request as an input and returns the response
+OCRepPayload* constructResponse (OCEntityHandlerRequest *ehRequest)
+{
+    if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
+    {
+        OIC_LOG(ERROR, TAG, "Incoming payload not a representation");
+        return NULL;
+    }
+
+    OCRepPayload* input = (OCRepPayload*)(ehRequest->payload);
+
+    LEDResource *currLEDResource = &LED;
+
+    if (ehRequest->resource == gLedInstance[0].handle)
+    {
+        currLEDResource = &gLedInstance[0];
+        gResourceUri = (char *) "/a/led/0";
+    }
+    else if (ehRequest->resource == gLedInstance[1].handle)
+    {
+        currLEDResource = &gLedInstance[1];
+        gResourceUri = (char *) "/a/led/1";
+    }
+
+    if(OC_REST_PUT == ehRequest->method)
+    {
+        // Get pointer to query
+        int64_t pow;
+        if(OCRepPayloadGetPropInt(input, "power", &pow))
+        {
+            currLEDResource->power =pow;
+        }
+
+        bool state;
+        if(OCRepPayloadGetPropBool(input, "state", &state))
+        {
+            currLEDResource->state = state;
+        }
+    }
+
+    return getPayload(gResourceUri, currLEDResource->power, currLEDResource->state);
+}
+
+OCEntityHandlerResult ProcessGetRequest (OCEntityHandlerRequest *ehRequest,
+        OCRepPayload **payload)
+{
+    OCEntityHandlerResult ehResult;
+
+    OCRepPayload *getResp = constructResponse(ehRequest);
+
+    if(getResp)
+    {
+        *payload = getResp;
+        ehResult = OC_EH_OK;
+    }
+    else
+    {
+        ehResult = OC_EH_ERROR;
+    }
+
+    return ehResult;
+}
+
+OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
+        OCRepPayload **payload)
+{
+    OCEntityHandlerResult ehResult;
+
+    OCRepPayload *putResp = constructResponse(ehRequest);
+
+    if(putResp)
+    {
+        *payload = putResp;
+        ehResult = OC_EH_OK;
+    }
+    else
+    {
+        ehResult = OC_EH_ERROR;
+    }
+
+    return ehResult;
+}
+
+OCEntityHandlerResult ProcessPostRequest (OCEntityHandlerRequest *ehRequest,
+        OCEntityHandlerResponse *response, OCRepPayload **payload)
+{
+    OCRepPayload *respPLPost_led = NULL;
+    OCEntityHandlerResult ehResult = OC_EH_OK;
+
+    /*
+     * The entity handler determines how to process a POST request.
+     * Per the REST paradigm, POST can also be used to update representation of existing
+     * resource or create a new resource.
+     * In the sample below, if the POST is for /a/led then a new instance of the LED
+     * resource is created with default representation (if representation is included in
+     * POST payload it can be used as initial values) as long as the instance is
+     * lesser than max new instance count. Once max instance count is reached, POST on
+     * /a/led updated the representation of /a/led (just like PUT)
+     */
+
+    if (ehRequest->resource == LED.handle)
+    {
+        if (gCurrLedInstance < SAMPLE_MAX_NUM_POST_INSTANCE)
+        {
+            // Create new LED instance
+            char newLedUri[15] = "/a/led/";
+            int newLedUriLength = strlen(newLedUri);
+            snprintf (newLedUri + newLedUriLength, sizeof(newLedUri)-newLedUriLength, "%d", gCurrLedInstance);
+
+            respPLPost_led = OCRepPayloadCreate();
+            OCRepPayloadSetUri(respPLPost_led, gResourceUri);
+            OCRepPayloadSetPropString(respPLPost_led, "createduri", newLedUri);
+
+            if (0 == createLEDResource (newLedUri, &gLedInstance[gCurrLedInstance], false, 0))
+            {
+                OIC_LOG (INFO, TAG, "Created new LED instance");
+                gLedInstance[gCurrLedInstance].state = 0;
+                gLedInstance[gCurrLedInstance].power = 0;
+                gCurrLedInstance++;
+                strncpy ((char *)response->resourceUri, newLedUri, sizeof(response->resourceUri));
+                ehResult = OC_EH_RESOURCE_CREATED;
+            }
+        }
+        else
+        {
+            respPLPost_led = constructResponse(ehRequest);
+        }
+    }
+    else
+    {
+        for (int i = 0; i < SAMPLE_MAX_NUM_POST_INSTANCE; i++)
+        {
+            if (ehRequest->resource == gLedInstance[i].handle)
+            {
+                if (i == 0)
+                {
+                    respPLPost_led = constructResponse(ehRequest);
+                    break;
+                }
+                else if (i == 1)
+                {
+                    respPLPost_led = constructResponse(ehRequest);
+                }
+            }
+        }
+    }
+
+    if (respPLPost_led != NULL)
+    {
+        *payload = respPLPost_led;
+        ehResult = OC_EH_OK;
+    }
+    else
+    {
+        OIC_LOG_V (INFO, TAG, "Payload was NULL");
+        ehResult = OC_EH_ERROR;
+    }
+
+    return ehResult;
+}
+
+OCEntityHandlerResult
+OCEntityHandlerCb (OCEntityHandlerFlag flag,
+        OCEntityHandlerRequest *entityHandlerRequest,
+        void* callbackParam)
+{
+    OIC_LOG_V (INFO, TAG, "Inside entity handler - flags: 0x%x", flag);
+    (void)callbackParam;
+    OCEntityHandlerResult ehResult = OC_EH_ERROR;
+
+    OCEntityHandlerResponse response;
+    memset(&response, 0, sizeof(response));
+
+    // Validate pointer
+    if (!entityHandlerRequest)
+    {
+        OIC_LOG (ERROR, TAG, "Invalid request pointer");
+        return OC_EH_ERROR;
+    }
+
+    OCRepPayload* payload = NULL;
+
+    if (flag & OC_REQUEST_FLAG)
+    {
+        OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
+        if (entityHandlerRequest)
+        {
+            if (OC_REST_GET == entityHandlerRequest->method)
+            {
+                OIC_LOG (INFO, TAG, "Received OC_REST_GET from client");
+                ehResult = ProcessGetRequest (entityHandlerRequest, &payload);
+            }
+            else if (OC_REST_PUT == entityHandlerRequest->method)
+            {
+                OIC_LOG (INFO, TAG, "Received OC_REST_PUT from client");
+                ehResult = ProcessPutRequest (entityHandlerRequest, &payload);
+            }
+            else if (OC_REST_POST == entityHandlerRequest->method)
+            {
+                OIC_LOG (INFO, TAG, "Received OC_REST_POST from client");
+                ehResult = ProcessPostRequest (entityHandlerRequest, &response, &payload);
+            }
+            else
+            {
+                OIC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
+                        entityHandlerRequest->method);
+                ehResult = OC_EH_ERROR;
+            }
+
+            if (ehResult == OC_EH_OK && ehResult != OC_EH_FORBIDDEN)
+            {
+                // Format the response.  Note this requires some info about the request
+                response.requestHandle = entityHandlerRequest->requestHandle;
+                response.resourceHandle = entityHandlerRequest->resource;
+                response.ehResult = ehResult;
+                response.payload = (OCPayload*)(payload);
+                response.numSendVendorSpecificHeaderOptions = 0;
+                memset(response.sendVendorSpecificHeaderOptions, 0,
+                       sizeof(response.sendVendorSpecificHeaderOptions));
+                memset(response.resourceUri, 0, sizeof(response.resourceUri));
+                // Indicate that response is NOT in a persistent buffer
+                response.persistentBufferFlag = 0;
+
+                // Send the response
+                if (OCDoResponse(&response) != OC_STACK_OK)
+                {
+                    OIC_LOG(ERROR, TAG, "Error sending response");
+                    ehResult = OC_EH_ERROR;
+                }
+            }
+        }
+    }
+
+    OCPayloadDestroy(response.payload);
+    return ehResult;
+}
+
+/* SIGINT handler: set gQuitFlag to 1 for graceful termination */
+void handleSigInt(int signum)
+{
+    if (signum == SIGINT)
+    {
+        gQuitFlag = 1;
+    }
+}
+
+FILE* server_fopen(const char *path, const char *mode)
+{
+    (void)path;
+    return fopen(CRED_FILE, mode);
+}
+
+int main()
+{
+    struct timespec timeout;
+
+    OIC_LOG(DEBUG, TAG, "OCServer is starting...");
+
+    // Initialize Persistent Storage for SVR database
+    OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink};
+
+    OCRegisterPersistentStorageHandler(&ps);
+
+    if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
+    {
+        OIC_LOG(ERROR, TAG, "OCStack init error");
+        return 0;
+    }
+
+    /*
+     * Declare and create the example resource: LED
+     */
+    createLEDResource(gResourceUri, &LED, false, 0);
+
+    timeout.tv_sec  = 0;
+    timeout.tv_nsec = 100000000L;
+
+    // Break from loop with Ctrl-C
+    OIC_LOG(INFO, TAG, "Entering ocserver main loop...");
+    signal(SIGINT, handleSigInt);
+    while (!gQuitFlag)
+    {
+        if (OCProcess() != OC_STACK_OK)
+        {
+            OIC_LOG(ERROR, TAG, "OCStack process error");
+            return 0;
+        }
+        nanosleep(&timeout, NULL);
+    }
+
+    OIC_LOG(INFO, TAG, "Exiting ocserver main loop...");
+
+    if (OCStop() != OC_STACK_OK)
+    {
+        OIC_LOG(ERROR, TAG, "OCStack process error");
+    }
+
+    return 0;
+}
+
+int createLEDResource (char *uri, LEDResource *ledResource, bool resourceState, int resourcePower)
+{
+    if (!uri)
+    {
+        OIC_LOG(ERROR, TAG, "Resource URI cannot be NULL");
+        return -1;
+    }
+
+    ledResource->state = resourceState;
+    ledResource->power= resourcePower;
+    OCStackResult res = OCCreateResource(&(ledResource->handle),
+            "core.led",
+            OC_RSRVD_INTERFACE_DEFAULT,
+            uri,
+            OCEntityHandlerCb,
+            NULL,
+            OC_DISCOVERABLE|OC_OBSERVABLE | OC_SECURE);
+    OIC_LOG_V(INFO, TAG, "Created LED resource with result: %s", getResult(res));
+
+    return 0;
+}
index 81b07c4..0f750a0 100644 (file)
@@ -142,7 +142,7 @@ const char *getResult(OCStackResult result) {
     }
 }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 
 #include <assert.h>
 #include <thread>
@@ -177,7 +177,7 @@ static void StopOCProcessThread()
     g_LoopFlag = false;
     oc_process_thread->join();
 }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
 OCRepPayload* getPayload(const char* uri, int64_t power, bool state)
 {
@@ -460,12 +460,19 @@ void GeneratePinCB(char* pin, size_t pinSize)
     OIC_LOG(INFO, TAG, "============================");
 }
 
+void ClosePinDisplayCB(void)
+{
+    OIC_LOG(INFO, TAG, "============================");
+    OIC_LOG(INFO, TAG, "    PIN DISPLAY CLOSED.");
+    OIC_LOG(INFO, TAG, "============================");
+}
+
 int main()
 {
     OIC_LOG(DEBUG, TAG, "OCServer is starting...");
 
     // Initialize Persistent Storage for SVR database
-    OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink};
+    OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink, NULL, NULL};
     OCRegisterPersistentStorageHandler(&ps);
 
     if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
@@ -481,6 +488,13 @@ int main()
     SetGeneratePinCB(GeneratePinCB);
 
     /**
+     * If ther server supports random pin based OTM,
+     * the callback to close PIN display can be registered.
+     * This callback will be invoked when random PIN based OTM is done.
+     */
+    SetClosePinDisplayCB(ClosePinDisplayCB);
+
+    /**
      * Random PIN generation policy can be changed through SetRandomPinPolicy() API.
      * first param : byte length of random PIN ( 4 <= first param <= 32)
      * second param : PIN type (This is bitmask)
@@ -500,7 +514,7 @@ int main()
     OIC_LOG(INFO, TAG, "Entering ocserver main loop...");
     signal(SIGINT, handleSigInt);
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
     StartOCProcessThread();
 
     while(!gQuitFlag)
@@ -534,7 +548,7 @@ int main()
         }
         nanosleep(&timeout, NULL);
     }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
     OIC_LOG(INFO, TAG, "Exiting ocserver main loop...");
 
index d13f1d2..ac24a22 100644 (file)
@@ -321,7 +321,7 @@ static int multipleOwnershipTransfer(void)
     // for error checking, the return value saved and printed
     g_doneCB = false;
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
     OCProvisionDev_t* dev = NULL;
     LL_FOREACH(g_motdev_list, dev)
     {
@@ -337,7 +337,7 @@ static int multipleOwnershipTransfer(void)
             }
         }
     }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
     if(OC_STACK_OK != OCDoMultipleOwnershipTransfer(g_ctx, g_motdev_list, multipleOwnershipTransferCB))
     {
@@ -855,6 +855,11 @@ static int waitCallbackRet(void)
         }
     }
 
+    if(!g_doneCB)
+    {
+        OCPDMCleanupForTimeout();
+    }
+
     return 0;
 }
 
index e2424db..20da886 100644 (file)
 #include "ocstack.h"
 #include "ocpayload.h"
 #include "pmutility.h"
-#include "srmutility.h"
 #include "cacommonutil.h"
 #include "aclresource.h"
 #include "ocpayloadcbor.h"
 #include "payload_logging.h"
 #include "utlist.h"
+#include "securevirtualresourcetypes.h"
 
 #define TAG "OIC_CLOUD_ACL_ID"
 
+/* Although this is already implemented in srmutility.h, we can't include the header file,
+ * because of "redefined VERIFY_NON_NULL"
+ */
+OCStackResult ConvertUuidToStr(const OicUuid_t* uuid, char** strUuid);
+
 /**
  * ACL Id parse from received response
  *
@@ -546,3 +551,33 @@ OCStackResult OCCloudAclIndividualDeleteAce(void* ctx,
                         CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
 }
 
+OCStackResult ConvertUuidToStr(const OicUuid_t* uuid, char** strUuid)
+{
+    if (NULL == uuid || NULL == strUuid || NULL != *strUuid)
+    {
+        OIC_LOG(ERROR, TAG, "ConvertUuidToStr : Invalid param");
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    size_t uuidIdx = 0;
+    size_t urnIdx = 0;
+    const size_t urnBufSize = (UUID_LENGTH * 2) + 4 + 1;
+    char *convertedUrn = (char*)OICCalloc(urnBufSize, sizeof(char));
+    VERIFY_NON_NULL(convertedUrn, TAG, "OICCalloc() is failed(convertedUrn)");
+
+    for (uuidIdx = 0, urnIdx = 0; uuidIdx < UUID_LENGTH && urnIdx < urnBufSize;
+            uuidIdx++, urnIdx += 2)
+    {
+        // canonical format for UUID has '8-4-4-4-12'
+        if (4 == uuidIdx || 6 == uuidIdx || 8 == uuidIdx || 10 == uuidIdx)
+        {
+            snprintf(convertedUrn + urnIdx, 2, "%c", '-');
+            urnIdx++;
+        }
+        snprintf(convertedUrn + urnIdx, 3, "%02x", (uint8_t)(uuid->id[uuidIdx]));
+    }
+    convertedUrn[urnBufSize - 1] = '\0';
+
+    *strUuid = convertedUrn;
+    return OC_STACK_OK;
+}
index 1c4fcd1..048e0f5 100644 (file)
@@ -393,17 +393,11 @@ static OCStackResult HandleCertificateIssueRequest(void *ctx, void **data, OCCli
             OIC_ENCODING_DER
         };
 
-        OicSecCert_t cert1 =
-        {
-            cert.data,
-            cert.len,
-        };
-
         uint16_t credId;
-        result = SRPSaveOwnCertChain(&cert1, &key, &credId);
+        result = SRPSaveOwnCertChain(&cert, &key, &credId);
         if (result != OC_STACK_OK)
         {
-            OIC_LOG(ERROR, TAG, "Cann't add cert");
+            OIC_LOG(ERROR, TAG, "Can't add cert");
         }
     }
 
@@ -412,7 +406,7 @@ static OCStackResult HandleCertificateIssueRequest(void *ctx, void **data, OCCli
     if (!OCRepPayloadGetPropPubDataType((OCRepPayload *)response->payload,
                                    OC_RSRVD_CACERT, &caCert))
     {
-        OIC_LOG_V(ERROR, TAG, "Cann't get: %s", OC_RSRVD_CACERT);
+        OIC_LOG_V(ERROR, TAG, "Can't get: %s", OC_RSRVD_CACERT);
         result = OC_STACK_ERROR;
     }
     else
@@ -462,7 +456,7 @@ OCStackResult OCCloudCertificateIssueRequest(void* ctx,
 
     OIC_LOG_V(DEBUG, TAG, "Certificate Request subject: %s", subject);
 
-    OCByteString request;
+    OCByteString request = {0};
     if (0 != GenerateCSR(subject, &request))
     {
         OIC_LOG(ERROR, TAG, "Cann't get the sertificate request");
index a6ee58e..a930e53 100644 (file)
@@ -55,7 +55,7 @@ OCStackResult PMGeneratePairWiseCredentials(OicSecCredType_t type, size_t keySiz
 
     uint8_t *privData = (uint8_t *)OICCalloc(privDataKeySize, sizeof(uint8_t));
     VERIFY_NON_NULL(TAG, privData, ERROR);
-    OicSecKey_t privKey = {privData, keySize};
+    OicSecKey_t privKey = {.data=privData, .len=keySize};
 
     OCFillRandomMem(privData, privDataKeySize);
 
index 6a84d27..fb7104c 100644 (file)
 #include "cacommon.h"
 #include "cainterface.h"
 #include "base64.h"
+#if defined (__TIZENRT__)
+#include <apps/netutils/cJSON.h>
+#else
 #include "cJSON.h"
-#include "global.h"
+#endif
 
 #include "srmresourcestrings.h"
 #include "doxmresource.h"
@@ -78,7 +81,7 @@
 static OCStackApplicationResult MOTUpdateSecurityResourceCB(void *ctx, OCDoHandle UNUSED,
                                                 OCClientResponse *clientResponse)
 {
-    OIC_LOG_V(INFO, TAG, "Inside MOTUpdateMomCB.");
+    OIC_LOG_V(INFO, TAG, "In %s", __func__);
     (void)UNUSED;
     OTMContext_t *motCtx = (OTMContext_t*)ctx;
     VERIFY_NON_NULL(TAG, motCtx, ERROR);
@@ -117,10 +120,68 @@ exit:
         OICFree(motCtx->ctxResultArray);
         OICFree(motCtx);
     }
+    OIC_LOG_V(INFO, TAG, "Out %s", __func__);
     return OC_STACK_DELETE_TRANSACTION;
 }
 
 /**
+ * Callback handler of security resource's DELETE request.
+ *
+ * @param[in] ctx             ctx value passed to callback from calling function.
+ * @param[in] UNUSED          handle to an invocation
+ * @param[in] clientResponse  Response from queries to remote servers.
+ * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
+ *          and  OC_STACK_KEEP_TRANSACTION to keep it.
+ */
+static OCStackApplicationResult MOTDeleteSecurityResourceCB(void *ctx, OCDoHandle UNUSED,
+                                                OCClientResponse *clientResponse)
+{
+    OIC_LOG_V(INFO, TAG, "In %s", __func__);
+    (void)UNUSED;
+    OTMContext_t *motCtx = (OTMContext_t*)ctx;
+    VERIFY_NON_NULL(TAG, motCtx, ERROR);
+    VERIFY_NON_NULL(TAG, motCtx->ctxResultCallback, ERROR);
+    VERIFY_NON_NULL(TAG, motCtx->ctxResultArray, ERROR);
+
+    if(clientResponse)
+    {
+        memcpy(motCtx->ctxResultArray[0].deviceId.id,
+               motCtx->selectedDeviceInfo->doxm->deviceID.id,
+               sizeof(OicUuid_t));
+        motCtx->ctxResultArray[0].res = clientResponse->result;
+
+        if(OC_STACK_RESOURCE_DELETED == clientResponse->result)
+        {
+            motCtx->ctxHasError = false;
+        }
+        else
+        {
+            motCtx->ctxHasError = true;
+        }
+    }
+    else
+    {
+        OIC_LOG_V(ERROR, TAG, "SRPGetACLResourceCB received Null clientResponse");
+        motCtx->ctxResultArray[0].res = OC_STACK_ERROR;
+        motCtx->ctxHasError = true;
+    }
+
+    motCtx->ctxResultCallback(motCtx->userCtx, motCtx->ctxResultArraySize,
+                              motCtx->ctxResultArray, motCtx->ctxHasError);
+
+exit:
+    if(motCtx)
+    {
+        OICFree(motCtx->ctxResultArray);
+        OICFree(motCtx);
+    }
+    OIC_LOG_V(INFO, TAG, "Out %s", __func__);
+
+    return OC_STACK_DELETE_TRANSACTION;
+
+}
+
+/**
  * Internal API to send POST doxm request
  */
 static OCStackResult MOTSendPostDoxm(void *ctx,
@@ -133,7 +194,7 @@ static OCStackResult MOTSendPostDoxm(void *ctx,
     OTMContext_t *motCtx = NULL;
     bool freeFlag = true;
 
-    OIC_LOG(DEBUG, TAG, "IN MOTSendPostDoxm");
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
 
     //Generate the security payload using updated doxm
     secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
@@ -178,8 +239,6 @@ static OCStackResult MOTSendPostDoxm(void *ctx,
 
     freeFlag = false;
 
-    OIC_LOG(DEBUG, TAG, "OUT MOTSendPostDoxm");
-
 exit:
     //If POST request successfully sent, motCtx will be cleaned from response handler.
     if(freeFlag && motCtx)
@@ -187,7 +246,7 @@ exit:
         OICFree(motCtx->ctxResultArray);
         OICFree(motCtx);
     }
-
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
     return postMomRes;
 }
 
@@ -208,7 +267,7 @@ OCStackResult MOTChangeMode(void *ctx, const OCProvisionDev_t *targetDeviceInfo,
     uint8_t* doxmPayload = NULL;
     size_t doxmPayloadLen = 0;
 
-    OIC_LOG(DEBUG, TAG, "IN MOTChangeMode");
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
 
     VERIFY_SUCCESS(TAG, (OIC_NUMBER_OF_MOM_TYPE > momType), ERROR);
     VERIFY_NON_NULL(TAG, targetDeviceInfo, ERROR);
@@ -235,11 +294,10 @@ OCStackResult MOTChangeMode(void *ctx, const OCProvisionDev_t *targetDeviceInfo,
     postMomRes = MOTSendPostDoxm(ctx, targetDeviceInfo, resultCallback, doxm);
     VERIFY_SUCCESS(TAG, (OC_STACK_OK == postMomRes), ERROR);
 
-    OIC_LOG(DEBUG, TAG, "OUT MOTChangeMode");
-
 exit:
     OICFree(doxmPayload);
     DeleteDoxmBinData(doxm);
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
     return postMomRes;
 }
 
@@ -260,7 +318,7 @@ OCStackResult MOTAddMOTMethod(void *ctx, OCProvisionDev_t *targetDeviceInfo,
     uint8_t* doxmPayload = NULL;
     size_t doxmPayloadLen = 0;
 
-    OIC_LOG(DEBUG, TAG, "IN MOTAddMOTMethod");
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
 
     VERIFY_SUCCESS(TAG, (OIC_OXM_COUNT > newOxm || OIC_PRECONFIG_PIN == newOxm), ERROR);
     VERIFY_NON_NULL(TAG, targetDeviceInfo, ERROR);
@@ -298,10 +356,9 @@ OCStackResult MOTAddMOTMethod(void *ctx, OCProvisionDev_t *targetDeviceInfo,
     postOxmRes = MOTSendPostDoxm(ctx, targetDeviceInfo, resultCallback, targetDeviceInfo->doxm);
     VERIFY_SUCCESS(TAG, (OC_STACK_OK == postOxmRes), ERROR);
 
-    OIC_LOG(DEBUG, TAG, "OUT MOTAddMOTMethod");
-
 exit:
     OICFree(doxmPayload);
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
     return postOxmRes;
 }
 
@@ -322,7 +379,7 @@ OCStackResult MOTSelectMOTMethod(void *ctx, const OCProvisionDev_t *targetDevice
     uint8_t* doxmPayload = NULL;
     size_t doxmPayloadLen = 0;
 
-    OIC_LOG(DEBUG, TAG, "IN MOTSelectOTMethod");
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
 
     VERIFY_NON_NULL(TAG, resultCallback, ERROR);
     postMomRes = OC_STACK_INVALID_PARAM;
@@ -353,11 +410,10 @@ OCStackResult MOTSelectMOTMethod(void *ctx, const OCProvisionDev_t *targetDevice
     postMomRes = MOTSendPostDoxm(ctx, targetDeviceInfo, resultCallback, doxm);
     VERIFY_SUCCESS(TAG, (OC_STACK_OK == postMomRes), ERROR);
 
-    OIC_LOG(DEBUG, TAG, "OUT MOTSelectOTMethod");
-
 exit:
     OICFree(doxmPayload);
     DeleteDoxmBinData(doxm);
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
     return postMomRes;
 }
 
@@ -380,7 +436,7 @@ OCStackResult MOTProvisionPreconfigPIN(void *ctx, const OCProvisionDev_t *target
     OTMContext_t *motCtx = NULL;
     OicSecCred_t* pinCred = NULL;
 
-    OIC_LOG(DEBUG, TAG, "IN MOTProvisionPreconfigPIN");
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
 
     VERIFY_NON_NULL(TAG, resultCallback, ERROR);
     postCredRes = OC_STACK_INVALID_PARAM;
@@ -447,7 +503,7 @@ OCStackResult MOTProvisionPreconfigPIN(void *ctx, const OCProvisionDev_t *target
 
     freeFlag = false;
 
-    OIC_LOG(DEBUG, TAG, "OUT MOTProvisionPreconfigPIN");
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
 
     return postCredRes;
 
@@ -463,6 +519,7 @@ exit:
         OICFree(pinCred->privateData.data);
         OICFree(pinCred);
     }
+    OIC_LOG_V(DEBUG, TAG, "Out %s : %d", __func__, postCredRes);
     return postCredRes;
 }
 
@@ -497,7 +554,7 @@ static bool IsComplete(OTMContext_t* otmCtx)
  */
 static void SetMOTResult(OTMContext_t* motCtx, const OCStackResult res)
 {
-    OIC_LOG_V(DEBUG, TAG, "IN SetMOTResult : %d ", res);
+    OIC_LOG_V(DEBUG, TAG, "IN %s : %d ", __func__, res);
     VERIFY_NON_NULL(TAG, motCtx, ERROR);
 
     if(motCtx->selectedDeviceInfo)
@@ -556,6 +613,7 @@ static void SetMOTResult(OTMContext_t* motCtx, const OCStackResult res)
 
             OICFree(motCtx->ctxResultArray);
             OICFree(motCtx);
+            motCtx = NULL;
         }
         else
         {
@@ -568,7 +626,7 @@ static void SetMOTResult(OTMContext_t* motCtx, const OCStackResult res)
     }
 
 exit:
-    OIC_LOG(DEBUG, TAG, "OUT SetMOTResult");
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
 }
 
 /**
@@ -588,7 +646,7 @@ OCStackResult MOTAddPreconfigPIN(const OCProvisionDev_t *targetDeviceInfo,
     OicSecCred_t* pinCred = NULL;
     bool freeFlag = true;
 
-    OIC_LOG(DEBUG, TAG, "IN MOTAddPreconfigPIN");
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
 
     VERIFY_NON_NULL(TAG, targetDeviceInfo, ERROR);
     VERIFY_NON_NULL(TAG, preconfPIN, ERROR);
@@ -620,7 +678,7 @@ OCStackResult MOTAddPreconfigPIN(const OCProvisionDev_t *targetDeviceInfo,
     addCredRes = AddCredential(pinCred);
     VERIFY_SUCCESS(TAG, (OC_STACK_OK == addCredRes), ERROR);
 
-    OIC_LOG(DEBUG, TAG, "OUT MOTAddPreconfigPIN");
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
 
     return addCredRes;
 
@@ -630,6 +688,7 @@ exit:
         OICFree(pinCred->privateData.data);
         OICFree(pinCred);
     }
+    OIC_LOG_V(DEBUG, TAG, "In %s : %d", __func__, addCredRes);
     return addCredRes;
 }
 
@@ -641,7 +700,7 @@ exit:
  */
 static OCStackResult SaveSubOwnerPSK(OCProvisionDev_t *selectedDeviceInfo)
 {
-    OIC_LOG(DEBUG, TAG, "IN SaveSubOwnerPSK");
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
 
     OCStackResult res = OC_STACK_ERROR;
 
@@ -709,7 +768,7 @@ static OCStackResult SaveSubOwnerPSK(OCProvisionDev_t *selectedDeviceInfo)
         OIC_LOG(ERROR, TAG, "CAGenerateOwnerPSK failed");
     }
 
-    OIC_LOG(DEBUG, TAG, "OUT SaveSubOwnerPSK");
+    OIC_LOG_V(DEBUG, TAG, "Out %s : %d", __func__, res);
 exit:
     return res;
 }
@@ -730,7 +789,8 @@ static OCStackApplicationResult SubOwnerCredentialHandler(void *ctx, OCDoHandle
     VERIFY_NON_NULL(TAG, clientResponse, WARNING);
     VERIFY_NON_NULL(TAG, ctx, WARNING);
 
-    OIC_LOG(DEBUG, TAG, "IN SubOwnerCredentialHandler");
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+
     (void)UNUSED;
     OTMContext_t* motCtx = (OTMContext_t*)ctx;
 
@@ -738,27 +798,39 @@ static OCStackApplicationResult SubOwnerCredentialHandler(void *ctx, OCDoHandle
     {
         if(motCtx && motCtx->selectedDeviceInfo)
         {
-            //Close the temporal secure session to verify the owner credential
-            CAEndpoint_t* endpoint = (CAEndpoint_t *)&motCtx->selectedDeviceInfo->endpoint;
-            endpoint->port = motCtx->selectedDeviceInfo->securePort;
-            CAResult_t caResult = CAcloseSslSession(endpoint);
-            if(CA_STATUS_OK != caResult)
+            //Delete previous credential such as preconfigured-pin
+            RemoveCredential(&(motCtx->selectedDeviceInfo->doxm->deviceID));
+            OCStackResult res = SaveSubOwnerPSK(motCtx->selectedDeviceInfo);
+            if(OC_STACK_OK == res)
             {
-                OIC_LOG(ERROR, TAG, "Failed to close DTLS session");
-                SetMOTResult(motCtx, OC_STACK_ERROR);
-                return OC_STACK_DELETE_TRANSACTION;
-            }
+                //Close the temporal secure session to verify the owner credential
+                CAEndpoint_t* endpoint = (CAEndpoint_t *)&motCtx->selectedDeviceInfo->endpoint;
+                endpoint->port = motCtx->selectedDeviceInfo->securePort;
+                CAResult_t caResult = CAcloseSslSession(endpoint);
+                if(CA_STATUS_OK != caResult)
+                {
+                    OIC_LOG(ERROR, TAG, "Failed to close DTLS session");
+                    SetMOTResult(motCtx, OC_STACK_ERROR);
+                    return OC_STACK_DELETE_TRANSACTION;
+                }
+
+                // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256 = 0xC037, /**< see RFC 5489 */
+                caResult = CASelectCipherSuite(0xC037, endpoint->adapter);
+                if(CA_STATUS_OK != caResult)
+                {
+                    OIC_LOG(ERROR, TAG, "Failed to select TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256");
+                    SetMOTResult(motCtx, OC_STACK_ERROR);
+                    return OC_STACK_DELETE_TRANSACTION;
+                }
 
-            // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256 = 0xC037, /**< see RFC 5489 */
-            caResult = CASelectCipherSuite(0xC037, endpoint->adapter);
-            if(CA_STATUS_OK != caResult)
+                SetMOTResult(motCtx, OC_STACK_OK);
+            }
+            else
             {
-                OIC_LOG(ERROR, TAG, "Failed to select TLS_NULL_WITH_NULL_NULL");
-                SetMOTResult(motCtx, OC_STACK_ERROR);
+                OIC_LOG(ERROR, TAG, "Failed to save the SubOwner PSK.");
+                SetMOTResult(motCtx, res);
                 return OC_STACK_DELETE_TRANSACTION;
             }
-
-            SetMOTResult(motCtx, OC_STACK_OK);
         }
     }
     else
@@ -768,7 +840,7 @@ static OCStackApplicationResult SubOwnerCredentialHandler(void *ctx, OCDoHandle
         SetMOTResult(motCtx, clientResponse->result);
     }
 
-    OIC_LOG(DEBUG, TAG, "OUT SubOwnerCredentialHandler");
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
 
 exit:
     return  OC_STACK_DELETE_TRANSACTION;
@@ -777,7 +849,7 @@ exit:
 
 static OCStackResult PostSubOwnerCredential(OTMContext_t* motCtx)
 {
-    OIC_LOG(DEBUG, TAG, "IN PostSubOwnerCredential");
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
 
     if(!motCtx || !motCtx->selectedDeviceInfo)
     {
@@ -806,19 +878,18 @@ static OCStackResult PostSubOwnerCredential(OTMContext_t* motCtx)
 
     //Generate sub-owner credential for new device
     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
-    const OicSecCred_t* ownerCredential = GetCredResourceData(&(deviceInfo->doxm->deviceID));
-    if(!ownerCredential)
-    {
-        OIC_LOG(ERROR, TAG, "Can not find SubOwnerPSK.");
-        return OC_STACK_NO_RESOURCE;
-    }
 
+    /**
+     * Because of the deadlock issue, we can not get a server's session information at this time.
+     * So use the dumpy owner credential instance to send POST credential request.
+     */
     OicUuid_t ownerId = {.id={0}};
     if(OC_STACK_OK == GetDoxmDeviceID(&ownerId))
     {
         OicSecCred_t newCredential;
-        memcpy(&newCredential, ownerCredential, sizeof(OicSecCred_t));
+        memset(&newCredential, 0x0, sizeof(OicSecCred_t));
         newCredential.next = NULL;
+        newCredential.credType = SYMMETRIC_PAIR_WISE_KEY;
 
         //Set subject ID as SubOwner's ID
         memcpy(&(newCredential.subject), &ownerId, sizeof(OicUuid_t));
@@ -837,10 +908,12 @@ static OCStackResult PostSubOwnerCredential(OTMContext_t* motCtx)
         //Fill private data as empty string
         newCredential.privateData.data = "";
         newCredential.privateData.len = 0;
-        newCredential.privateData.encoding = ownerCredential->privateData.encoding;
-#ifdef __WITH_X509__
+        newCredential.privateData.encoding = OIC_ENCODING_BASE64;
+
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
         newCredential.publicData.data = NULL;
         newCredential.publicData.len = 0;
+        newCredential.publicData.encoding = OIC_ENCODING_RAW;
 #endif
         //Send owner credential to new device : POST /oic/sec/cred [ owner credential ]
         if (OC_STACK_OK != CredToCBORPayload(&newCredential, &secPayload->securityData,
@@ -852,6 +925,7 @@ static OCStackResult PostSubOwnerCredential(OTMContext_t* motCtx)
         }
         OIC_LOG(DEBUG, TAG, "Cred Payload:");
         OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
+        OICFree(newCredential.eownerID);
 
         OCCallbackData cbData;
         cbData.cb = &SubOwnerCredentialHandler;
@@ -871,7 +945,7 @@ static OCStackResult PostSubOwnerCredential(OTMContext_t* motCtx)
         return OC_STACK_NO_RESOURCE;
     }
 
-    OIC_LOG(DEBUG, TAG, "OUT PostSubOwnerCredential");
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
 
     return OC_STACK_OK;
 }
@@ -886,7 +960,7 @@ static OCStackResult PostSubOwnerCredential(OTMContext_t* motCtx)
  */
 static void MOTDtlsHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info)
 {
-    OIC_LOG(INFO, TAG, "IN MOTDtlsHandshakeCB");
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
 
     if(NULL != endpoint && NULL != info)
     {
@@ -913,24 +987,12 @@ static void MOTDtlsHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t
                     //If temporal secure sesstion established successfully
                     if(CA_STATUS_OK == info->result)
                     {
-                        //Delete previous credential such as preconfigured-pin
-                        RemoveCredential(&(motCtx->selectedDeviceInfo->doxm->deviceID));
-
-                        res = SaveSubOwnerPSK(motCtx->selectedDeviceInfo);
-                        if(OC_STACK_OK == res)
+                        //POST sub owner credential to new device.
+                        res = PostSubOwnerCredential(motCtx);
+                        if(OC_STACK_OK != res)
                         {
-                            //POST sub owner credential to new device.
-                            res = PostSubOwnerCredential(motCtx);
-                            if(OC_STACK_OK != res)
-                            {
-                                OIC_LOG(ERROR, TAG,
-                                        "Failed to send POST request for SubOwner Credential");
-                                SetMOTResult(motCtx, res);
-                            }
-                        }
-                        else
-                        {
-                            OIC_LOG(ERROR, TAG, "Failed to save the SubOwner PSK.");
+                            OIC_LOG(ERROR, TAG,
+                                    "Failed to send POST request for SubOwner Credential");
                             SetMOTResult(motCtx, res);
                         }
                     }
@@ -974,20 +1036,45 @@ static void MOTDtlsHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t
         }
     }
 
-    OIC_LOG(INFO, TAG, "OUT MOTDtlsHandshakeCB");
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
 }
 
 static OCStackResult StartMultipleOwnershipTransfer(OTMContext_t* motCtx,
                                                     OCProvisionDev_t* selectedDevice)
 {
-    OIC_LOG(INFO, TAG, "IN StartMultipleOwnershipTransfer");
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
     OCStackResult res = OC_STACK_INVALID_PARAM;
+    OicUuid_t myUuid = {.id={0}};
 
     VERIFY_NON_NULL(TAG, motCtx, ERROR);
     VERIFY_NON_NULL(TAG, selectedDevice, ERROR);
     VERIFY_NON_NULL(TAG, selectedDevice->doxm, ERROR);
     motCtx->selectedDeviceInfo = selectedDevice;
 
+    res = GetDoxmDeviceID(&myUuid);
+    if(OC_STACK_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "Failed to GetDoxmDeviceID");
+        SetMOTResult(motCtx, res);
+        return res;
+    }
+    if(memcmp(selectedDevice->doxm->owner.id, myUuid.id, sizeof(myUuid.id)) == 0)
+    {
+        res = OC_STACK_INVALID_DEVICE_INFO;
+        OIC_LOG(ERROR, TAG, "Owner cannot be registered as sub-owner.");
+        SetMOTResult(motCtx, res);
+        return res;
+    }
+    if (NULL == selectedDevice->doxm->mom ||
+        (selectedDevice->doxm->mom &&
+         OIC_MULTIPLE_OWNER_DISABLE == selectedDevice->doxm->mom->mode))
+    {
+        res = OC_STACK_NOT_ACCEPTABLE;
+        OIC_LOG(ERROR, TAG, "Selected device's MOT is disabled.");
+        SetMOTResult(motCtx, res);
+        return res;
+    }
+
     //Checking duplication of Device ID.
     char* strUuid = NULL;
     PdmDeviceState_t deviceState = PDM_DEVICE_UNKNOWN;
@@ -1076,7 +1163,7 @@ static OCStackResult StartMultipleOwnershipTransfer(OTMContext_t* motCtx,
     res = motCtx->otmCallback.createSecureSessionCB(motCtx);
     VERIFY_SUCCESS(TAG, OC_STACK_OK == res, ERROR);
 
-    OIC_LOG(INFO, TAG, "OUT StartMultipleOwnershipTransfer");
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
 
 exit:
     return res;
@@ -1086,7 +1173,7 @@ OCStackResult MOTDoOwnershipTransfer(void* ctx,
                                      OCProvisionDev_t *selectedDevicelist,
                                      OCProvisionResultCB resultCallback)
 {
-    OIC_LOG(DEBUG, TAG, "IN MOTDoOwnershipTransfer");
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
     OCStackResult res = OC_STACK_INVALID_PARAM;
     OTMContext_t* motCtx = NULL;
     OCProvisionDev_t* pCurDev = NULL;
@@ -1125,10 +1212,10 @@ OCStackResult MOTDoOwnershipTransfer(void* ctx,
 
     motCtx->selectedDeviceInfo = selectedDevicelist;
     res = StartMultipleOwnershipTransfer(motCtx, selectedDevicelist);
-    VERIFY_SUCCESS(TAG, OC_STACK_OK == res, ERROR);
 
-    OIC_LOG(DEBUG, TAG, "OUT MOTDoOwnershipTransfer");
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
 
+    return res;
 exit:
     if(OC_STACK_OK != res)
     {
@@ -1138,5 +1225,87 @@ exit:
             OICFree(motCtx);
         }
     }
+    OIC_LOG_V(DEBUG, TAG, "Out %s : %d", __func__, res);
+
     return res;
 }
+
+OCStackResult MOTRemoveSubOwner(void* ctx,
+                                const OCProvisionDev_t *targetDeviceInfo,
+                                const OicUuid_t* subOwner,
+                                OCProvisionResultCB resultCallback)
+{
+    OCStackResult deleteSubOwnerRes = OC_STACK_INVALID_CALLBACK;
+    OTMContext_t *motCtx = NULL;
+    char* strUuid = NULL;
+
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+
+    VERIFY_NON_NULL(TAG, resultCallback, ERROR);
+    deleteSubOwnerRes = OC_STACK_INVALID_PARAM;
+    VERIFY_NON_NULL(TAG, targetDeviceInfo, ERROR);
+    VERIFY_NON_NULL(TAG, subOwner, ERROR);
+
+    deleteSubOwnerRes = OC_STACK_NO_MEMORY;
+    //Generate the qurey to delete sub-owner
+    if (memcmp(subOwner->id, WILDCARD_SUBJECT_ID.id, sizeof(WILDCARD_SUBJECT_ID.id)) == 0)
+    {
+        strUuid = OICStrdup(WILDCARD_RESOURCE_URI);
+        VERIFY_NON_NULL(TAG, strUuid, ERROR);
+    }
+    else
+    {
+        VERIFY_SUCCESS(TAG, (OC_STACK_OK == ConvertUuidToStr(subOwner, &strUuid)), ERROR);
+    }
+    char url[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
+    snprintf(url, sizeof(url), "%s?%s=%s", OIC_RSRC_DOXM_URI, OIC_JSON_SUBOWNERID_NAME, strUuid);
+
+    char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
+    bool queryGenRes = PMGenerateQuery(true,
+                                       targetDeviceInfo->endpoint.addr,
+                                       targetDeviceInfo->securePort,
+                                       targetDeviceInfo->connType,
+                                       query, sizeof(query), url);
+    VERIFY_SUCCESS(TAG, (true == queryGenRes), ERROR);
+
+    OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
+
+    //Create the MOT Context to handle the response message
+    motCtx = (OTMContext_t*)OICCalloc(1, sizeof(OTMContext_t));
+    VERIFY_NON_NULL(TAG, motCtx, ERROR);
+    motCtx->selectedDeviceInfo= targetDeviceInfo;
+    motCtx->ctxResultCallback = resultCallback;
+    motCtx->ctxResultArraySize =1;
+    motCtx->ctxHasError = false;
+    motCtx->userCtx = ctx;
+    motCtx->ctxResultArray = (OCProvisionResult_t*)OICCalloc(1, sizeof(OCProvisionResult_t));
+    VERIFY_NON_NULL(TAG, motCtx->ctxResultArray, ERROR);
+
+    //Send POST request
+    OCCallbackData cbData =  {.context=NULL, .cb=NULL, .cd=NULL};
+    cbData.cb = &MOTDeleteSecurityResourceCB;
+    cbData.context = (void *)motCtx;
+    OIC_LOG(DEBUG, TAG, "Sending DELETE sub-owner request to resource server");
+    deleteSubOwnerRes = OCDoResource(NULL, OC_REST_DELETE, query,
+                                     &targetDeviceInfo->endpoint, NULL,
+                                     targetDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
+    VERIFY_SUCCESS(TAG, (OC_STACK_OK == deleteSubOwnerRes), ERROR);
+
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+
+    OICFree(strUuid);
+
+    return deleteSubOwnerRes;
+
+exit:
+    //If DELETE request successfully sent, motCtx will be cleaned from response handler.
+    OICFree(strUuid);
+    if (motCtx)
+    {
+        OICFree(motCtx->ctxResultArray);
+        OICFree(motCtx);
+    }
+    OIC_LOG_V(DEBUG, TAG, "Out %s : %d", __func__, deleteSubOwnerRes);
+    return deleteSubOwnerRes;
+}
+
index 1bb5efe..ffd1256 100644 (file)
@@ -24,9 +24,9 @@
 #include "pmutility.h"
 #include "srmutility.h"
 #include "ownershiptransfermanager.h"
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 #include "multipleownershiptransfermanager.h"
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 #include "oic_malloc.h"
 #include "logger.h"
 #include "secureresourceprovider.h"
@@ -35,6 +35,8 @@
 #include "utlist.h"
 #include "aclresource.h" //Note: SRM internal header
 #include "pconfresource.h"
+#include "psinterface.h"
+#include "srmresourcestrings.h"
 
 #define TAG "OIC_OCPMAPI"
 
@@ -53,7 +55,7 @@ struct Linkdata
 
 };
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 typedef struct ProvPreconfPINCtx ProvPreconfPINCtx_t;
 struct ProvPreconfPINCtx
 {
@@ -63,7 +65,7 @@ struct ProvPreconfPINCtx
     size_t pinLen;
     OCProvisionResultCB resultCallback;
 };
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
 /**
  * The function is responsible for initializaton of the provisioning manager. It will load
@@ -80,6 +82,16 @@ OCStackResult OCInitPM(const char* dbPath)
     return PDMInit(dbPath);
 }
 
+void OCTerminatePM()
+{
+    OTMTerminate();
+}
+
+OCStackResult OCPDMCleanupForTimeout()
+{
+    return PDMDeleteDeviceWithState(PDM_DEVICE_INIT);
+}
+
 /**
  * The function is responsible for discovery of owned/unowned device is specified endpoint/deviceID.
  * And this function will only return the specified device's response.
@@ -102,6 +114,33 @@ OCStackResult OCDiscoverSingleDevice(unsigned short timeout, const OicUuid_t* de
 }
 
 /**
+ * The function is responsible for discovery of owned/unowned device is specified endpoint/deviceID.
+ * And this function will only return the specified device's response.
+ *
+ * @param[in] timeout Timeout in seconds, value till which function will listen to responses from
+ *                    server before returning the device.
+ * @param[in] deviceID         deviceID of target device.
+ * @param[in] hostAddress       MAC address of target device.
+ * @param[in] connType       ConnectivityType for discovery.
+ * @param[out] ppFoundDevice     OCProvisionDev_t of found device.
+ * @return OTM_SUCCESS in case of success and other value otherwise.
+ */
+OCStackResult OCDiscoverSingleDeviceInUnicast(unsigned short timeout, const OicUuid_t* deviceID,
+                             const char* hostAddress, OCConnectivityType connType,
+                             OCProvisionDev_t **ppFoundDevice)
+{
+    if( NULL == ppFoundDevice || NULL != *ppFoundDevice || 0 == timeout || NULL == deviceID ||
+            NULL == hostAddress)
+    {
+        OIC_LOG(ERROR, TAG, "OCDiscoverSingleDeviceInUnicast : Invalid Parameter");
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    return PMSingleDeviceDiscoveryInUnicast(timeout, deviceID, hostAddress, connType,
+            ppFoundDevice);
+}
+
+/**
  * The function is responsible for discovery of device is current subnet. It will list
  * all the device in subnet which are not yet owned. Please call OCInit with OC_CLIENT_SERVER as
  * OCMode.
@@ -140,7 +179,7 @@ OCStackResult OCDiscoverOwnedDevices(unsigned short timeout, OCProvisionDev_t **
     return PMDeviceDiscovery(timeout, true, ppList);
 }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 /**
  * The function is responsible for discovery of MOT enabled device is current subnet.
  *
@@ -211,7 +250,45 @@ OCStackResult OCDoMultipleOwnershipTransfer(void* ctx,
     return MOTDoOwnershipTransfer(ctx, targetDevices, resultCallback);
 }
 
-#endif //_ENABLE_MULTIPLE_OWNER_
+OCStackResult OCRemoveSubOwner(void* ctx,
+                                const OCProvisionDev_t *targetDeviceInfo,
+                                const OicUuid_t* subOwner,
+                                OCProvisionResultCB resultCallback)
+{
+    if (NULL == targetDeviceInfo || NULL == subOwner)
+    {
+        OIC_LOG_V(ERROR, TAG, "%s : NULL Param", __func__);
+        return OC_STACK_INVALID_PARAM;
+    }
+    if (NULL == resultCallback)
+    {
+        OIC_LOG_V(ERROR, TAG, "%s : NULL Callback", __func__);
+        return OC_STACK_INVALID_CALLBACK;
+    }
+
+    return MOTRemoveSubOwner(ctx, targetDeviceInfo, subOwner, resultCallback);
+}
+
+OCStackResult OCRemoveAllSubOwner(void* ctx,
+                                const OCProvisionDev_t *targetDeviceInfo,
+                                OCProvisionResultCB resultCallback)
+{
+    if (NULL == targetDeviceInfo)
+    {
+        OIC_LOG_V(ERROR, TAG, "%s : NULL Param", __func__);
+        return OC_STACK_INVALID_PARAM;
+    }
+    if (NULL == resultCallback)
+    {
+        OIC_LOG_V(ERROR, TAG, "%s : NULL Callback", __func__);
+        return OC_STACK_INVALID_CALLBACK;
+    }
+
+    return MOTRemoveSubOwner(ctx, targetDeviceInfo, &WILDCARD_SUBJECT_ID, resultCallback);
+}
+
+
+#endif //MULTIPLE_OWNER
 
 /**
  * API to register for particular OxM.
@@ -369,7 +446,7 @@ OCStackResult OCProvisionDirectPairing(void* ctx, const OCProvisionDev_t *select
     return SRPProvisionDirectPairing(ctx, selectedDeviceInfo, pconf, resultCallback);
 }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 static void AddPreconfPinOxMCB(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
 {
     ProvPreconfPINCtx_t* provCtx = (ProvPreconfPINCtx_t*)ctx;
@@ -390,7 +467,7 @@ OCStackResult OCProvisionPreconfigPin(void *ctx,
                                       size_t preconfigPinLen,
                                       OCProvisionResultCB resultCallback)
 {
-    if( NULL == targetDeviceInfo )
+    if( NULL == targetDeviceInfo || NULL == preconfigPin || 0 == preconfigPinLen )
     {
         return OC_STACK_INVALID_PARAM;
     }
@@ -419,7 +496,7 @@ OCStackResult OCProvisionPreconfigPin(void *ctx,
      */
     return MOTAddMOTMethod((void*)provCtx, targetDeviceInfo, OIC_PRECONFIG_PIN, AddPreconfPinOxMCB);
 }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
 /*
 * Function to unlink devices.
@@ -526,14 +603,12 @@ static OCStackResult RemoveDeviceInfoFromLocal(const OCProvisionDev_t* pTargetDe
     // TODO: We need to add new mechanism to clean up the stale state of the device.
 
     // Close the DTLS session of the removed device.
-    CAEndpoint_t *endpoint = (CAEndpoint_t *)&pTargetDev->endpoint;
-    endpoint->port = pTargetDev->securePort;
-    CAResult_t caResult = CAcloseSslSession(endpoint);
+    CAResult_t caResult = CAcloseSslConnectionUsingUuid(pTargetDev->doxm->deviceID.id
+                                                        , sizeof(pTargetDev->doxm->deviceID.id));
     if(CA_STATUS_OK != caResult)
     {
-        OIC_LOG_V(WARNING, TAG, "OCRemoveDevice : Failed to close DTLS session : %d", caResult);
+        OIC_LOG_V(WARNING, TAG, "OCRemoveDevice : Failed to close (D)TLS session : %d", caResult);
     }
-
     OIC_LOG(DEBUG, TAG, "OUT RemoveDeviceInfoFromLocal");
 error:
     return res;
@@ -818,6 +893,26 @@ OCStackResult OCResetDevice(void* ctx, unsigned short waitTimeForOwnedDeviceDisc
 }
 
 /**
+ * This function resets SVR DB to its factory setting.
+ *
+ * @return OC_STACK_OK in case of successful reset and other value otherwise.
+ */
+OCStackResult OCResetSVRDB(void)
+{
+    return ResetSecureResourceInPS();
+}
+
+/**
+ * This function configures SVR DB as self-ownership.
+ *
+ *@return OC_STACK_OK in case of successful configue and other value otherwise.
+ */
+OCStackResult OCConfigSelfOwnership(void)
+{
+    return ConfigSelfOwnership();
+}
+
+/**
  * Internal Function to update result in link result array.
  */
 static void UpdateLinkResults(Linkdata_t *link, int device, OCStackResult stackresult)
@@ -1240,7 +1335,7 @@ void OCDeletePdAclList(OicSecPdAcl_t* pPdAcl)
     FreePdAclList(pPdAcl);
 }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 /**
  * API to update 'doxm.mom' to resource server.
  *
@@ -1270,7 +1365,23 @@ OCStackResult OCSelectMOTMethod(void *ctx, const OCProvisionDev_t *targetDeviceI
 {
     return MOTSelectMOTMethod(ctx, targetDeviceInfo, oxmSelValue, resultCallback);
 }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
+
+/**
+ * Function to select appropriate security provisioning method.
+ *
+ * @param[in] supportedMethods   Array of supported methods
+ * @param[in] numberOfMethods   number of supported methods
+ * @param[out]  selectedMethod         Selected methods
+ * @param[in] ownerType type of owner device (SUPER_OWNER or SUB_OWNER)
+ * @return  OC_STACK_OK on success
+ */
+OCStackResult OCSelectOwnershipTransferMethod(const OicSecOxm_t *supportedMethods,
+        size_t numberOfMethods, OicSecOxm_t *selectedMethod, OwnerType_t ownerType)
+{
+    return OTMSelectOwnershipTransferMethod(supportedMethods, numberOfMethods,
+                                            selectedMethod, ownerType);
+}
 
 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
 /**
@@ -1326,5 +1437,25 @@ void OCRemoveTrustCertChainNotifier()
 {
     SRPRemoveTrustCertChainNotifier();
 }
+
+/**
+ * This function sets the callback to utilize peer certificate information
+ */
+OCStackResult OCSetPeerCertCallback(void *ctx, PeerCertCallback peerCertCallback)
+{
+    CAResult_t ret;
+
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+    ret = CAsetPeerCertCallback(ctx, peerCertCallback);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "CAsetPeerCertCallback() Failed(%d)", ret);
+        return OC_STACK_ERROR;
+    }
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+
+    return OC_STACK_OK;
+}
+
 #endif // __WITH_DTLS__ || __WITH_TLS__
 
index 6cfc96f..99cba81 100644 (file)
@@ -26,7 +26,7 @@
 #include "utlist.h"
 #include "otmcontextlist.h"
 
-#define TAG "OTM_CTX_LIST"
+#define TAG "OIC_OTM_CTX"
 
 /**
  * List for saving the OTMContext to be used while ownership transfer.
@@ -35,9 +35,8 @@ static OTMContextItem_t* g_otmCtxList = NULL;
 
 void RemoveOTMContext(const char* addr, uint16_t port)
 {
-    OTMContext_t* retCtx = NULL;
-
-    OIC_LOG(DEBUG, TAG, "IN RemoveOTMContext");
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+    size_t ctxCnt = 0;
 
     if (NULL != addr && 0 != port)
     {
@@ -46,20 +45,63 @@ void RemoveOTMContext(const char* addr, uint16_t port)
 
         LL_FOREACH_SAFE(g_otmCtxList, item, temp)
         {
+            ctxCnt++;
             if (strncmp(addr, item->endpoint.addr, sizeof(item->endpoint.addr)) == 0 &&
                 port == item->endpoint.port)
             {
                 OIC_LOG_V(DEBUG, TAG, "Remove [%s:%d]'s context from OTMContext list", addr, port);
-                retCtx = item->otmCtx;
                 item->otmCtx = NULL;
                 LL_DELETE(g_otmCtxList, item);
                 OICFree(item);
+                ctxCnt--;
                 break;
             }
         }
+
+        if (0 == ctxCnt)
+        {
+            g_otmCtxList = NULL;
+        }
     }
 
-    OIC_LOG(DEBUG, TAG, "OUT RemoveOTMContext");
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+}
+
+void DeleteOTMContextList()
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+
+    OTMContextItem_t* item = NULL;
+    OTMContextItem_t* temp = NULL;
+    int index = 0;
+
+    LL_FOREACH_SAFE(g_otmCtxList, item, temp)
+    {
+        LL_DELETE(g_otmCtxList, item);
+        if (item)
+        {
+            OIC_LOG_V(DEBUG, TAG, "Found OTM Context Item #%d in List", index++);
+            if (item->otmCtx)
+            {
+                OIC_LOG(DEBUG, TAG, "Found OTM Context is exist.");
+                if (item->otmCtx->selectedDeviceInfo)
+                {
+                    OIC_LOG_V(DEBUG, TAG, "Remove [%s:%d]'s context from OTMContext list",
+                              item->otmCtx->selectedDeviceInfo->endpoint.addr,
+                              item->otmCtx->selectedDeviceInfo->securePort);
+                }
+                if (item->otmCtx->ctxResultArray)
+                {
+                    OIC_LOG(DEBUG, TAG, "Found Result Array is exist in OTM Context.");
+                    OICFree(item->otmCtx->ctxResultArray);
+                }
+                OICFree(item->otmCtx);
+            }
+            OICFree(item);
+        }
+    }
+    g_otmCtxList = NULL;
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
 }
 
 OCStackResult AddOTMContext(OTMContext_t* ctx, const char* addr, uint16_t port)
@@ -68,7 +110,7 @@ OCStackResult AddOTMContext(OTMContext_t* ctx, const char* addr, uint16_t port)
     OTMContextItem_t* temp = NULL;
     OTMContextItem_t* newItem = NULL;
 
-    OIC_LOG(DEBUG, TAG, "IN AddOTMContext");
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
 
     if (NULL == ctx || NULL == addr || 0 == strlen(addr) || 0 == port)
     {
@@ -82,6 +124,7 @@ OCStackResult AddOTMContext(OTMContext_t* ctx, const char* addr, uint16_t port)
             {
                 //if OTM Context already exists, just return OC_STACK_OK.
                 OIC_LOG(DEBUG, TAG, "Same OTMContext already exists.");
+                item->otmCtx->ctxResultCallback = ctx->ctxResultCallback;
                 return OC_STACK_OK;
             }
     }
@@ -100,14 +143,14 @@ OCStackResult AddOTMContext(OTMContext_t* ctx, const char* addr, uint16_t port)
     newItem->endpoint.port = port;
     LL_APPEND(g_otmCtxList, newItem);
 
-    OIC_LOG(DEBUG, TAG, "OUT AddOTMContext");
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
 
     return OC_STACK_OK;
 }
 
-const OTMContext_t* GetOTMContext(const char* addr, uint16_t port)
+OTMContext_t* GetOTMContext(const char* addr, uint16_t port)
 {
-    OIC_LOG(DEBUG, TAG, "IN GetOTMContext");
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
 
     if (NULL != addr && 0 != port)
     {
@@ -125,7 +168,7 @@ const OTMContext_t* GetOTMContext(const char* addr, uint16_t port)
         }
     }
 
-    OIC_LOG(DEBUG, TAG, "OUT GetOTMContext");
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
 
     return NULL;
 }
index e07ebab..fc7946b 100644 (file)
@@ -42,6 +42,8 @@
 #endif
 #include <stdbool.h>
 #include <string.h>
+#include <stdlib.h>
+#include <pthread.h>
 
 #include "logger.h"
 #include "oic_malloc.h"
 #include "cacommon.h"
 #include "cainterface.h"
 #include "base64.h"
+#if defined (__TIZENRT__)
+#include <apps/netutils/cJSON.h>
+#else
 #include "cJSON.h"
-#include "global.h"
+#endif
 #include "utlist.h"
 #include "srmresourcestrings.h"
 #include "doxmresource.h"
 #include "oxmjustworks.h"
 #include "oxmrandompin.h"
 #include "oxmmanufacturercert.h"
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#include "secureresourceprovider.h"
+
+#ifdef MULTIPLE_OWNER
 #include "oxmpreconfpin.h"
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 #include "otmcontextlist.h"
 #include "pmtypes.h"
 #include "pmutility.h"
@@ -73,6 +80,8 @@
 #include "ocpayload.h"
 #include "payload_logging.h"
 #include "pkix_interface.h"
+#include "oxmverifycommon.h"
+#include "psinterface.h"
 
 #define TAG "OIC_OTM"
 
  * List of allowed oxm list.
  * All oxm methods are allowed as default.
  */
-static uint8_t g_OxmAllowStatus[OIC_OXM_COUNT] = {ALLOWED_OXM, ALLOWED_OXM, ALLOWED_OXM, NOT_ALLOWED_OXM};
-
-/**
- * Variables for pointing the OTMContext to be used in the DTLS handshake result callback.
- */
-static OTMContext_t* g_otmCtx = NULL;
+#ifdef MULTIPLE_OWNER
+static uint8_t g_OxmAllowStatus[OXM_IDX_COUNT] = {ALLOWED_OXM, ALLOWED_OXM, ALLOWED_OXM,
+                                                  ALLOWED_OXM, ALLOWED_OXM, ALLOWED_OXM,
+                                                  NOT_ALLOWED_OXM};
+#else
+static uint8_t g_OxmAllowStatus[OXM_IDX_COUNT] = {ALLOWED_OXM, ALLOWED_OXM, ALLOWED_OXM,
+                                                  ALLOWED_OXM, ALLOWED_OXM, NOT_ALLOWED_OXM};
+#endif
 
 OCStackResult OTMSetOTCallback(OicSecOxm_t oxm, OTMCallbackData_t* callbacks)
 {
@@ -98,11 +109,13 @@ OCStackResult OTMSetOTCallback(OicSecOxm_t oxm, OTMCallbackData_t* callbacks)
     OIC_LOG(INFO, TAG, "IN OTMSetOTCallback");
 
     VERIFY_NON_NULL(TAG, callbacks, ERROR);
-#ifdef _ENABLE_MULTIPLE_OWNER_
-    VERIFY_SUCCESS(TAG, (OIC_OXM_COUNT > oxm || OIC_PRECONFIG_PIN == oxm), ERROR);
+
+#ifdef MULTIPLE_OWNER
+    VERIFY_SUCCESS(TAG, (OIC_OXM_COUNT > oxm || OIC_PRECONFIG_PIN == oxm || OIC_MV_JUST_WORKS == oxm
+                    || OIC_CON_MFG_CERT == oxm), ERROR);
 #else
-    VERIFY_SUCCESS(TAG, (OIC_OXM_COUNT > oxm), ERROR);
-#endif //_ENABLE_MULTIPLE_OWNER_
+    VERIFY_SUCCESS(TAG, (OIC_OXM_COUNT > oxm || OIC_MV_JUST_WORKS == oxm || OIC_CON_MFG_CERT == oxm), ERROR);
+#endif // MULTIPLE_OWNER
 
     switch(oxm)
     {
@@ -127,14 +140,26 @@ OCStackResult OTMSetOTCallback(OicSecOxm_t oxm, OTMCallbackData_t* callbacks)
     case OIC_DECENTRALIZED_PUBLIC_KEY:
         OIC_LOG(ERROR, TAG, "OIC_DECENTRALIZED_PUBLIC_KEY not supported yet.");
         return OC_STACK_INVALID_METHOD;
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
     case OIC_PRECONFIG_PIN:
         callbacks->loadSecretCB = LoadPreconfigPinCodeCallback;
         callbacks->createSecureSessionCB = CreateSecureSessionPreconfigPinCallback;
         callbacks->createSelectOxmPayloadCB = CreatePreconfigPinBasedSelectOxmPayload;
         callbacks->createOwnerTransferPayloadCB = CreatePreconfigPinBasedOwnerTransferPayload;
         break;
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
+    case OIC_MV_JUST_WORKS:
+        callbacks->loadSecretCB = LoadSecretJustWorksCallback;
+        callbacks->createSecureSessionCB = CreateSecureSessionJustWorksCallback;
+        callbacks->createSelectOxmPayloadCB = CreateMVJustWorksSelectOxmPayload;
+        callbacks->createOwnerTransferPayloadCB = CreateJustWorksOwnerTransferPayload;
+        break;
+    case OIC_CON_MFG_CERT:
+        callbacks->loadSecretCB = PrepareMCertificateCallback;
+        callbacks->createSecureSessionCB = CreateSecureSessionMCertificateCallback;
+        callbacks->createSelectOxmPayloadCB = CreateConMCertificateBasedSelectOxmPayload;
+        callbacks->createOwnerTransferPayloadCB = CreateMCertificateBasedOwnerTransferPayload;
+        break;
     default:
         OIC_LOG_V(ERROR, TAG, "Unknown OxM : %d", (int)oxm);
         return OC_STACK_INVALID_PARAM;
@@ -148,50 +173,119 @@ exit:
 }
 
 /**
+ * Internal API to convert OxM value to index of oxm allow table.
+ */
+static OxmAllowTableIdx_t GetOxmAllowTableIdx(OicSecOxm_t oxm)
+{
+    switch(oxm)
+    {
+        case OIC_JUST_WORKS:
+            return OXM_IDX_JUST_WORKS;
+        case OIC_RANDOM_DEVICE_PIN:
+            return OXM_IDX_RANDOM_DEVICE_PIN;
+        case OIC_MANUFACTURER_CERTIFICATE:
+            return OXM_IDX_MANUFACTURER_CERTIFICATE;
+        case OIC_DECENTRALIZED_PUBLIC_KEY:
+            return OXM_IDX_DECENTRALIZED_PUBLIC_KEY;
+        case OIC_MV_JUST_WORKS:
+            return OXM_IDX_MV_JUST_WORKS;
+        case OIC_CON_MFG_CERT:
+            return OXM_IDX_CON_MFG_CERT;
+#ifdef MULTIPLE_OWNER
+        case OIC_PRECONFIG_PIN:
+            return OXM_IDX_PRECONFIG_PIN;
+#endif
+        default:
+            return OXM_IDX_UNKNOWN;
+    }
+}
+
+/**
  * Function to select appropriate  provisioning method.
  *
  * @param[in] supportedMethods   Array of supported methods
  * @param[in] numberOfMethods   number of supported methods
  * @param[out]  selectedMethod         Selected methods
+ * @param[in] ownerType type of owner device (SUPER_OWNER or SUB_OWNER)
  * @return  OC_STACK_OK on success
  */
-static OCStackResult SelectProvisioningMethod(const OicSecOxm_t *supportedMethods,
-        size_t numberOfMethods, OicSecOxm_t *selectedMethod)
+OCStackResult OTMSelectOwnershipTransferMethod(const OicSecOxm_t *supportedMethods,
+        size_t numberOfMethods, OicSecOxm_t *selectedMethod, OwnerType_t ownerType)
 {
     bool isOxmSelected = false;
+    OxmAllowTableIdx_t selectedOxmIdx = OXM_IDX_UNKNOWN;
 
     OIC_LOG(DEBUG, TAG, "IN SelectProvisioningMethod");
 
-    if(numberOfMethods == 0 || !supportedMethods)
+    if (numberOfMethods == 0 || !supportedMethods)
     {
         OIC_LOG(WARNING, TAG, "Could not find a supported OxM.");
         return OC_STACK_ERROR;
     }
 
-    for(size_t i = 0; i < numberOfMethods; i++)
+    switch(ownerType)
     {
-        if(ALLOWED_OXM == g_OxmAllowStatus[supportedMethods[i]])
+        case SUPER_OWNER:
+        {
+            for (size_t i = 0; i < numberOfMethods; i++)
+            {
+                selectedOxmIdx = GetOxmAllowTableIdx(supportedMethods[i]);
+                if (OXM_IDX_COUNT <= selectedOxmIdx)
+                {
+                    OIC_LOG(WARNING, TAG, "Invalid oxm index to access OxM allow table");
+                    continue;
+                }
+
+#ifdef MULTIPLE_OWNER
+                if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx] &&
+                   OXM_IDX_PRECONFIG_PIN != selectedOxmIdx)
+#else
+                if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx])
+#endif //MULTIPLE_OWNER
+                {
+                    *selectedMethod  = supportedMethods[i];
+                    isOxmSelected = true;
+                }
+            }
+        }
+        break;
+#ifdef MULTIPLE_OWNER
+        case SUB_OWNER:
+        {
+            for (size_t i = 0; i < numberOfMethods; i++)
+            {
+                selectedOxmIdx = GetOxmAllowTableIdx(supportedMethods[i]);
+                if (OXM_IDX_COUNT <= selectedOxmIdx)
+                {
+                    OIC_LOG(WARNING, TAG, "Invalid oxm index to access OxM allow table");
+                    continue;
+                }
+
+                //in case of MOT, only Random PIN & Preconfigured PIN based OxM is allowed
+                if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx] &&
+                    (OXM_IDX_RANDOM_DEVICE_PIN == selectedOxmIdx ||
+                     OXM_IDX_PRECONFIG_PIN == selectedOxmIdx))
+                {
+                    *selectedMethod  = supportedMethods[i];
+                    isOxmSelected = true;
+                }
+            }
+        }
+        break;
+#endif
+        default:
         {
-            *selectedMethod  = supportedMethods[i];
-            isOxmSelected = true;
-            break;
+            OIC_LOG_V(ERROR, TAG, "Unknown owner type or Not supported owner type : %d", ownerType);
+            return OC_STACK_INVALID_PARAM;
         }
     }
-    if(!isOxmSelected)
+
+    if (!isOxmSelected)
     {
         OIC_LOG(ERROR, TAG, "Can not find the allowed OxM.");
         return OC_STACK_NOT_ALLOWED_OXM;
     }
 
-    for(size_t i = 0; i < numberOfMethods; i++)
-    {
-        if(*selectedMethod < supportedMethods[i] &&
-           ALLOWED_OXM == g_OxmAllowStatus[supportedMethods[i]])
-        {
-            *selectedMethod =  supportedMethods[i];
-        }
-    }
-
     OIC_LOG(DEBUG, TAG, "OUT SelectProvisioningMethod");
 
     return OC_STACK_OK;
@@ -223,6 +317,14 @@ static void SelectOperationMode(const OCProvisionDev_t *selectedDeviceInfo,
  */
 static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice);
 
+/*
+ * Internal function to setup & cleanup PDM to performing provisioning.
+ *
+ * @param[in] selectedDevice   selected device information to performing provisioning.
+ * @return  OC_STACK_OK on success
+ */
+static OCStackResult SetupPDM(const OCProvisionDev_t* selectedDevice);
+
 /**
  * Function to update owner transfer mode
  *
@@ -323,11 +425,12 @@ static bool IsComplete(OTMContext_t* otmCtx)
  * @param[in,out] otmCtx   Context value of ownership transfer.
  * @param[in] res   result of provisioning
  */
-static void SetResult(OTMContext_t* otmCtx, const OCStackResult res)
+void SetResult(OTMContext_t* otmCtx, const OCStackResult res)
 {
     OIC_LOG_V(DEBUG, TAG, "IN SetResult : %d ", res);
 
-    if(NULL == otmCtx || NULL == otmCtx->selectedDeviceInfo)
+    if(NULL == otmCtx || NULL == otmCtx->selectedDeviceInfo
+            || NULL == otmCtx->selectedDeviceInfo->doxm)
     {
         OIC_LOG(WARNING, TAG, "OTMContext is NULL");
         return;
@@ -338,7 +441,6 @@ static void SetResult(OTMContext_t* otmCtx, const OCStackResult res)
                              otmCtx->selectedDeviceInfo->securePort))
     {
         OIC_LOG(WARNING, TAG, "Current OTM Process has already ended.");
-        return;
     }
 
     //Revert psk_info callback and new deivce uuid in case of random PIN OxM
@@ -351,7 +453,8 @@ static void SetResult(OTMContext_t* otmCtx, const OCStackResult res)
         OicUuid_t emptyUuid = { .id={0}};
         SetUuidForPinBasedOxm(&emptyUuid);
     }
-    else if(OIC_MANUFACTURER_CERTIFICATE == otmCtx->selectedDeviceInfo->doxm->oxmSel)
+    else if(OIC_MANUFACTURER_CERTIFICATE == otmCtx->selectedDeviceInfo->doxm->oxmSel ||
+                        OIC_CON_MFG_CERT == otmCtx->selectedDeviceInfo->doxm->oxmSel)
     {
         //Revert back certificate related callbacks.
         if(CA_STATUS_OK != CAregisterPkixInfoHandler(GetPkixInfo))
@@ -377,9 +480,10 @@ static void SetResult(OTMContext_t* otmCtx, const OCStackResult res)
                 {
                     OIC_LOG(WARNING, TAG, "Internal error in PDMDeleteDevice");
                 }
-                CAEndpoint_t* endpoint = (CAEndpoint_t *)&otmCtx->selectedDeviceInfo->endpoint;
-                endpoint->port = otmCtx->selectedDeviceInfo->securePort;
-                if (CA_STATUS_OK != CAcloseSslConnection(endpoint))
+                CAEndpoint_t endpoint;
+                memcpy(&endpoint, &(otmCtx->selectedDeviceInfo->endpoint), sizeof(CAEndpoint_t));
+                endpoint.port = otmCtx->selectedDeviceInfo->securePort;
+                if (CA_STATUS_OK != CAcloseSslConnection(&endpoint))
                 {
                     OIC_LOG(WARNING, TAG, "Failed to close Secure session");
                 }
@@ -414,6 +518,23 @@ static void SetResult(OTMContext_t* otmCtx, const OCStackResult res)
     //If all OTM process is complete, invoke the user callback.
     if(IsComplete(otmCtx))
     {
+        if(OC_STACK_OK != res && OC_STACK_CONTINUE != res && OC_STACK_DUPLICATE_REQUEST != res)
+        {
+            // Reset doxm and pstat properties to pre-Ownership Transfer state
+            OIC_LOG(DEBUG, TAG, "Resetting doxm and pstat properties");
+            if(otmCtx->selectedDeviceInfo->doxm)
+            {
+                OicUuid_t emptyUuid = {.id = {0}};
+                memcpy(&(otmCtx->selectedDeviceInfo->doxm->owner), &emptyUuid, sizeof(OicUuid_t));
+                otmCtx->selectedDeviceInfo->doxm->owned = false;
+            }
+            if(otmCtx->selectedDeviceInfo->pstat)
+            {
+                otmCtx->selectedDeviceInfo->pstat->isOp = false;
+                otmCtx->selectedDeviceInfo->pstat->cm |= TAKE_OWNER;
+            }
+        }
+
         otmCtx->ctxResultCallback(otmCtx->userCtx, otmCtx->ctxResultArraySize,
                                    otmCtx->ctxResultArray, otmCtx->ctxHasError);
         OICFree(otmCtx->ctxResultArray);
@@ -440,6 +561,7 @@ static void SetResult(OTMContext_t* otmCtx, const OCStackResult res)
  */
 void DTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info)
 {
+    OIC_LOG(DEBUG, TAG, "IN DTLSHandshakeCB");
     if(NULL != endpoint && NULL != info)
     {
         OIC_LOG_V(INFO, TAG, "Received status from remote device(%s:%d) : %d",
@@ -466,6 +588,59 @@ void DTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info)
                        false == newDevDoxm->owned &&
                        memcmp(&(newDevDoxm->owner), &emptyUuid, sizeof(OicUuid_t)) == 0)
                     {
+                        //In case of Mutual Verified Just-Works, display mutualVerifNum
+                        if (OIC_MV_JUST_WORKS == newDevDoxm->oxmSel)
+                        {
+                            uint8_t preMutualVerifNum[OWNER_PSK_LENGTH_128] = {0};
+                            uint8_t mutualVerifNum[MUTUAL_VERIF_NUM_LEN] = {0};
+                            OicUuid_t deviceID = {.id = {0}};
+
+                            //Generate mutualVerifNum
+                            char label[LABEL_LEN] = {0};
+                            snprintf(label, LABEL_LEN, "%s%s", MUTUAL_VERIF_NUM, OXM_MV_JUST_WORKS);
+                            res = GetDoxmDeviceID(&deviceID);
+                            if (OC_STACK_OK != res)
+                            {
+                                OIC_LOG(ERROR, TAG, "Error while retrieving Owner's device ID");
+                                SetResult(otmCtx, res);
+                                return;
+                            }
+
+                            CAResult_t pskRet = CAGenerateOwnerPSK(endpoint,
+                                    (uint8_t *)label,
+                                    strlen(label),
+                                    deviceID.id, sizeof(deviceID.id),
+                                    newDevDoxm->deviceID.id, sizeof(newDevDoxm->deviceID.id),
+                                    preMutualVerifNum, OWNER_PSK_LENGTH_128);
+                            if (CA_STATUS_OK != pskRet)
+                            {
+                                OIC_LOG(WARNING, TAG, "Failed to remove the invaild owner credential");
+                                SetResult(otmCtx, OC_STACK_ERROR);
+                                return;
+                            }
+
+                            memcpy(mutualVerifNum, preMutualVerifNum + OWNER_PSK_LENGTH_128 - sizeof(mutualVerifNum),
+                                    sizeof(mutualVerifNum));
+                            res = VerifyOwnershipTransfer(mutualVerifNum, DISPLAY_NUM);
+                            if (OC_STACK_OK != res)
+                            {
+                                OIC_LOG(ERROR, TAG, "Error while displaying mutualVerifNum");
+                                SetResult(otmCtx, res);
+                                return;
+                            }
+                        }
+                        //In case of confirmed manufacturer cert, display message
+                        else if (OIC_MANUFACTURER_CERTIFICATE == newDevDoxm->oxmSel || OIC_CON_MFG_CERT == newDevDoxm->oxmSel)
+                        {
+                            res = VerifyOwnershipTransfer(NULL, DISPLAY_NUM);
+                            if (OC_STACK_OK != res)
+                            {
+                                OIC_LOG(ERROR, TAG, "Error while displaying message");
+                                SetResult(otmCtx, res);
+                                return;
+                            }
+                        }
+
                         //Send request : POST /oic/sec/doxm [{... , "devowner":"PT's UUID"}]
                         res = PostOwnerUuid(otmCtx);
                         if(OC_STACK_OK != res)
@@ -498,19 +673,32 @@ void DTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info)
                             newDevDoxm->owned = false;
                             otmCtx->attemptCnt++;
 
-                            if(WRONG_PIN_MAX_ATTEMP > otmCtx->attemptCnt)
+                            RemoveOTMContext(otmCtx->selectedDeviceInfo->endpoint.addr,
+                                             otmCtx->selectedDeviceInfo->securePort);
+
+                            // In order to re-start ownership transfer, device information should be deleted from PDM.
+                            res = PDMDeleteDevice(&(otmCtx->selectedDeviceInfo->doxm->deviceID));
+                            if (OC_STACK_OK != res)
                             {
-                                res = StartOwnershipTransfer(otmCtx, otmCtx->selectedDeviceInfo);
-                                if(OC_STACK_OK != res)
-                                {
-                                    SetResult(otmCtx, res);
-                                    OIC_LOG(ERROR, TAG, "Failed to Re-StartOwnershipTransfer");
-                                }
+                                SetResult(otmCtx, res);
+                                OIC_LOG(ERROR, TAG, "Failed to PDMDeleteDevice");
                             }
                             else
                             {
-                                OIC_LOG(ERROR, TAG, "User has exceeded the number of authentication attempts.");
-                                SetResult(otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
+                                if(WRONG_PIN_MAX_ATTEMP > otmCtx->attemptCnt)
+                                {
+                                    res = StartOwnershipTransfer(otmCtx, otmCtx->selectedDeviceInfo);
+                                    if(OC_STACK_OK != res)
+                                    {
+                                        SetResult(otmCtx, res);
+                                        OIC_LOG(ERROR, TAG, "Failed to Re-StartOwnershipTransfer");
+                                    }
+                                }
+                                else
+                                {
+                                    OIC_LOG(ERROR, TAG, "User has exceeded the number of authentication attempts.");
+                                    SetResult(otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
+                                }
                             }
                         }
                         else
@@ -527,6 +715,7 @@ void DTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info)
             OIC_LOG(ERROR, TAG, "Can not find the OTM Context.");
         }
     }
+    OIC_LOG(DEBUG, TAG, "OUT DTLSHandshakeCB");
 }
 
 /**
@@ -556,7 +745,7 @@ static OCStackResult SaveOwnerPSK(OCProvisionDev_t *selectedDeviceInfo)
     }
 
     uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {0};
-    OicSecKey_t ownerKey = {ownerPSK, OWNER_PSK_LENGTH_128};
+    OicSecKey_t ownerKey = {.data=ownerPSK, .len=OWNER_PSK_LENGTH_128, .encoding=OIC_ENCODING_RAW};
 
     //Generating OwnerPSK
     CAResult_t pskRet = CAGenerateOwnerPSK(&endpoint,
@@ -577,14 +766,9 @@ static OCStackResult SaveOwnerPSK(OCProvisionDev_t *selectedDeviceInfo)
         OICClearMemory(ownerPSK, sizeof(ownerPSK));
         VERIFY_NON_NULL(TAG, cred, ERROR);
 
-        // TODO: Added as workaround. Will be replaced soon.
-        cred->privateData.encoding = OIC_ENCODING_RAW;
-
-#if 1
-        // NOTE: Test codes to use BASE64 encoded owner PSK.
         uint32_t outSize = 0;
         size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((OWNER_PSK_LENGTH_128 + 1));
-        char* b64Buf = (uint8_t *)OICCalloc(1, b64BufSize);
+        char* b64Buf = (char *)OICCalloc(1, b64BufSize);
         VERIFY_NON_NULL(TAG, b64Buf, ERROR);
         b64Encode(cred->privateData.data, cred->privateData.len, b64Buf, b64BufSize, &outSize);
 
@@ -592,16 +776,15 @@ static OCStackResult SaveOwnerPSK(OCProvisionDev_t *selectedDeviceInfo)
         cred->privateData.data = (uint8_t *)OICCalloc(1, outSize + 1);
         VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
 
-        strncpy(cred->privateData.data, b64Buf, outSize);
+        strncpy((char*)(cred->privateData.data), b64Buf, outSize);
         cred->privateData.data[outSize] = '\0';
         cred->privateData.encoding = OIC_ENCODING_BASE64;
         cred->privateData.len = outSize;
         OICFree(b64Buf);
-#endif //End of Test codes
 
         //Finding previous ownerPSK.
         const OicSecCred_t* credList = GetCredList();
-        OicSecCred_t* prevCred = NULL;
+        const OicSecCred_t* prevCred = NULL;
         uint16_t credId = 0;
         LL_FOREACH(credList, prevCred)
         {
@@ -797,6 +980,22 @@ static OCStackApplicationResult OwnerUuidUpdateHandler(void *ctx, OCDoHandle UNU
     {
         if(otmCtx && otmCtx->selectedDeviceInfo)
         {
+            //In case of Mutual Verified Just-Works, wait for user confirmation
+            if (OIC_MV_JUST_WORKS == otmCtx->selectedDeviceInfo->doxm->oxmSel)
+            {
+                res = VerifyOwnershipTransfer(NULL, USER_CONFIRM);
+                if (OC_STACK_OK != res)
+                {
+                    if (OC_STACK_OK != SRPResetDevice(otmCtx->selectedDeviceInfo, otmCtx->ctxResultCallback))
+                    {
+                        OIC_LOG(WARNING, TAG, "OwnerUuidUpdateHandler : SRPResetDevice error");
+                    }
+                    OIC_LOG(ERROR, TAG, "OwnerUuidUpdateHandler:Failed to verify user confirm");
+                    SetResult(otmCtx, res);
+                    return OC_STACK_DELETE_TRANSACTION;
+                }
+            }
+
             res = SaveOwnerPSK(otmCtx->selectedDeviceInfo);
             if(OC_STACK_OK != res)
             {
@@ -818,8 +1017,25 @@ static OCStackApplicationResult OwnerUuidUpdateHandler(void *ctx, OCDoHandle UNU
     }
     else
     {
-        res = clientResponse->result;
-        OIC_LOG_V(ERROR, TAG, "OwnerUuidHandler : Unexpected result %d", res);
+        if (((OIC_MANUFACTURER_CERTIFICATE == otmCtx->selectedDeviceInfo->doxm->oxmSel) ||
+            (OIC_CON_MFG_CERT == otmCtx->selectedDeviceInfo->doxm->oxmSel)) &&
+                    OC_STACK_NOT_ACCEPTABLE == clientResponse->result)
+        {
+            res = OC_STACK_USER_DENIED_REQ;
+            OIC_LOG_V(ERROR, TAG,
+                    "OwnerUuidUpdateHandler : Denied Request(%d)", res);
+        }
+        else if (OC_STACK_GATEWAY_TIMEOUT == clientResponse->result)
+        {
+            res = clientResponse->result;
+            OIC_LOG_V(ERROR, TAG,
+                    "OwnerUuidUpdateHandler : Timeout:No Response Received(%d)", res);
+        }
+        else
+        {
+            res = clientResponse->result;
+            OIC_LOG_V(ERROR, TAG, "OwnerUuidUpdateHandler : Unexpected result(%d)", res);
+        }
         SetResult(otmCtx, res);
     }
 
@@ -829,6 +1045,49 @@ exit:
     return  OC_STACK_DELETE_TRANSACTION;
 }
 
+/*
+ * Invokes Callback to load Random PIN
+ */
+void *LoadRandomPin(void *ctx)
+{
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+    OTMContext_t* otmCtx = (OTMContext_t*)ctx;
+    OCStackResult res = OC_STACK_ERROR;
+    res = otmCtx->otmCallback.loadSecretCB(otmCtx);
+
+    if(OC_STACK_OK != res)
+    {
+        OIC_LOG_V(ERROR, TAG, "%s : Failed to load secret", __func__);
+        SetResult(otmCtx, res);
+        OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+        return NULL;
+    }
+
+    //Save the current context instance to use on the dtls handshake callback
+    if(OC_STACK_OK != AddOTMContext(otmCtx,
+                                     otmCtx->selectedDeviceInfo->endpoint.addr,
+                                     otmCtx->selectedDeviceInfo->securePort))
+    {
+        OIC_LOG_V(ERROR, TAG, "%s : Failed to add OTM Context into OTM List.", __func__);
+        SetResult(otmCtx, res);
+        OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+        return NULL;
+    }
+
+    //Try DTLS handshake to generate secure session
+    if(otmCtx->otmCallback.createSecureSessionCB)
+    {
+        res = otmCtx->otmCallback.createSecureSessionCB(otmCtx);
+        if(OC_STACK_OK != res)
+        {
+            OIC_LOG_V(ERROR, TAG, "%s : Failed to create DTLS session", __func__);
+            SetResult(otmCtx, res);
+        }
+    }
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+    return NULL;
+}
+
 /**
  * Response handler for update operation mode.
  *
@@ -857,34 +1116,50 @@ static OCStackApplicationResult OperationModeUpdateHandler(void *ctx, OCDoHandle
         //Load secret for temporal secure session.
         if(otmCtx->otmCallback.loadSecretCB)
         {
-            res = otmCtx->otmCallback.loadSecretCB(otmCtx);
-            if(OC_STACK_OK != res)
+            if (OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel)
             {
-                OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to load secret");
-                SetResult(otmCtx, res);
-                return  OC_STACK_DELETE_TRANSACTION;
+                pthread_t p_thread;
+                int thr_result;
+                thr_result = pthread_create(&p_thread, NULL, LoadRandomPin, (void *) otmCtx);
+                if (0 != thr_result)
+                {
+                    OIC_LOG_V(ERROR, TAG, "pthread_create Error with code %d", thr_result);
+                    SetResult(otmCtx, res);
+                    return  OC_STACK_DELETE_TRANSACTION;
+                }
+                OIC_LOG(INFO, TAG, "Random Pin loadSecretCB Thread Created");
             }
-        }
+            else
+            {
+                res = otmCtx->otmCallback.loadSecretCB(otmCtx);
+                if(OC_STACK_OK != res)
+                {
+                    OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to load secret");
+                    SetResult(otmCtx, res);
+                    return  OC_STACK_DELETE_TRANSACTION;
+                }
 
-        //Save the current context instance to use on the dtls handshake callback
-        if(OC_STACK_OK != AddOTMContext(otmCtx,
-                                         otmCtx->selectedDeviceInfo->endpoint.addr,
-                                         otmCtx->selectedDeviceInfo->securePort))
-        {
-            OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to add OTM Context into OTM List.");
-            SetResult(otmCtx, res);
-            return OC_STACK_DELETE_TRANSACTION;
-        }
+                //Save the current context instance to use on the dtls handshake callback
+                if(OC_STACK_OK != AddOTMContext(otmCtx,
+                                                 otmCtx->selectedDeviceInfo->endpoint.addr,
+                                                 otmCtx->selectedDeviceInfo->securePort))
+                {
+                    OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to add OTM Context into OTM List.");
+                    SetResult(otmCtx, res);
+                    return OC_STACK_DELETE_TRANSACTION;
+                }
 
-        //Try DTLS handshake to generate secure session
-        if(otmCtx->otmCallback.createSecureSessionCB)
-        {
-            res = otmCtx->otmCallback.createSecureSessionCB(otmCtx);
-            if(OC_STACK_OK != res)
-            {
-                OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to create DTLS session");
-                SetResult(otmCtx, res);
-                return OC_STACK_DELETE_TRANSACTION;
+                //Try DTLS handshake to generate secure session
+                if(otmCtx->otmCallback.createSecureSessionCB)
+                {
+                    res = otmCtx->otmCallback.createSecureSessionCB(otmCtx);
+                    if(OC_STACK_OK != res)
+                    {
+                        OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to create DTLS session");
+                        SetResult(otmCtx, res);
+                        return OC_STACK_DELETE_TRANSACTION;
+                    }
+                }
             }
         }
     }
@@ -944,7 +1219,6 @@ static OCStackApplicationResult OwnerCredentialHandler(void *ctx, OCDoHandle UNU
              */
             // TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256 = 0xC037, /**< see RFC 5489 */
             caResult = CASelectCipherSuite(0xC037, endpoint->adapter);
-
             if(CA_STATUS_OK != caResult)
             {
                 OIC_LOG(ERROR, TAG, "Failed to select TLS_NULL_WITH_NULL_NULL");
@@ -1238,12 +1512,13 @@ static OCStackResult PostOwnerCredential(OTMContext_t* otmCtx)
         memcpy(&(newCredential.subject), &credSubjectId, sizeof(OicUuid_t));
 
         //Fill private data as empty string
-        newCredential.privateData.data = "";
+        newCredential.privateData.data = (uint8_t*)"";
         newCredential.privateData.len = 0;
         newCredential.privateData.encoding = ownerCredential->privateData.encoding;
 
         newCredential.publicData.data = NULL;
         newCredential.publicData.len = 0;
+        newCredential.publicData.encoding = ownerCredential->publicData.encoding;
 
         int secureFlag = 0;
         //Send owner credential to new device : POST /oic/sec/cred [ owner credential ]
@@ -1704,92 +1979,151 @@ static OCStackResult PostUpdateOperationMode(OTMContext_t* otmCtx)
     return res;
 }
 
-static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice)
+static OCStackResult SetupPDM(const OCProvisionDev_t* selectedDevice)
 {
-    OIC_LOG(INFO, TAG, "IN StartOwnershipTransfer");
-    OCStackResult res = OC_STACK_INVALID_PARAM;
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
 
-    VERIFY_NON_NULL(TAG, selectedDevice, ERROR);
-    VERIFY_NON_NULL(TAG, selectedDevice->doxm, ERROR);
+    PdmDeviceState_t pdmState = PDM_DEVICE_UNKNOWN;
+    OCStackResult res = PDMGetDeviceState(&selectedDevice->doxm->deviceID, &pdmState);
+    if (OC_STACK_OK != res)
+    {
+        OIC_LOG_V(ERROR, TAG, "Internal error in PDMGetDeviceState : %d", res);
+        return res;
+    }
 
-    OTMContext_t* otmCtx = (OTMContext_t*)ctx;
-    otmCtx->selectedDeviceInfo = selectedDevice;
+    char* strUuid = NULL;
+    bool removeCredReq = false;
+    if (OC_STACK_OK != ConvertUuidToStr(&selectedDevice->doxm->deviceID, &strUuid))
+    {
+        OIC_LOG(WARNING, TAG, "Failed to covert uuid to string");
+        return OC_STACK_NO_MEMORY;
+    }
+
+    if (PDM_DEVICE_UNKNOWN == pdmState && !selectedDevice->doxm->owned)
+    {
+        removeCredReq = true;
+    }
+    else if (PDM_DEVICE_ACTIVE == pdmState && !selectedDevice->doxm->owned)
+    {
+        OIC_LOG_V(WARNING, TAG, "Unowned device[%s] dectected from PDM.", strUuid);
+        OIC_LOG_V(WARNING, TAG, "[%s] will be removed from PDM.", strUuid);
+        res = PDMDeleteDevice(&selectedDevice->doxm->deviceID);
+        if(OC_STACK_OK != res)
+        {
+            OIC_LOG_V(ERROR, TAG, "Failed to remove [%s] information from PDM.", strUuid);
+            goto exit;
+        }
+
+        removeCredReq = true;
+    }
+
+    if (removeCredReq)
+    {
+        OIC_LOG_V(WARNING, TAG, "[%s]'s credential will be removed.", strUuid);
+        res = RemoveCredential(&selectedDevice->doxm->deviceID);
+        if (OC_STACK_RESOURCE_DELETED != res)
+        {
+            OIC_LOG_V(WARNING, TAG, "Can not find [%s]'s credential.", strUuid);
+        }
+    }
 
     //Checking duplication of Device ID.
     bool isDuplicate = true;
     res = PDMIsDuplicateDevice(&selectedDevice->doxm->deviceID, &isDuplicate);
     if (OC_STACK_OK != res)
     {
-        OIC_LOG(ERROR, TAG, "Internal error in PDMIsDuplicateDevice");
-        return res;
+        OIC_LOG_V(ERROR, TAG, "Internal error in PDMIsDuplicateDevice : %d", res);
+        goto exit;
     }
+
     if (isDuplicate)
     {
-        PdmDeviceState_t state = PDM_DEVICE_UNKNOWN;
-        res = PDMGetDeviceState(&selectedDevice->doxm->deviceID, &state);
-        if(OC_STACK_OK != res)
-        {
-            OIC_LOG(ERROR, TAG, "Internal error in PDMGetDeviceState");
-            SetResult(otmCtx, res);
-            return res;
-        }
-
         char* strUuid = NULL;
         res = ConvertUuidToStr(&selectedDevice->doxm->deviceID, &strUuid);
-        if(OC_STACK_OK != res)
+        if (OC_STACK_OK != res)
         {
-            OIC_LOG(ERROR, TAG, "Failed to convert UUID to str");
-            SetResult(otmCtx, res);
-            return res;
+            OIC_LOG_V(ERROR, TAG, "Failed to convert UUID to str : %d", res);
+            goto exit;
         }
 
-        if(PDM_DEVICE_STALE == state)
+        if (PDM_DEVICE_STALE == pdmState)
         {
             OIC_LOG(INFO, TAG, "Detected duplicated UUID in stale status, "
                                "device status will revert back to initial status.");
             res = PDMSetDeviceState(&selectedDevice->doxm->deviceID, PDM_DEVICE_INIT);
-            if(OC_STACK_OK != res)
+            if (OC_STACK_OK != res)
             {
-                OIC_LOG(ERROR, TAG, "Internal error in PDMSetDeviceState");
-                OICFree(strUuid);
-                SetResult(otmCtx, res);
-                return res;
+                OIC_LOG_V(ERROR, TAG, "Internal error in PDMSetDeviceState : %d", res);
+                goto exit;
             }
         }
-        else if(PDM_DEVICE_INIT == state)
+        else if (PDM_DEVICE_INIT == pdmState)
         {
             OIC_LOG_V(ERROR, TAG, "[%s]'s ownership transfer process is already started.", strUuid);
             OICFree(strUuid);
-            SetResult(otmCtx, OC_STACK_DUPLICATE_REQUEST);
-            return OC_STACK_OK;
+            res = OC_STACK_DUPLICATE_REQUEST;
+            goto exit;
         }
         else
         {
             OIC_LOG(ERROR, TAG, "Unknow device status while OTM.");
             OICFree(strUuid);
-            SetResult(otmCtx, OC_STACK_ERROR);
-            return OC_STACK_ERROR;
+            res = OC_STACK_ERROR;
+            goto exit;
         }
     }
     else
     {
         res = PDMAddDevice(&selectedDevice->doxm->deviceID);
-        if(OC_STACK_OK != res)
+        if (OC_STACK_OK != res)
         {
-            OIC_LOG(ERROR, TAG, "Internal error in PDMAddDevice");
-            SetResult(otmCtx, res);
-            return res;
+            OIC_LOG_V(ERROR, TAG, "Internal error in PDMAddDevice : %d", res);
+            goto exit;
         }
     }
 
+exit:
+    OICFree(strUuid);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+    return res;
+}
 
-    //Set to the lowest level OxM, and then find more higher level OxM.
-    res = SelectProvisioningMethod(selectedDevice->doxm->oxm,
-                                   selectedDevice->doxm->oxmLen,
-                                   &selectedDevice->doxm->oxmSel);
+static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selectedDevice)
+{
+    OIC_LOG(INFO, TAG, "IN StartOwnershipTransfer");
+    OCStackResult res = OC_STACK_INVALID_PARAM;
+    OicUuid_t emptyOwner = {.id = {0} };
+
+    VERIFY_NON_NULL(TAG, selectedDevice, ERROR);
+    VERIFY_NON_NULL(TAG, selectedDevice->doxm, ERROR);
+
+    OTMContext_t* otmCtx = (OTMContext_t*)ctx;
+    otmCtx->selectedDeviceInfo = selectedDevice;
+
+    //If devowneruuid of selectedDevice is not emtry, PostOwnerUuid does not triggered in DTLSHandshakeCB
+    if (memcmp(&(selectedDevice->doxm->owner), &emptyOwner, sizeof(OicUuid_t)) != 0)
+    {
+        OIC_LOG(DEBUG, TAG, "Set devowneruuid of selectedDevice to empty for OwnershipTransfer");
+        memcpy(&(selectedDevice->doxm->owner), &emptyOwner, sizeof(OicUuid_t));
+    }
+
+    //Setup PDM to perform the OTM, PDM will be cleanup if necessary.
+    res = SetupPDM(selectedDevice);
+    if(OC_STACK_OK != res)
+    {
+        OIC_LOG_V(ERROR, TAG, "SetupPDM error : %d", res);
+        SetResult(otmCtx, res);
+        return res;
+    }
+
+    //Select the OxM to performing ownership transfer
+    res = OTMSelectOwnershipTransferMethod(selectedDevice->doxm->oxm,
+                                          selectedDevice->doxm->oxmLen,
+                                          &selectedDevice->doxm->oxmSel,
+                                          SUPER_OWNER);
     if(OC_STACK_OK != res)
     {
-        OIC_LOG(ERROR, TAG, "Failed to select the provisioning method");
+        OIC_LOG_V(ERROR, TAG, "Failed to select the provisioning method : %d", res);
         SetResult(otmCtx, res);
         return res;
     }
@@ -1806,7 +2140,7 @@ static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selecte
     res = PostOwnerTransferModeToResource(otmCtx);
     if(OC_STACK_OK != res)
     {
-        OIC_LOG(WARNING, TAG, "Failed to select the provisioning method");
+        OIC_LOG_V(WARNING, TAG, "Failed to select the provisioning method : %d", res);
         SetResult(otmCtx, res);
         return res;
     }
@@ -1893,7 +2227,6 @@ OCStackResult OTMDoOwnershipTransfer(void* ctx,
     }
     pCurDev = selectedDevicelist;
 
-    OCStackResult res = OC_STACK_OK;
     //Fill the device UUID for result array.
     for(size_t devIdx = 0; devIdx < otmCtx->ctxResultArraySize; devIdx++)
     {
@@ -1904,10 +2237,11 @@ OCStackResult OTMDoOwnershipTransfer(void* ctx,
         pCurDev = pCurDev->next;
     }
 
-    StartOwnershipTransfer(otmCtx, selectedDevicelist);
+    OCStackResult res = StartOwnershipTransfer(otmCtx, selectedDevicelist);
 
     OIC_LOG(DEBUG, TAG, "OUT OTMDoOwnershipTransfer");
-    return OC_STACK_OK;
+
+    return res;
 }
 
 OCStackResult OTMSetOxmAllowStatus(const OicSecOxm_t oxm, const bool allowStatus)
@@ -1915,12 +2249,22 @@ OCStackResult OTMSetOxmAllowStatus(const OicSecOxm_t oxm, const bool allowStatus
     OIC_LOG_V(INFO, TAG, "IN %s : oxm=%d, allow status=%s",
               __func__, oxm, (allowStatus ? "true" : "false"));
 
-    if(OIC_OXM_COUNT <= oxm)
+#ifdef MULTIPLE_OWNER
+    if(OIC_OXM_COUNT <= oxm && OIC_MV_JUST_WORKS != oxm && OIC_PRECONFIG_PIN != oxm && OIC_CON_MFG_CERT != oxm)
+#else
+    if(OIC_OXM_COUNT <= oxm && OIC_MV_JUST_WORKS != oxm && OIC_CON_MFG_CERT != oxm)
+#endif
     {
         return OC_STACK_INVALID_PARAM;
     }
 
-    g_OxmAllowStatus[oxm] = (allowStatus ? ALLOWED_OXM : NOT_ALLOWED_OXM);
+    OxmAllowTableIdx_t oxmIdx = GetOxmAllowTableIdx(oxm);
+    if(OXM_IDX_COUNT <= oxmIdx)
+    {
+        OIC_LOG(ERROR, TAG, "Invalid oxm index to access oxm allow table.");
+        return OC_STACK_ERROR;
+    }
+    g_OxmAllowStatus[oxmIdx] = (allowStatus ? ALLOWED_OXM : NOT_ALLOWED_OXM);
 
     OIC_LOG_V(INFO, TAG, "OUT %s", __func__);
 
@@ -2042,3 +2386,97 @@ OCStackResult PostNormalOperationStatus(OTMContext_t* otmCtx)
 
     return ret;
 }
+
+OCStackResult ConfigSelfOwnership(void)
+{
+    OIC_LOG(INFO, TAG, "IN ConfigSelfOwnership");
+
+    bool isDeviceOwned = true;
+    if (OC_STACK_OK != GetDoxmIsOwned(&isDeviceOwned))
+    {
+        OIC_LOG (ERROR, TAG, "Unable to retrieve doxm owned state");
+        return OC_STACK_ERROR;
+    }
+    if( (true == isDeviceOwned) ||(true == GetPstatIsop()) )
+    {
+        OIC_LOG(ERROR, TAG, "The state of device is not Ready for Ownership transfer.");
+        return OC_STACK_ERROR;
+    }
+    OicUuid_t deviceID = {.id={0}};
+    if ( OC_STACK_OK != GetDoxmDeviceID(&deviceID) )
+    {
+        OIC_LOG (ERROR, TAG, "Unable to retrieve doxm Device ID");
+        return OC_STACK_ERROR;
+    }
+
+    OCStackResult ret = OC_STACK_OK;
+    //Update the pstat resource as Normal Operation.
+    ret = SetPstatSelfOwnership(&deviceID);
+    if(OC_STACK_OK != ret)
+    {
+        OIC_LOG (ERROR, TAG, "Unable to update pstat resource as Normal Operation");
+        goto exit;
+    }
+    //Update the doxm resource as Normal Operation.
+    ret = SetDoxmSelfOwnership(&deviceID);
+    if(OC_STACK_OK != ret)
+    {
+        OIC_LOG (ERROR, TAG, "Unable to update doxm resource as Normal Operation");
+        goto exit;
+    }
+    //Update default ACE of security resource to prevent anonymous user access.
+    ret = UpdateDefaultSecProvACE();
+    if(OC_STACK_OK != ret)
+    {
+        OIC_LOG (ERROR, TAG, "Unable to update default ace in ConfigSelfOwnership");
+        goto exit;
+    }
+    //Update the acl resource owner as owner device.
+    ret = SetAclRownerId(&deviceID);
+    if(OC_STACK_OK != ret)
+    {
+        OIC_LOG (ERROR, TAG, "Unable to update acl resource in ConfigSelfOwnership");
+        goto exit;
+    }
+    //Update the cred resource owner as owner device.
+    ret = SetCredRownerId(&deviceID);
+    if(OC_STACK_OK != ret)
+    {
+        // Cred resouce may be empty in Ready for Ownership transfer state.
+        if (OC_STACK_NO_RESOURCE == ret)
+        {
+            OIC_LOG (INFO, TAG, "Cred resource is empty");
+            ret = OC_STACK_OK;
+            goto exit;
+        }
+        OIC_LOG (ERROR, TAG, "Unable to update cred resource in ConfigSelfOwnership");
+    }
+
+exit:
+    if(OC_STACK_OK != ret)
+    {
+        /*
+         * If some error is occured while configure self-ownership,
+         * ownership related resource should be revert back to initial status.
+        */
+        ResetSecureResourceInPS();
+    }
+
+    return ret;
+}
+
+
+void OTMTerminate()
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+    DeleteOTMContextList();
+
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+    if(CA_STATUS_OK != CAregisterSslHandshakeCallback(NULL))
+    {
+        OIC_LOG(WARNING, TAG, "Failed to register (D)TLS handshake callback.");
+    }
+#endif // __WITH_DTLS__ or __WITH_TLS__
+
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+}
index 90ee407..ce696ff 100644 (file)
@@ -26,7 +26,6 @@
 #include "cainterface.h"
 #include "oic_malloc.h"
 #include "logger.h"
-#include "global.h"
 #include "pmtypes.h"
 #include "ownershiptransfermanager.h"
 
@@ -91,10 +90,10 @@ OCStackResult CreateSecureSessionJustWorksCallback(OTMContext_t* otmCtx)
     }
     OIC_LOG(INFO, TAG, "Anonymous cipher suite Enabled.");
 
-    caresult  = CASelectCipherSuite(TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256, otmCtx->selectedDeviceInfo->endpoint.adapter);
+    caresult  = CASelectCipherSuite(MBEDTLS_TLS_ECDH_ANON_WITH_AES_128_CBC_SHA256, otmCtx->selectedDeviceInfo->endpoint.adapter);
     if (CA_STATUS_OK != caresult)
     {
-        OIC_LOG_V(ERROR, TAG, "Failed to select TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256");
+        OIC_LOG_V(ERROR, TAG, "Failed to select TLS_ECDH_anon_WITH_AES_128_CBC_SHA256");
         caresult = CAEnableAnonECDHCipherSuite(false);
         if (CA_STATUS_OK != caresult)
         {
@@ -106,7 +105,7 @@ OCStackResult CreateSecureSessionJustWorksCallback(OTMContext_t* otmCtx)
         }
         return OC_STACK_ERROR;
     }
-    OIC_LOG(INFO, TAG, "TLS_ECDH_anon_WITH_AES_128_CBC_SHA_256 cipher suite selected.");
+    OIC_LOG(INFO, TAG, "TLS_ECDH_anon_WITH_AES_128_CBC_SHA256 cipher suite selected.");
 
     OCProvisionDev_t *selDevInfo = otmCtx->selectedDeviceInfo;
     CAEndpoint_t endpoint;
@@ -117,6 +116,10 @@ OCStackResult CreateSecureSessionJustWorksCallback(OTMContext_t* otmCtx)
         endpoint.port = selDevInfo->securePort;
         caresult = CAInitiateHandshake(&endpoint);
     }
+    else if (CA_ADAPTER_GATT_BTLE == endpoint.adapter)
+    {
+        caresult = CAInitiateHandshake(&endpoint);
+    }
 #ifdef __WITH_TLS__
     else
     {
@@ -133,3 +136,19 @@ OCStackResult CreateSecureSessionJustWorksCallback(OTMContext_t* otmCtx)
     OIC_LOG(INFO, TAG, "OUT CreateSecureSessionJustWorksCallback");
     return OC_STACK_OK;
 }
+
+OCStackResult CreateMVJustWorksSelectOxmPayload(OTMContext_t *otmCtx, uint8_t **cborPayload,
+                                             size_t *cborSize)
+{
+    if (!otmCtx || !otmCtx->selectedDeviceInfo || !cborPayload || *cborPayload || !cborSize)
+    {
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    otmCtx->selectedDeviceInfo->doxm->oxmSel = OIC_MV_JUST_WORKS;
+    *cborPayload = NULL;
+    *cborSize = 0;
+
+    return DoxmToCBORPayload(otmCtx->selectedDeviceInfo->doxm, cborPayload, cborSize, true);
+}
+
index 7a24e99..671f78f 100644 (file)
@@ -31,7 +31,6 @@
 #include "oic_malloc.h"
 #include "logger.h"
 #include "pbkdf2.h"
-#include "global.h"
 #include "base64.h"
 #include "oxmmanufacturercert.h"
 #include "ownershiptransfermanager.h"
@@ -53,6 +52,18 @@ OCStackResult CreateMCertificateBasedSelectOxmPayload(OTMContext_t* otmCtx, uint
     return DoxmToCBORPayload(otmCtx->selectedDeviceInfo->doxm, payload, size, true);
 }
 
+OCStackResult CreateConMCertificateBasedSelectOxmPayload(OTMContext_t* otmCtx, uint8_t **payload, size_t *size)
+{
+    if (!otmCtx || !otmCtx->selectedDeviceInfo || !payload || *payload || !size)
+    {
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    otmCtx->selectedDeviceInfo->doxm->oxmSel = OIC_CON_MFG_CERT;
+
+    return DoxmToCBORPayload(otmCtx->selectedDeviceInfo->doxm, payload, size, true);
+}
+
 OCStackResult CreateMCertificateBasedOwnerTransferPayload(OTMContext_t* otmCtx, uint8_t **payload, size_t *size)
 {
     if (!otmCtx || !otmCtx->selectedDeviceInfo || !payload || *payload || !size)
@@ -117,14 +128,14 @@ OCStackResult CreateSecureSessionMCertificateCallback(OTMContext_t* otmCtx)
     }
     OIC_LOG(INFO, TAG, "Anonymous cipher suite disabled.");
 
-    caresult  = CASelectCipherSuite(MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+    caresult  = CASelectCipherSuite(MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8,
                                     otmCtx->selectedDeviceInfo->endpoint.adapter);
     if (CA_STATUS_OK != caresult)
     {
-        OIC_LOG_V(ERROR, TAG, "Failed to select TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256");
+        OIC_LOG_V(ERROR, TAG, "Failed to select MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8");
         return OC_STACK_ERROR;
     }
-    OIC_LOG(INFO, TAG, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 cipher suite selected.");
+    OIC_LOG(INFO, TAG, "MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 cipher suite selected.");
 
     OCProvisionDev_t* selDevInfo = otmCtx->selectedDeviceInfo;
     CAEndpoint_t *endpoint = (CAEndpoint_t *)OICCalloc(1, sizeof (CAEndpoint_t));
index ecdeb35..83f1687 100644 (file)
@@ -30,7 +30,6 @@
 #include "oic_malloc.h"
 #include "logger.h"
 #include "pbkdf2.h"
-#include "global.h"
 #include "base64.h"
 #include "oxmpreconfpin.h"
 #include "ownershiptransfermanager.h"
@@ -146,7 +145,7 @@ OCStackResult LoadPreconfigPinCodeCallback(OTMContext_t *otmCtx)
             res = OC_STACK_ERROR;
         }
     }
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
     //in case of MOT
     else if(true == otmCtx->selectedDeviceInfo->doxm->owned &&
             otmCtx->selectedDeviceInfo->doxm->mom &&
@@ -158,7 +157,7 @@ OCStackResult LoadPreconfigPinCodeCallback(OTMContext_t *otmCtx)
             res = OC_STACK_ERROR;
         }
     }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
     //Set the device id to derive temporal PSK
     SetUuidForPinBasedOxm(&(otmCtx->selectedDeviceInfo->doxm->deviceID));
@@ -185,13 +184,13 @@ OCStackResult CreateSecureSessionPreconfigPinCallback(OTMContext_t* otmCtx)
     }
     OIC_LOG(INFO, TAG, "Anonymous cipher suite disabled.");
 
-    caresult  = CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256, otmCtx->selectedDeviceInfo->endpoint.adapter);
+    caresult  = CASelectCipherSuite(MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, otmCtx->selectedDeviceInfo->endpoint.adapter);
     if (CA_STATUS_OK != caresult)
     {
-        OIC_LOG_V(ERROR, TAG, "Failed to select TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256");
+        OIC_LOG_V(ERROR, TAG, "Failed to select TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256");
         return OC_STACK_ERROR;
     }
-    OIC_LOG(INFO, TAG, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256 cipher suite selected.");
+    OIC_LOG(INFO, TAG, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 cipher suite selected.");
 
     OCProvisionDev_t* selDevInfo = otmCtx->selectedDeviceInfo;
     CAEndpoint_t *endpoint = (CAEndpoint_t *)OICCalloc(1, sizeof (CAEndpoint_t));
index dcf7214..314e5b7 100644 (file)
 #include "oic_malloc.h"
 #include "logger.h"
 #include "pbkdf2.h"
-#include "global.h"
 #include "base64.h"
 #include "oxmrandompin.h"
 #include "ownershiptransfermanager.h"
 #include "pinoxmcommon.h"
+#include "oxmverifycommon.h"
 
 #define TAG "OIC_OXM_RandomPIN"
 
+typedef enum PinState{
+    PIN_INPUT_READY = 0,
+    PIN_INPUT_WAIT = 1,
+    PIN_INPUT_SUCCESS = 2,
+    PIN_INPUT_FAIL = 3
+} PinState_t;
+
+static PinState_t gPinState = PIN_INPUT_READY;
+
 OCStackResult CreatePinBasedSelectOxmPayload(OTMContext_t* otmCtx, uint8_t **payload, size_t *size)
 {
     if(!otmCtx || !otmCtx->selectedDeviceInfo || !payload || *payload || !size)
@@ -79,13 +88,27 @@ OCStackResult InputPinCodeCallback(OTMContext_t *otmCtx)
     }
 
     uint8_t pinData[OXM_RANDOM_PIN_MAX_SIZE + 1] = {0};
+    OCStackResult res = OC_STACK_ERROR;
+
+    if (PIN_INPUT_WAIT == gPinState)
+    {
+        OIC_LOG(ERROR, TAG, "Pin input callback invoked already");
+        NotifyInputState();
+        SetResult(otmCtx, res);
+        return OC_STACK_NOT_ACCEPTABLE;
+    }
 
-    OCStackResult res = InputPin((char*)pinData, sizeof(pinData));
+    gPinState = PIN_INPUT_WAIT;
+
+    res = InputPin((char*)pinData, sizeof(pinData));
     if (OC_STACK_OK != res)
     {
         OIC_LOG(ERROR, TAG, "Failed to input PIN");
+        gPinState = PIN_INPUT_FAIL;
+        SetResult(otmCtx, res);
         return res;
     }
+    gPinState = PIN_INPUT_SUCCESS;
 
     /**
      * Since PSK will be used directly while PIN based ownership transfer,
@@ -101,7 +124,7 @@ OCStackResult InputPinCodeCallback(OTMContext_t *otmCtx)
             res = OC_STACK_ERROR;
         }
     }
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
     //in case of MOT
     else if(otmCtx->selectedDeviceInfo->doxm->owned &&
             otmCtx->selectedDeviceInfo->doxm->mom &&
@@ -113,7 +136,7 @@ OCStackResult InputPinCodeCallback(OTMContext_t *otmCtx)
             res = OC_STACK_ERROR;
         }
     }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
     //Set the device id to derive temporal PSK
     SetUuidForPinBasedOxm(&(otmCtx->selectedDeviceInfo->doxm->deviceID));
@@ -138,13 +161,13 @@ OCStackResult CreateSecureSessionRandomPinCallback(OTMContext_t* otmCtx)
     }
     OIC_LOG(INFO, TAG, "Anonymous cipher suite disabled.");
 
-    caresult  = CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256, otmCtx->selectedDeviceInfo->endpoint.adapter);
+    caresult  = CASelectCipherSuite(MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, otmCtx->selectedDeviceInfo->endpoint.adapter);
     if (CA_STATUS_OK != caresult)
     {
-        OIC_LOG_V(ERROR, TAG, "Failed to select TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256");
+        OIC_LOG_V(ERROR, TAG, "Failed to select TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256");
         return OC_STACK_ERROR;
     }
-    OIC_LOG(INFO, TAG, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256 cipher suite selected.");
+    OIC_LOG(INFO, TAG, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 cipher suite selected.");
 
     OCProvisionDev_t* selDevInfo = otmCtx->selectedDeviceInfo;
     CAEndpoint_t endpoint;
@@ -155,6 +178,10 @@ OCStackResult CreateSecureSessionRandomPinCallback(OTMContext_t* otmCtx)
         endpoint.port = selDevInfo->securePort;
         caresult = CAInitiateHandshake(&endpoint);
     }
+    else if (CA_ADAPTER_GATT_BTLE == endpoint.adapter)
+    {
+        caresult = CAInitiateHandshake(&endpoint);
+    }
 #ifdef __WITH_TLS__
     else
     {
index bdf08c5..0efb109 100644 (file)
 #include "oic_string.h"
 #include "oic_time.h"
 #include "logger.h"
+#if defined (__TIZENRT__)
+#include <apps/netutils/cJSON.h>
+#else
 #include "cJSON.h"
+#endif
 #include "utlist.h"
 #include "ocpayload.h"
 
@@ -71,17 +75,6 @@ typedef struct _DiscoveryInfo{
 static OCStackResult SecurePortDiscovery(DiscoveryInfo* discoveryInfo,
                                          const OCClientResponse *clientResponse);
 
-/*
- * Function to discover security version information through unicast
- *
- * @param[in] discoveryInfo The pointer of discovery information to matain result of discovery
- * @param[in] clientResponse  Response information(It will contain payload)
- *
- * @return OC_STACK_OK on success otherwise error.
- */
-static OCStackResult SecurityVersionDiscovery(DiscoveryInfo* discoveryInfo,
-                                              const OCClientResponse *clientResponse);
-
 /**
  * Callback handler for PMDeviceDiscovery API.
  *
@@ -94,6 +87,22 @@ static OCStackResult SecurityVersionDiscovery(DiscoveryInfo* discoveryInfo,
 static OCStackApplicationResult DeviceDiscoveryHandler(void *ctx, OCDoHandle UNUSED,
                                 OCClientResponse *clientResponse);
 
+/*
+ * Since security version discovery does not used anymore, disable security version discovery.
+ * Need to discussion to removing all version discovery related codes.
+ */
+#if 0
+/*
+ * Function to discover security version information through unicast
+ *
+ * @param[in] discoveryInfo The pointer of discovery information to matain result of discovery
+ * @param[in] clientResponse  Response information(It will contain payload)
+ *
+ * @return OC_STACK_OK on success otherwise error.
+ */
+static OCStackResult SecurityVersionDiscovery(DiscoveryInfo* discoveryInfo,
+                                              const OCClientResponse *clientResponse);
+
 /**
  * Callback handler for getting secure port information using /oic/res discovery.
  *
@@ -106,7 +115,13 @@ static OCStackApplicationResult DeviceDiscoveryHandler(void *ctx, OCDoHandle UNU
  */
 static OCStackApplicationResult SecurePortDiscoveryHandler(void *ctx, OCDoHandle UNUSED,
                                  OCClientResponse *clientResponse);
+#endif
 
+/*
+ * Since security version discovery does not used anymore, disable security version discovery.
+ * Need to discussion to removing all version discovery related codes.
+ */
+#if 0
 /**
  * Callback handler for security version discovery.
  *
@@ -118,6 +133,7 @@ static OCStackApplicationResult SecurePortDiscoveryHandler(void *ctx, OCDoHandle
  */
 static OCStackApplicationResult SecVersionDiscoveryHandler(void *ctx, OCDoHandle UNUSED,
                                 OCClientResponse *clientResponse);
+#endif
 
 /**
  * Function to search node in linked list that matches given IP and port.
@@ -139,7 +155,7 @@ OCProvisionDev_t* GetDevice(OCProvisionDev_t **ppDevicesList, const char* addr,
     OCProvisionDev_t *ptr = NULL;
     LL_FOREACH(*ppDevicesList, ptr)
     {
-        if( strcmp(ptr->endpoint.addr, addr) == 0 && port == ptr->endpoint.port)
+        if( (ptr && ptr->endpoint.addr) && strncmp(ptr->endpoint.addr, addr, MAX_ADDR_STR_SIZE) == 0 && port == ptr->endpoint.port)
         {
             return ptr;
         }
@@ -179,11 +195,12 @@ OCStackResult AddDevice(OCProvisionDev_t **ppDevicesList, OCDevAddr* endpoint,
 
         ptr->endpoint = *endpoint;
         ptr->doxm = doxm;
-        ptr->securePort = DEFAULT_SECURE_PORT;
+        ptr->securePort = (CT_ADAPTER_GATT_BTLE == connType) ?
+                          endpoint->port : DEFAULT_SECURE_PORT;
         ptr->next = NULL;
         ptr->connType = connType;
         ptr->devStatus = DEV_STATUS_ON; //AddDevice is called when discovery(=alive)
-        OICStrcpy(ptr->secVer, MAX_VERSION_LEN, DEFAULT_SEC_VERSION); // version initialization
+        OICStrcpy(ptr->secVer, OIC_SEC_MAX_VER_LEN, DEFAULT_SEC_VERSION); // version initialization
         ptr->handle = NULL;
 
         LL_PREPEND(*ppDevicesList, ptr);
@@ -246,7 +263,8 @@ static OCStackResult UpdateSecurePortOfDevice(OCProvisionDev_t **ppDevicesList,
         return OC_STACK_ERROR;
     }
 
-    ptr->securePort = securePort;
+    ptr->securePort = (OC_ADAPTER_GATT_BTLE == ptr->endpoint.adapter) ?
+                      ptr->endpoint.port : securePort;
 
 #ifdef __WITH_TLS__
     ptr->tcpPort = tcpPort;
@@ -281,7 +299,7 @@ OCStackResult UpdateSecVersionOfDevice(OCProvisionDev_t **ppDevicesList, const c
         return OC_STACK_ERROR;
     }
 
-    OICStrcpy(ptr->secVer, MAX_VERSION_LEN, secVer);
+    OICStrcpy(ptr->secVer, OIC_SEC_MAX_VER_LEN, secVer);
 
     return OC_STACK_OK;
 }
@@ -346,11 +364,11 @@ OCProvisionDev_t* PMCloneOCProvisionDev(const OCProvisionDev_t* src)
 
     if (0 == strlen(src->secVer))
     {
-        OICStrcpy(newDev->secVer, MAX_VERSION_LEN, DEFAULT_SEC_VERSION);
+        OICStrcpy(newDev->secVer, OIC_SEC_MAX_VER_LEN, DEFAULT_SEC_VERSION);
     }
     else
     {
-        OICStrcpy(newDev->secVer, MAX_VERSION_LEN, src->secVer);
+        OICStrcpy(newDev->secVer, OIC_SEC_MAX_VER_LEN, src->secVer);
     }
 
     newDev->securePort = src->securePort;
@@ -511,8 +529,23 @@ bool PMGenerateQuery(bool isSecure,
             }
 
             break;
-        // TODO: We need to verify tinyDTLS in below cases
         case CT_ADAPTER_GATT_BTLE:
+            snRet = snprintf(buffer, bufferSize, "%s%s%s",
+                             prefix, address, uri);
+            // snprintf return value check
+            if (snRet < 0)
+            {
+                OIC_LOG_V(ERROR, TAG, "PMGenerateQuery : Error (snprintf) %d\n", snRet);
+                return false;
+            }
+            else if ((size_t)snRet >= bufferSize)
+            {
+                OIC_LOG_V(ERROR, TAG, "PMGenerateQuery : Truncated (snprintf) %d\n", snRet);
+                return false;
+            }
+
+            break;
+        // TODO: We need to verify tinyDTLS in below cases
         case CT_ADAPTER_RFCOMM_BTEDR:
             OIC_LOG(ERROR, TAG, "Not supported connectivity adapter.");
             return false;
@@ -525,6 +558,11 @@ bool PMGenerateQuery(bool isSecure,
     return true;
 }
 
+/*
+ * Since security version discovery does not used anymore, disable security version discovery.
+ * Need to discussion to removing all version discovery related codes.
+ */
+#if 0
 static OCStackApplicationResult SecurityVersionDiscoveryHandler(void *ctx, OCDoHandle UNUSED,
                                 OCClientResponse *clientResponse)
 {
@@ -597,6 +635,7 @@ static OCStackApplicationResult SecurityVersionDiscoveryHandler(void *ctx, OCDoH
 
     return  OC_STACK_DELETE_TRANSACTION;
 }
+#endif
 
 static OCStackApplicationResult SecurePortDiscoveryHandler(void *ctx, OCDoHandle UNUSED,
                                  OCClientResponse *clientResponse)
@@ -703,7 +742,6 @@ static OCStackApplicationResult SecurePortDiscoveryHandler(void *ctx, OCDoHandle
                 return OC_STACK_DELETE_TRANSACTION;
             }
 #endif
-
             OIC_LOG(INFO, TAG, "Exiting SecurePortDiscoveryHandler.");
         }
 
@@ -767,7 +805,7 @@ static OCStackApplicationResult DeviceDiscoveryHandler(void *ctx, OCDoHandle UNU
                 // Get my device ID from doxm resource
                 OicUuid_t myId;
                 memset(&myId, 0, sizeof(myId));
-                OCStackResult res = GetDoxmDevOwnerId(&myId);
+                OCStackResult res = GetDoxmDeviceID(&myId);
                 if(OC_STACK_OK != res)
                 {
                     OIC_LOG(ERROR, TAG, "Error while getting my device ID.");
@@ -784,13 +822,6 @@ static OCStackApplicationResult DeviceDiscoveryHandler(void *ctx, OCDoHandle UNU
                     return OC_STACK_KEEP_TRANSACTION;
                 }
 
-                res = GetDoxmDeviceID(&myId);
-                if(OC_STACK_OK != res)
-                {
-                    OIC_LOG(ERROR, TAG, "Error while getting my UUID.");
-                    DeleteDoxmBinData(ptrDoxm);
-                    return OC_STACK_KEEP_TRANSACTION;
-                }
                 //if targetId and discovered deviceID are different, discard it
                 if ((pDInfo->isSingleDiscovery) &&
                     (0 != memcmp(&ptrDoxm->deviceID.id, &pDInfo->targetId->id, sizeof(pDInfo->targetId->id))) )
@@ -799,9 +830,8 @@ static OCStackApplicationResult DeviceDiscoveryHandler(void *ctx, OCDoHandle UNU
                     DeleteDoxmBinData(ptrDoxm);
                     return OC_STACK_KEEP_TRANSACTION;
                 }
-                //if this is owned discovery and this is PT's reply, discard it
-                if (((pDInfo->isSingleDiscovery) || (pDInfo->isOwnedDiscovery)) &&
-                        (0 == memcmp(&ptrDoxm->deviceID.id, &myId.id, sizeof(myId.id))) )
+                //If self reply, discard it
+                if (0 == memcmp(&ptrDoxm->deviceID.id, &myId.id, sizeof(myId.id)))
                 {
                     OIC_LOG(DEBUG, TAG, "discarding provision tool's reply");
                     DeleteDoxmBinData(ptrDoxm);
@@ -816,7 +846,6 @@ static OCStackApplicationResult DeviceDiscoveryHandler(void *ctx, OCDoHandle UNU
                     DeleteDoxmBinData(ptrDoxm);
                     return OC_STACK_KEEP_TRANSACTION;
                 }
-
                 res = SecurePortDiscovery(pDInfo, clientResponse);
                 if(OC_STACK_OK != res)
                 {
@@ -827,7 +856,6 @@ static OCStackApplicationResult DeviceDiscoveryHandler(void *ctx, OCDoHandle UNU
 
                 OIC_LOG(INFO, TAG, "Exiting ProvisionDiscoveryHandler.");
             }
-
             return  OC_STACK_KEEP_TRANSACTION;
         }
     }
@@ -964,12 +992,15 @@ OCStackResult PMSingleDeviceDiscovery(unsigned short waittime, const OicUuid_t*
         OICFree(pDInfo);
         return res;
     }
-    OIC_LOG(DEBUG, TAG, "OUT PMSingleDeviceDiscovery");
+    if (!pDInfo->isFound)
+    {
+        res = OC_STACK_TIMEOUT;
+    }
     OICFree(pDInfo);
+    OIC_LOG(DEBUG, TAG, "OUT PMSingleDeviceDiscovery");
     return res;
 }
 
-
 /**
  * Discover owned/unowned devices in the same IP subnet. .
  *
@@ -1049,7 +1080,113 @@ OCStackResult PMDeviceDiscovery(unsigned short waittime, bool isOwned, OCProvisi
     return res;
 }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+OCStackResult PMSingleDeviceDiscoveryInUnicast(unsigned short waittime, const OicUuid_t* deviceID,
+                                 const char* hostAddress, OCConnectivityType connType,
+                                 OCProvisionDev_t **ppFoundDevice)
+{
+    OIC_LOG(DEBUG, TAG, "IN PMSingleDeviceDiscoveryInUnicast");
+
+    if (NULL != *ppFoundDevice)
+    {
+        OIC_LOG(ERROR, TAG, "List is not null can cause memory leak");
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    if (NULL == deviceID)
+    {
+        OIC_LOG(ERROR, TAG, "Invalid device ID");
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    DiscoveryInfo *pDInfo = (DiscoveryInfo*)OICCalloc(1, sizeof(DiscoveryInfo));
+    if (NULL == pDInfo)
+    {
+        OIC_LOG(ERROR, TAG, "PMSingleDeviceDiscoveryInUnicast : Memory allocation failed.");
+        return OC_STACK_NO_MEMORY;
+    }
+
+    pDInfo->ppDevicesList = ppFoundDevice;
+    pDInfo->pCandidateList = NULL;
+    pDInfo->isOwnedDiscovery = false;
+    pDInfo->isSingleDiscovery = true;
+    pDInfo->isFound = false;
+    pDInfo->targetId = deviceID;
+
+    OCCallbackData cbData;
+    cbData.cb = &DeviceDiscoveryHandler;
+    cbData.context = (void *)pDInfo;
+    cbData.cd = &DeviceDiscoveryDeleteHandler;
+
+    OCStackResult res = OC_STACK_ERROR;
+
+    char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH + 1] = { '\0' };
+    if (hostAddress == NULL)
+    {
+        hostAddress = "";
+    }
+    snprintf(query, MAX_URI_LENGTH + MAX_QUERY_LENGTH + 1, "%s/oic/sec/doxm", hostAddress);
+    connType = connType & CT_MASK_ADAPTER;
+
+    OCDoHandle handle = NULL;
+    res = OCDoResource(&handle, OC_REST_DISCOVER, query, 0, 0,
+            connType, OC_HIGH_QOS, &cbData, NULL, 0);
+
+    if (res != OC_STACK_OK)
+    {
+        OIC_LOG(ERROR, TAG, "OCStack resource error");
+        OICFree(pDInfo);
+        pDInfo = NULL;
+        return res;
+    }
+
+    res = OC_STACK_OK;
+    uint64_t startTime = OICGetCurrentTime(TIME_IN_MS);
+    while (OC_STACK_OK == res && !pDInfo->isFound)
+    {
+        uint64_t currTime = OICGetCurrentTime(TIME_IN_MS);
+
+        long elapsed = (long)((currTime - startTime) / MS_PER_SEC);
+        if (elapsed > waittime)
+        {
+            break;
+        }
+        res = OCProcess();
+    }
+
+    if (OC_STACK_OK != res)
+    {
+        OIC_LOG (ERROR, TAG, "Failed to wait response for secure discovery.");
+        OICFree(pDInfo);
+        pDInfo = NULL;
+        OCStackResult resCancel = OCCancel(handle, OC_HIGH_QOS, NULL, 0);
+        if (OC_STACK_OK !=  resCancel)
+        {
+            OIC_LOG(ERROR, TAG, "Failed to remove registered callback");
+        }
+        return res;
+    }
+
+    res = OCCancel(handle, OC_HIGH_QOS, NULL, 0);
+    if (OC_STACK_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "Failed to remove registered callback");
+        OICFree(pDInfo);
+        pDInfo = NULL;
+        return res;
+    }
+    OIC_LOG(DEBUG, TAG, "OUT PMSingleDeviceDiscoveryInUnicast");
+
+    if (!pDInfo->isFound)
+    {
+        res = OC_STACK_TIMEOUT;
+    }
+
+    OICFree(pDInfo);
+    pDInfo = NULL;
+    return res;
+}
+
+#ifdef MULTIPLE_OWNER
 static OCStackApplicationResult MOTDeviceDiscoveryHandler(void *ctx, OCDoHandle UNUSED,
                                 OCClientResponse *clientResponse)
 {
@@ -1224,8 +1361,15 @@ OCStackResult PMMultipleOwnerDeviceDiscovery(unsigned short waittime, bool isMul
         return OC_STACK_INVALID_PARAM;
     }
 
-    const char *DOXM_MOM_ENABLE_MULTICAST_QUERY = "/oic/sec/doxm?mom!=0&owned=TRUE";
-    const char *DOXM_MULTIPLE_OWNED_MULTICAST_QUERY = "/oic/sec/doxm?owned=TRUE";
+    char DOXM_MOM_ENABLE_MULTICAST_QUERY[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
+    char DOXM_MULTIPLE_OWNED_MULTICAST_QUERY[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
+    snprintf(DOXM_MOM_ENABLE_MULTICAST_QUERY, sizeof(DOXM_MOM_ENABLE_MULTICAST_QUERY),
+             "%s?%s=%d&%s=TRUE",
+             OIC_RSRC_DOXM_URI, OIC_JSON_MOM_NAME, OIC_MULTIPLE_OWNER_DISABLE,
+             OIC_JSON_OWNED_NAME);
+    snprintf(DOXM_MULTIPLE_OWNED_MULTICAST_QUERY, sizeof(DOXM_MOM_ENABLE_MULTICAST_QUERY),
+             "%s?%s=TRUE",
+             OIC_RSRC_DOXM_URI, OIC_JSON_OWNED_NAME);
 
     DiscoveryInfo *pDInfo = OICCalloc(1, sizeof(DiscoveryInfo));
     if(NULL == pDInfo)
@@ -1282,7 +1426,7 @@ OCStackResult PMMultipleOwnerDeviceDiscovery(unsigned short waittime, bool isMul
     return res;
 }
 
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
 static OCStackResult SecurePortDiscovery(DiscoveryInfo* discoveryInfo,
                                          const OCClientResponse *clientResponse)
@@ -1343,6 +1487,11 @@ static OCStackResult SecurePortDiscovery(DiscoveryInfo* discoveryInfo,
     return ret;
 }
 
+/*
+ * Since security version discovery does not used anymore, disable security version discovery.
+ * Need to discussion to removing all version discovery related codes.
+ */
+#if 0
 static OCStackResult SecurityVersionDiscovery(DiscoveryInfo* discoveryInfo,
                                               const OCClientResponse *clientResponse)
 {
@@ -1385,6 +1534,7 @@ static OCStackResult SecurityVersionDiscovery(DiscoveryInfo* discoveryInfo,
 
     return ret;
 }
+#endif
 
 /**
  * Function to print OCProvisionDev_t for debug purpose.
index 68c8ece..359b510 100644 (file)
@@ -66,6 +66,7 @@
 #define PDM_SQLITE_DELETE_LINK "DELETE FROM T_DEVICE_LINK_STATE WHERE ID = ? and ID2 = ?"
 #define PDM_SQLITE_DELETE_DEVICE_LINK "DELETE FROM T_DEVICE_LINK_STATE WHERE ID = ? or ID2 = ?"
 #define PDM_SQLITE_DELETE_DEVICE "DELETE FROM T_DEVICE_LIST  WHERE ID = ?"
+#define PDM_SQLITE_DELETE_DEVICE_WITH_STATE "DELETE FROM T_DEVICE_LIST  WHERE STATE= ?"
 #define PDM_SQLITE_UPDATE_LINK "UPDATE T_DEVICE_LINK_STATE SET STATE = ?  WHERE ID = ? and ID2 = ?"
 #define PDM_SQLITE_LIST_ALL_UUID "SELECT UUID FROM T_DEVICE_LIST WHERE STATE = 0"
 #define PDM_SQLITE_GET_UUID "SELECT UUID,STATE FROM T_DEVICE_LIST WHERE ID = ?"
@@ -93,6 +94,7 @@ static bool gInit = false;  /* Only if we can open sqlite db successfully, gInit
  */
 static OCStackResult createDB(const char* path)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
 
     int result = 0;
     result = sqlite3_open_v2(path, &g_db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, NULL);
@@ -107,6 +109,9 @@ static OCStackResult createDB(const char* path)
 
     OIC_LOG(INFO, TAG, "Created T_DEVICE_LINK_STATE");
     gInit = true;
+
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+
     return OC_STACK_OK;
 }
 
@@ -152,11 +157,13 @@ void errLogCallback(void *pArg, int iErrCode, const char *zMsg)
     (void) pArg;
     (void) iErrCode;
     (void) zMsg;
-    OIC_LOG_V(DEBUG,TAG, "(%d) %s", iErrCode, zMsg);
+    OIC_LOG_V(DEBUG,TAG, "%s : (%d) %s", __func__, iErrCode, zMsg);
 }
 
 OCStackResult PDMInit(const char *path)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     int rc;
     const char *dbPath = NULL;
     if (SQLITE_OK !=  sqlite3_config(SQLITE_CONFIG_LOG, errLogCallback, NULL))
@@ -176,15 +183,37 @@ OCStackResult PDMInit(const char *path)
     if (SQLITE_OK != rc)
     {
         OIC_LOG_V(INFO, TAG, "ERROR: Can't open database: %s", sqlite3_errmsg(g_db));
-        return createDB(dbPath);
+        sqlite3_close(g_db);
+        OCStackResult ret = createDB(dbPath);
+        if (OC_STACK_OK != ret)
+        {
+            sqlite3_close(g_db);
+        }
+        return ret;
     }
     gInit = true;
+
+    /*
+     * Remove PDM_DEVICE_INIT status devices.
+     * PDM_DEVICE_INIT means that the OTM process is in progress.
+     * PDM_DEVICE_INIT state device can be existed when the program is terminated during the OTM process in progress.
+     * For this reason, PDM_DEVICE_INIT devices should be removed at PDM initialization time.
+     */
+    if(OC_STACK_OK != PDMDeleteDeviceWithState(PDM_DEVICE_INIT))
+    {
+        OIC_LOG_V(WARNING, TAG, "Failed to delete init state devices.");
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+
     return OC_STACK_OK;
 }
 
 
 OCStackResult PDMAddDevice(const OicUuid_t *UUID)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     CHECK_PDM_INIT(TAG);
     if (NULL == UUID)
     {
@@ -218,6 +247,8 @@ OCStackResult PDMAddDevice(const OicUuid_t *UUID)
         return OC_STACK_ERROR;
     }
     sqlite3_finalize(stmt);
+
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
@@ -226,6 +257,8 @@ OCStackResult PDMAddDevice(const OicUuid_t *UUID)
  */
 static OCStackResult getIdForUUID(const OicUuid_t *UUID , int *id)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     sqlite3_stmt *stmt = 0;
     int res = 0;
     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_ID, strlen(PDM_SQLITE_GET_ID) + 1, &stmt, NULL);
@@ -241,6 +274,7 @@ static OCStackResult getIdForUUID(const OicUuid_t *UUID , int *id)
         OIC_LOG_V(DEBUG, TAG, "ID is %d", tempId);
         *id = tempId;
         sqlite3_finalize(stmt);
+        OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
         return OC_STACK_OK;
     }
     sqlite3_finalize(stmt);
@@ -252,6 +286,7 @@ static OCStackResult getIdForUUID(const OicUuid_t *UUID , int *id)
  */
 OCStackResult PDMIsDuplicateDevice(const OicUuid_t* UUID, bool *result)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
 
     CHECK_PDM_INIT(TAG);
     if (NULL == UUID || NULL == result)
@@ -277,6 +312,8 @@ OCStackResult PDMIsDuplicateDevice(const OicUuid_t* UUID, bool *result)
 
     sqlite3_finalize(stmt);
     *result = retValue;
+
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
@@ -285,6 +322,8 @@ OCStackResult PDMIsDuplicateDevice(const OicUuid_t* UUID, bool *result)
  */
 static OCStackResult addlink(int id1, int id2)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     sqlite3_stmt *stmt = 0;
     int res = 0;
     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_INSERT_LINK_DATA,
@@ -307,11 +346,14 @@ static OCStackResult addlink(int id1, int id2)
         return OC_STACK_ERROR;
     }
     sqlite3_finalize(stmt);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
 OCStackResult PDMLinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     CHECK_PDM_INIT(TAG);
     if (NULL == UUID1 || NULL == UUID2)
     {
@@ -357,6 +399,7 @@ OCStackResult PDMLinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
     }
 
     ASCENDING_ORDER(id1, id2);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return addlink(id1, id2);
 }
 
@@ -365,6 +408,8 @@ OCStackResult PDMLinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
  */
 static OCStackResult removeLink(int id1, int id2)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     int res = 0;
     sqlite3_stmt *stmt = 0;
     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_DELETE_LINK, strlen(PDM_SQLITE_DELETE_LINK) + 1, &stmt, NULL);
@@ -383,11 +428,14 @@ static OCStackResult removeLink(int id1, int id2)
         return OC_STACK_ERROR;
     }
     sqlite3_finalize(stmt);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
 OCStackResult PDMUnlinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     CHECK_PDM_INIT(TAG);
     if (NULL == UUID1 || NULL == UUID2)
     {
@@ -409,11 +457,14 @@ OCStackResult PDMUnlinkDevices(const OicUuid_t *UUID1, const OicUuid_t *UUID2)
         return OC_STACK_INVALID_PARAM;
     }
     ASCENDING_ORDER(id1, id2);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return removeLink(id1, id2);
 }
 
 static OCStackResult removeFromDeviceList(int id)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     sqlite3_stmt *stmt = 0;
     int res = 0;
     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_DELETE_DEVICE,
@@ -430,11 +481,14 @@ static OCStackResult removeFromDeviceList(int id)
         return OC_STACK_ERROR;
     }
     sqlite3_finalize(stmt);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
 OCStackResult PDMDeleteDevice(const OicUuid_t *UUID)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     CHECK_PDM_INIT(TAG);
     if (NULL == UUID)
     {
@@ -454,12 +508,15 @@ OCStackResult PDMDeleteDevice(const OicUuid_t *UUID)
         return OC_STACK_ERROR;
     }
     commit();
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
 
 static OCStackResult updateLinkState(int id1, int id2, int state)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     sqlite3_stmt *stmt = 0;
     int res = 0 ;
     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_UPDATE_LINK,
@@ -482,11 +539,14 @@ static OCStackResult updateLinkState(int id1, int id2, int state)
         return OC_STACK_ERROR;
     }
     sqlite3_finalize(stmt);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
 OCStackResult PDMSetLinkStale(const OicUuid_t* uuidOfDevice1, const OicUuid_t* uuidOfDevice2)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     CHECK_PDM_INIT(TAG);
     if (NULL == uuidOfDevice1 || NULL == uuidOfDevice2)
     {
@@ -508,11 +568,14 @@ OCStackResult PDMSetLinkStale(const OicUuid_t* uuidOfDevice1, const OicUuid_t* u
         return OC_STACK_INVALID_PARAM;
     }
     ASCENDING_ORDER(id1, id2);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return updateLinkState(id1, id2, PDM_DEVICE_STALE);
 }
 
 OCStackResult PDMGetOwnedDevices(OCUuidList_t **uuidList, size_t *numOfDevices)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     CHECK_PDM_INIT(TAG);
     if (NULL != *uuidList)
     {
@@ -543,11 +606,14 @@ OCStackResult PDMGetOwnedDevices(OCUuidList_t **uuidList, size_t *numOfDevices)
     }
     *numOfDevices = counter;
     sqlite3_finalize(stmt);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
 static OCStackResult getUUIDforId(int id, OicUuid_t *uid, bool *result)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     sqlite3_stmt *stmt = 0;
     int res = 0;
     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_GET_UUID,
@@ -581,11 +647,14 @@ static OCStackResult getUUIDforId(int id, OicUuid_t *uid, bool *result)
         return OC_STACK_OK;
     }
     sqlite3_finalize(stmt);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_INVALID_PARAM;
 }
 
 OCStackResult PDMGetLinkedDevices(const OicUuid_t *UUID, OCUuidList_t **UUIDLIST, size_t *numOfDevices)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     CHECK_PDM_INIT(TAG);
     if (NULL == UUID || NULL == numOfDevices || !UUIDLIST)
     {
@@ -657,11 +726,14 @@ OCStackResult PDMGetLinkedDevices(const OicUuid_t *UUID, OCUuidList_t **UUIDLIST
     }
     *numOfDevices = counter;
      sqlite3_finalize(stmt);
+     OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
      return OC_STACK_OK;
 }
 
 OCStackResult PDMGetToBeUnlinkedDevices(OCPairList_t **staleDevList, size_t *numOfDevices)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     CHECK_PDM_INIT(TAG);
     if (NULL != *staleDevList)
     {
@@ -702,20 +774,26 @@ OCStackResult PDMGetToBeUnlinkedDevices(OCPairList_t **staleDevList, size_t *num
     }
     *numOfDevices = counter;
     sqlite3_finalize(stmt);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
 OCStackResult PDMClose()
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     CHECK_PDM_INIT(TAG);
     int res = 0;
     res = sqlite3_close(g_db);
     PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
 void PDMDestoryOicUuidLinkList(OCUuidList_t* ptr)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     if(ptr)
     {
         OCUuidList_t *tmp1 = NULL,*tmp2=NULL;
@@ -725,10 +803,14 @@ void PDMDestoryOicUuidLinkList(OCUuidList_t* ptr)
             OICFree(tmp1);
         }
     }
+
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
 }
 
 void PDMDestoryStaleLinkList(OCPairList_t* ptr)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     if(ptr)
     {
         OCPairList_t *tmp1 = NULL,*tmp2=NULL;
@@ -738,11 +820,15 @@ void PDMDestoryStaleLinkList(OCPairList_t* ptr)
             OICFree(tmp1);
         }
     }
+
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
 }
 
 OCStackResult PDMIsLinkExists(const OicUuid_t* uuidOfDevice1, const OicUuid_t* uuidOfDevice2,
                                bool* result)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     CHECK_PDM_INIT(TAG);
     if (NULL == uuidOfDevice1 || NULL == uuidOfDevice2 || NULL == result)
     {
@@ -808,11 +894,14 @@ OCStackResult PDMIsLinkExists(const OicUuid_t* uuidOfDevice1, const OicUuid_t* u
     }
     sqlite3_finalize(stmt);
     *result = ret;
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
 static OCStackResult updateDeviceState(const OicUuid_t *uuid, PdmDeviceState_t state)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     sqlite3_stmt *stmt = 0;
     int res = 0 ;
     res = sqlite3_prepare_v2(g_db, PDM_SQLITE_UPDATE_DEVICE,
@@ -832,11 +921,14 @@ static OCStackResult updateDeviceState(const OicUuid_t *uuid, PdmDeviceState_t s
         return OC_STACK_ERROR;
     }
     sqlite3_finalize(stmt);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
 static OCStackResult updateLinkForStaleDevice(const OicUuid_t *devUuid)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     sqlite3_stmt *stmt = 0;
     int res = 0 ;
 
@@ -865,11 +957,14 @@ static OCStackResult updateLinkForStaleDevice(const OicUuid_t *devUuid)
         return OC_STACK_ERROR;
     }
     sqlite3_finalize(stmt);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
 OCStackResult PDMSetDeviceState(const OicUuid_t* uuid, PdmDeviceState_t state)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     OCStackResult res = OC_STACK_ERROR;
 
     CHECK_PDM_INIT(TAG);
@@ -899,11 +994,14 @@ OCStackResult PDMSetDeviceState(const OicUuid_t* uuid, PdmDeviceState_t state)
         return res;
     }
     commit();
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
 OCStackResult PDMGetDeviceState(const OicUuid_t *uuid, PdmDeviceState_t* result)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
     if (NULL == uuid || NULL == result)
     {
         OIC_LOG(ERROR, TAG, "UUID or result is NULL");
@@ -927,6 +1025,37 @@ OCStackResult PDMGetDeviceState(const OicUuid_t *uuid, PdmDeviceState_t* result)
         *result = (PdmDeviceState_t)tempStaleStateFromDb;
     }
     sqlite3_finalize(stmt);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
     return OC_STACK_OK;
 }
 
+OCStackResult PDMDeleteDeviceWithState(const PdmDeviceState_t state)
+{
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
+    CHECK_PDM_INIT(TAG);
+    if (PDM_DEVICE_ACTIVE != state && PDM_DEVICE_STALE != state &&
+        PDM_DEVICE_INIT != state && PDM_DEVICE_UNKNOWN != state)
+    {
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    sqlite3_stmt *stmt = 0;
+    int res =0;
+    res = sqlite3_prepare_v2(g_db, PDM_SQLITE_DELETE_DEVICE_WITH_STATE,
+                              strlen(PDM_SQLITE_DELETE_DEVICE_WITH_STATE) + 1, &stmt, NULL);
+    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+
+    res = sqlite3_bind_int(stmt, PDM_BIND_INDEX_FIRST, state);
+    PDM_VERIFY_SQLITE_OK(TAG, res, ERROR, OC_STACK_ERROR);
+
+    if (SQLITE_DONE != sqlite3_step(stmt))
+    {
+        OIC_LOG_V(ERROR, TAG, "Error message: %s", sqlite3_errmsg(g_db));
+        sqlite3_finalize(stmt);
+        return OC_STACK_ERROR;
+    }
+    sqlite3_finalize(stmt);
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+    return OC_STACK_OK;
+}
index 930bdf7..a5e1382 100644 (file)
 #include "pconfresource.h"
 #include "credentialgenerator.h"
 #include "cainterface.h"
+#if defined (__TIZENRT__)
+#include <apps/netutils/cJSON.h>
+#else
 #include "cJSON.h"
+#endif
 #include "pmtypes.h"
 #include "pmutility.h"
+#include "srmutility.h"
 #include "provisioningdatabasemanager.h"
 #include "base64.h"
 #include "utlist.h"
 #include "ocpayload.h"
-#include "srmutility.h"
 
 #ifdef __WITH_DTLS__
 #include "crlresource.h"
 
 /**
  * Macro to verify argument is not equal to NULL.
- * eg: VERIFY_NON_NULL(TAG, ptrData, ERROR,OC_STACK_ERROR);
+ * eg: VERIFY_NON_NULL_RET(TAG, ptrData, ERROR,OC_STACK_ERROR);
  */
-#define VERIFY_NON_NULL(tag, arg, logLevel, retValue) { if (NULL == (arg)) \
+#define VERIFY_NON_NULL_RET(tag, arg, logLevel, retValue) { if (NULL == (arg)) \
             { OIC_LOG((logLevel), tag, #arg " is NULL"); return retValue; } }
 
 /**
  * Macro to verify success of operation.
- * eg: VERIFY_SUCCESS(TAG, OC_STACK_OK == foo(), ERROR, OC_STACK_ERROR);
+ * eg: VERIFY_SUCCESS_RET(TAG, OC_STACK_OK == foo(), ERROR, OC_STACK_ERROR);
  */
-#define VERIFY_SUCCESS(tag, op, logLevel, retValue) { if (!(op)) \
+#define VERIFY_SUCCESS_RET(tag, op, logLevel, retValue) { if (!(op)) \
             {OIC_LOG((logLevel), tag, #op " failed!!"); return retValue;} }
 
 
@@ -198,7 +202,7 @@ static void registerResultForCredProvisioning(CredentialData_t *credData,
 static OCStackApplicationResult provisionCredentialCB2(void *ctx, OCDoHandle UNUSED,
                                                        OCClientResponse *clientResponse)
 {
-    VERIFY_NON_NULL(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
+    VERIFY_NON_NULL_RET(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
     CredentialData_t *credData = (CredentialData_t *) ctx;
     (void)UNUSED;
 
@@ -249,7 +253,7 @@ static OCStackApplicationResult provisionCredentialCB2(void *ctx, OCDoHandle UNU
 static OCStackApplicationResult provisionCredentialCB1(void *ctx, OCDoHandle UNUSED,
                                                        OCClientResponse *clientResponse)
 {
-    VERIFY_NON_NULL(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
+    VERIFY_NON_NULL_RET(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
     (void)UNUSED;
     CredentialData_t* credData = (CredentialData_t*) ctx;
     OICFree(credData->credInfoFirst);
@@ -395,69 +399,6 @@ static void registerResultForCertProvisioning(CertData_t *certData,
    ++(certData->numOfResults);
 }
 
-/**
- * Internal function for handling credential generation and sending cretificate credential.
- *
- * @param[in] cred Instance of cred resource.
- * @param[in] deviceInfo information about device to which credential is to be provisioned.
- * @param[in] responseHandler callbak called by OC stack when request API receives response.
- * @return  OC_STACK_OK in case of success and other value otherwise.
- */
-static OCStackResult provisionCertCred(const OicSecCred_t *cred,
-        const OCProvisionDev_t *deviceInfo, CertData_t *certData,
-        OCClientResponseHandler responseHandler)
-{
-    OCSecurityPayload* secPayload = (OCSecurityPayload*)OICCalloc(1, sizeof(OCSecurityPayload));
-    if(!secPayload)
-    {
-        OIC_LOG(ERROR, TAG, "Failed to memory allocation");
-        return OC_STACK_NO_MEMORY;
-    }
-    secPayload->base.type = PAYLOAD_TYPE_SECURITY;
-    int secureFlag = 0;
-    OCStackResult res = CredToCBORPayload(cred, &secPayload->securityData,
-        &secPayload->payloadSize, secureFlag);
-
-    if ((OC_STACK_OK != res) || (NULL == secPayload->securityData))
-    {
-        OICFree(secPayload);
-        OIC_LOG(ERROR, TAG, "Failed to CredToCBORPayload");
-        return OC_STACK_NO_MEMORY;
-    }
-
-    OIC_LOG(DEBUG, TAG, "Created payload for Cred:");
-    OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
-    char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
-    if(!PMGenerateQuery(true,
-                        deviceInfo->endpoint.addr,
-                        deviceInfo->securePort,
-                        deviceInfo->connType,
-                        query, sizeof(query), OIC_RSRC_CRED_URI))
-    {
-        OIC_LOG(ERROR, TAG, "DeviceDiscoveryHandler : Failed to generate query");
-        OCPayloadDestroy((OCPayload *)secPayload);
-        return OC_STACK_ERROR;
-    }
-    OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
-
-    OCCallbackData cbData = {.context=NULL, .cb=NULL, .cd=NULL};
-    cbData.cb = responseHandler;
-    cbData.context = (void *) certData;
-    cbData.cd = NULL;
-
-    OCDoHandle handle = NULL;
-    OCMethod method = OC_REST_POST;
-    OCStackResult ret = OCDoResource(&handle, method, query, 0, (OCPayload*)secPayload,
-            deviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
-    OIC_LOG_V(INFO, TAG, "OCDoResource::Certificate provisioning returned : %d",ret);
-    if (ret != OC_STACK_OK)
-    {
-        OIC_LOG(ERROR, TAG, "OCStack resource error");
-    }
-
-    return ret;
-}
-
 OCStackResult SRPRegisterTrustCertChainNotifier(void *ctx, TrustCertChainChangeCB callback)
 {
     if (g_trustCertChainNotifier.callback)
@@ -490,12 +431,12 @@ void SRPRemoveTrustCertChainNotifier()
 static OCStackApplicationResult provisionCertCB(void *ctx, OCDoHandle UNUSED,
                                                        OCClientResponse *clientResponse)
 {
-    VERIFY_NON_NULL(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
+    VERIFY_NON_NULL_RET(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
     CertData_t *certData = (CertData_t *) ctx;
     (void)UNUSED;
 
     OCProvisionResultCB resultCallback = certData->resultCallback;
-    OIC_LOG(INFO, TAG, "provisionCertCred called");
+    OIC_LOG(INFO, TAG, "provisionCertCB called");
     if (clientResponse)
     {
         if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
@@ -524,9 +465,9 @@ OCStackResult SRPProvisionTrustCertChain(void *ctx, OicSecCredType_t type, uint1
         const OCProvisionDev_t *selectedDeviceInfo, OCProvisionResultCB resultCallback)
 {
     OIC_LOG(INFO, TAG, "In SRPProvisionTrustCertChain");
-    VERIFY_NON_NULL(TAG, selectedDeviceInfo, ERROR,  OC_STACK_INVALID_PARAM);
-    VERIFY_NON_NULL(TAG, resultCallback, ERROR,  OC_STACK_INVALID_CALLBACK);
-    if (SIGNED_ASYMMETRIC_KEY != type || NULL == type)
+    VERIFY_NON_NULL_RET(TAG, selectedDeviceInfo, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL_RET(TAG, resultCallback, ERROR,  OC_STACK_INVALID_CALLBACK);
+    if (SIGNED_ASYMMETRIC_KEY != type)
     {
         OIC_LOG(INFO, TAG, "Invalid key type");
         return OC_STACK_INVALID_PARAM;
@@ -610,7 +551,7 @@ OCStackResult SRPProvisionTrustCertChain(void *ctx, OicSecCredType_t type, uint1
         OICFree(certData);
     }
 
-    VERIFY_SUCCESS(TAG, (OC_STACK_OK == ret), ERROR, OC_STACK_ERROR);
+    VERIFY_SUCCESS_RET(TAG, (OC_STACK_OK == ret), ERROR, OC_STACK_ERROR);
     return OC_STACK_OK;
 }
 
@@ -618,36 +559,52 @@ OCStackResult SRPSaveTrustCertChain(uint8_t *trustCertChain, size_t chainSize,
                                             OicEncodingType_t encodingType, uint16_t *credId)
 {
     OIC_LOG(DEBUG, TAG, "IN SRPSaveTrustCertChain");
-    VERIFY_NON_NULL(TAG, trustCertChain, ERROR,  OC_STACK_INVALID_PARAM);
-    VERIFY_NON_NULL(TAG, credId, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL_RET(TAG, trustCertChain, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL_RET(TAG, credId, ERROR,  OC_STACK_INVALID_PARAM);
+
+    // It is temporary condition.
+    // 6144(6K) = 6 * 1024, generally, one Cert is less than 2k.
+    // because we use 3 Cert, 6K is enough size for saving Certs.
+    if (6144 <= chainSize)
+    {
+        OIC_LOG_V(ERROR, TAG, "chainSize(%d) is invalid", chainSize);
+        return OC_STACK_INVALID_PARAM;
+    }
 
     OCStackResult res = OC_STACK_ERROR;
 
     OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(*cred));
-    VERIFY_NON_NULL(TAG, cred, ERROR, OC_STACK_NO_MEMORY);
+    VERIFY_NON_NULL_RET(TAG, cred, ERROR, OC_STACK_NO_MEMORY);
 
-    memcpy(cred->subject.id, &WILDCARD_SUBJECT_ID, WILDCARD_SUBJECT_ID_LEN);
+    res = GetDoxmDeviceID(&cred->subject);
+    if (OC_STACK_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "Cann't get the device id(GetDoxmDeviceID)");
+        DeleteCredList(cred);
+        return res;
+    }
 
     cred->credUsage= (char *)OICCalloc(1, strlen(TRUST_CA)+1 );
-    VERIFY_NON_NULL(TAG, cred->credUsage, ERROR, OC_STACK_NO_MEMORY);
-    OICStrcpy(cred->credUsage, strlen(TRUST_CA) + 1, TRUST_CA) ;
+    VERIFY_NON_NULL_RET(TAG, cred->credUsage, ERROR, OC_STACK_NO_MEMORY);
+    OICStrcpy(cred->credUsage, strlen(TRUST_CA) + 1, TRUST_CA);
 
     cred->credType = SIGNED_ASYMMETRIC_KEY;
 
     if (encodingType == OIC_ENCODING_PEM)
     {
         cred->optionalData.data = (uint8_t *)OICCalloc(1, chainSize + 1);
-        VERIFY_NON_NULL(TAG, cred->optionalData.data, ERROR, OC_STACK_NO_MEMORY);
+        VERIFY_NON_NULL_RET(TAG, cred->optionalData.data, ERROR, OC_STACK_NO_MEMORY);
         cred->optionalData.len = chainSize + 1;
     }
     else
     {
         cred->optionalData.data = (uint8_t *)OICCalloc(1, chainSize);
-        VERIFY_NON_NULL(TAG, cred->optionalData.data, ERROR, OC_STACK_NO_MEMORY);
+        VERIFY_NON_NULL_RET(TAG, cred->optionalData.data, ERROR, OC_STACK_NO_MEMORY);
         cred->optionalData.len = chainSize;
     }
     memcpy(cred->optionalData.data, trustCertChain, chainSize);
     cred->optionalData.encoding = encodingType;
+    cred->optionalData.revstat = false;
 
     res = AddCredential(cred);
     if(res != OC_STACK_OK)
@@ -660,9 +617,9 @@ OCStackResult SRPSaveTrustCertChain(uint8_t *trustCertChain, size_t chainSize,
     if (g_trustCertChainNotifier.callback)
     {
         uint8_t *certChain = (uint8_t*)OICCalloc(1, sizeof(uint8_t) * chainSize);
-        VERIFY_NON_NULL(TAG, certChain, ERROR, OC_STACK_NO_MEMORY);
+        VERIFY_NON_NULL_RET(TAG, certChain, ERROR, OC_STACK_NO_MEMORY);
         memcpy(certChain, trustCertChain, chainSize);
-        g_trustCertChainNotifier.callback(g_trustCertChainNotifier.context, credId,
+        g_trustCertChainNotifier.callback(g_trustCertChainNotifier.context, *credId,
                 certChain, chainSize);
         OICFree(certChain);
     }
@@ -673,42 +630,46 @@ OCStackResult SRPSaveTrustCertChain(uint8_t *trustCertChain, size_t chainSize,
 }
 
 
-OCStackResult SRPSaveOwnCertChain(OicSecCert_t * cert, OicSecKey_t * key, uint16_t *credId)
+OCStackResult SRPSaveOwnCertChain(OicSecKey_t * cert, OicSecKey_t * key, uint16_t *credId)
 {
     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
-    VERIFY_NON_NULL(TAG, cert, ERROR,  OC_STACK_INVALID_PARAM);
-    VERIFY_NON_NULL(TAG, cert->data, ERROR,  OC_STACK_INVALID_PARAM);
-    VERIFY_NON_NULL(TAG, key, ERROR,  OC_STACK_INVALID_PARAM);
-    VERIFY_NON_NULL(TAG, key->data, ERROR,  OC_STACK_INVALID_PARAM);
-    VERIFY_NON_NULL(TAG, credId, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL_RET(TAG, cert, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL_RET(TAG, cert->data, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL_RET(TAG, key, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL_RET(TAG, key->data, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL_RET(TAG, credId, ERROR,  OC_STACK_INVALID_PARAM);
 
     OCStackResult res = OC_STACK_ERROR;
 
     OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(*cred));
-    VERIFY_NON_NULL(TAG, cred, ERROR, OC_STACK_NO_MEMORY);
+    VERIFY_NON_NULL_RET(TAG, cred, ERROR, OC_STACK_NO_MEMORY);
 
     OIC_LOG_V(DEBUG, TAG, "IN: %s", __func__);
 
-    if (OC_STACK_OK != GetDoxmDeviceID(&cred->subject))
+    res = GetDoxmDeviceID(&cred->subject);
+    if (OC_STACK_OK != res)
     {
         OIC_LOG(ERROR, TAG, "Cann't get the device id(GetDoxmDeviceID)");
+        DeleteCredList(cred);
+        return res;
     }
 
     cred->credUsage= (char *)OICCalloc(1, strlen(PRIMARY_CERT)+1 );
-    VERIFY_NON_NULL(TAG, cred->credUsage, ERROR, OC_STACK_NO_MEMORY);
+    VERIFY_NON_NULL_RET(TAG, cred->credUsage, ERROR, OC_STACK_NO_MEMORY);
     OICStrcpy(cred->credUsage, strlen(PRIMARY_CERT) + 1, PRIMARY_CERT) ;
 
     cred->credType = SIGNED_ASYMMETRIC_KEY;
 
-    OicSecCert_t *publicData = &cred->publicData;
+    OicSecKey_t *publicData = &cred->publicData;
     publicData->data = (uint8_t *)OICCalloc(1, cert->len);
-    VERIFY_NON_NULL(TAG, publicData->data, ERROR, OC_STACK_NO_MEMORY);
+    VERIFY_NON_NULL_RET(TAG, publicData->data, ERROR, OC_STACK_NO_MEMORY);
     memcpy(publicData->data, cert->data, cert->len);
     publicData->len = cert->len;
+    publicData->encoding = cert->encoding;
 
     OicSecKey_t *privateData = &cred->privateData;
     privateData->data = (uint8_t *)OICCalloc(1, key->len);
-    VERIFY_NON_NULL(TAG, privateData->data, ERROR, OC_STACK_NO_MEMORY);
+    VERIFY_NON_NULL_RET(TAG, privateData->data, ERROR, OC_STACK_NO_MEMORY);
     memcpy(privateData->data, key->data, key->len);
     privateData->len = key->len;
     privateData->encoding = key->encoding;
@@ -732,10 +693,10 @@ OCStackResult SRPProvisionCredentials(void *ctx, OicSecCredType_t type, size_t k
                                       const OCProvisionDev_t *pDev2,
                                       OCProvisionResultCB resultCallback)
 {
-    VERIFY_NON_NULL(TAG, pDev1, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL_RET(TAG, pDev1, ERROR,  OC_STACK_INVALID_PARAM);
     if (SYMMETRIC_PAIR_WISE_KEY == type)
     {
-        VERIFY_NON_NULL(TAG, pDev2, ERROR,  OC_STACK_INVALID_PARAM);
+        VERIFY_NON_NULL_RET(TAG, pDev2, ERROR,  OC_STACK_INVALID_PARAM);
     }
     if (!resultCallback)
     {
@@ -794,7 +755,7 @@ OCStackResult SRPProvisionCredentials(void *ctx, OicSecCredType_t type, size_t k
             OCStackResult res = PMGeneratePairWiseCredentials(type, keySize, &provTooldeviceID,
                     &firstDevice->doxm->deviceID, &secondDevice->doxm->deviceID,
                     &firstCred, &secondCred);
-            VERIFY_SUCCESS(TAG, (res==OC_STACK_OK), ERROR, OC_STACK_ERROR);
+            VERIFY_SUCCESS_RET(TAG, (res==OC_STACK_OK), ERROR, OC_STACK_ERROR);
             OIC_LOG(INFO, TAG, "Credentials generated successfully");
             CredentialData_t *credData =
                 (CredentialData_t *) OICCalloc(1, sizeof(CredentialData_t));
@@ -834,7 +795,7 @@ OCStackResult SRPProvisionCredentials(void *ctx, OicSecCredType_t type, size_t k
                 OICFree(credData);
             }
             OIC_LOG_V(INFO, TAG, "provisionCredentials returned: %d",res);
-            VERIFY_SUCCESS(TAG, (res==OC_STACK_OK), ERROR, OC_STACK_ERROR);
+            VERIFY_SUCCESS_RET(TAG, (res==OC_STACK_OK), ERROR, OC_STACK_ERROR);
             return res;
         }
         default:
@@ -874,7 +835,7 @@ static OCStackApplicationResult SRPProvisionACLCB(void *ctx, OCDoHandle UNUSED,
 {
     OIC_LOG_V(INFO, TAG, "Inside SRPProvisionACLCB.");
     (void)UNUSED;
-    VERIFY_NON_NULL(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
+    VERIFY_NON_NULL_RET(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
     ACLData_t *aclData = (ACLData_t*)ctx;
     OCProvisionResultCB resultCallback = aclData->resultCallback;
 
@@ -904,9 +865,9 @@ static OCStackApplicationResult SRPProvisionACLCB(void *ctx, OCDoHandle UNUSED,
 OCStackResult SRPProvisionACL(void *ctx, const OCProvisionDev_t *selectedDeviceInfo,
         OicSecAcl_t *acl, OCProvisionResultCB resultCallback)
 {
-    VERIFY_NON_NULL(TAG, selectedDeviceInfo, ERROR,  OC_STACK_INVALID_PARAM);
-    VERIFY_NON_NULL(TAG, acl, ERROR,  OC_STACK_INVALID_PARAM);
-    VERIFY_NON_NULL(TAG, resultCallback, ERROR,  OC_STACK_INVALID_CALLBACK);
+    VERIFY_NON_NULL_RET(TAG, selectedDeviceInfo, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL_RET(TAG, acl, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL_RET(TAG, resultCallback, ERROR,  OC_STACK_INVALID_CALLBACK);
 
     // if rowneruuid is empty, set it to device ID
     OicUuid_t emptyOwner = {.id = {0} };
@@ -991,14 +952,14 @@ OCStackResult SRPProvisionACL(void *ctx, const OCProvisionDev_t *selectedDeviceI
         OICFree(aclData->resArr);
         OICFree(aclData);
     }
-    VERIFY_SUCCESS(TAG, (OC_STACK_OK == ret), ERROR, OC_STACK_ERROR);
+    VERIFY_SUCCESS_RET(TAG, (OC_STACK_OK == ret), ERROR, OC_STACK_ERROR);
     return OC_STACK_OK;
 }
 
 OCStackResult SRPSaveACL(const OicSecAcl_t *acl)
 {
     OIC_LOG(DEBUG, TAG, "IN SRPSaveACL");
-    VERIFY_NON_NULL(TAG, acl, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL_RET(TAG, acl, ERROR,  OC_STACK_INVALID_PARAM);
 
     OCStackResult res =  InstallACL(acl);
 
@@ -1034,7 +995,7 @@ static OCStackApplicationResult SRPProvisionDirectPairingCB(void *ctx, OCDoHandl
 {
     OIC_LOG_V(INFO, TAG, "Inside SRPProvisionDirectPairingCB.");
     (void)UNUSED;
-    VERIFY_NON_NULL(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
+    VERIFY_NON_NULL_RET(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
     PconfData_t *pconfData = (PconfData_t*)ctx;
     OCProvisionResultCB resultCallback = pconfData->resultCallback;
 
@@ -1064,9 +1025,9 @@ static OCStackApplicationResult SRPProvisionDirectPairingCB(void *ctx, OCDoHandl
 OCStackResult SRPProvisionDirectPairing(void *ctx, const OCProvisionDev_t *selectedDeviceInfo,
         OicSecPconf_t *pconf, OCProvisionResultCB resultCallback)
 {
-    VERIFY_NON_NULL(TAG, selectedDeviceInfo, ERROR,  OC_STACK_INVALID_PARAM);
-    VERIFY_NON_NULL(TAG, pconf, ERROR,  OC_STACK_INVALID_PARAM);
-    VERIFY_NON_NULL(TAG, resultCallback, ERROR,  OC_STACK_INVALID_CALLBACK);
+    VERIFY_NON_NULL_RET(TAG, selectedDeviceInfo, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL_RET(TAG, pconf, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL_RET(TAG, resultCallback, ERROR,  OC_STACK_INVALID_CALLBACK);
 
     // check direct-pairing capability
     if (true != selectedDeviceInfo->doxm->dpc)
@@ -1150,7 +1111,7 @@ OCStackResult SRPProvisionDirectPairing(void *ctx, const OCProvisionDev_t *selec
         OICFree(pconfData->resArr);
         OICFree(pconfData);
     }
-    VERIFY_SUCCESS(TAG, (OC_STACK_OK == ret), ERROR, OC_STACK_ERROR);
+    VERIFY_SUCCESS_RET(TAG, (OC_STACK_OK == ret), ERROR, OC_STACK_ERROR);
     return OC_STACK_OK;
 }
 
@@ -1223,9 +1184,9 @@ static OCStackResult SendDeleteCredentialRequest(void* ctx,
     char reqBuf[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
     int snRet = 0;
                     //coaps://0.0.0.0:5684/oic/sec/cred?subjectid=(Canonical ENCODED UUID)
-    char *srpUri = SRP_FORM_DELETE_CREDENTIAL;
+    const char *srpUri = SRP_FORM_DELETE_CREDENTIAL;
 #ifdef __WITH_TLS__
-    if(CA_ADAPTER_TCP == destDev->endpoint.adapter)
+    if(OC_ADAPTER_TCP == destDev->endpoint.adapter)
     {
         srpUri = SRP_FORM_DELETE_CREDENTIAL_TCP;
     }
@@ -1349,7 +1310,7 @@ static OCStackApplicationResult SRPUnlinkDevice2CB(void *unlinkCtx, OCDoHandle h
 {
     (void) handle;
     OIC_LOG(DEBUG, TAG, "IN SRPUnlinkDevice2CB");
-    VERIFY_NON_NULL(TAG, unlinkCtx, ERROR, OC_STACK_DELETE_TRANSACTION);
+    VERIFY_NON_NULL_RET(TAG, unlinkCtx, ERROR, OC_STACK_DELETE_TRANSACTION);
     UnlinkData_t* unlinkData = (UnlinkData_t*)unlinkCtx;
 
     if (clientResponse)
@@ -1412,7 +1373,7 @@ static OCStackApplicationResult SRPUnlinkDevice1CB(void *unlinkCtx, OCDoHandle h
         OCClientResponse *clientResponse)
 {
     OIC_LOG_V(INFO, TAG, "Inside SRPUnlinkDevice1CB ");
-    VERIFY_NON_NULL(TAG, unlinkCtx, ERROR, OC_STACK_DELETE_TRANSACTION);
+    VERIFY_NON_NULL_RET(TAG, unlinkCtx, ERROR, OC_STACK_DELETE_TRANSACTION);
     UnlinkData_t* unlinkData = (UnlinkData_t*)unlinkCtx;
     (void) handle;
 
@@ -1518,7 +1479,7 @@ OCStackResult SRPUnlinkDevices(void* ctx,
     }
 
     UnlinkData_t* unlinkData = (UnlinkData_t*)OICCalloc(1, sizeof(UnlinkData_t));
-    VERIFY_NON_NULL(TAG, unlinkData, ERROR, OC_STACK_NO_MEMORY);
+    VERIFY_NON_NULL_RET(TAG, unlinkData, ERROR, OC_STACK_NO_MEMORY);
 
     //Initialize unlink data
     unlinkData->ctx = ctx;
@@ -1652,7 +1613,7 @@ static OCStackApplicationResult SRPRemoveDeviceCB(void *delDevCtx, OCDoHandle ha
     //Save the deleted status in delDevCtx
     (void)handle;
     OIC_LOG_V(INFO, TAG, "Inside SRPRemoveDeviceCB.");
-    VERIFY_NON_NULL(TAG, delDevCtx, ERROR, OC_STACK_DELETE_TRANSACTION);
+    VERIFY_NON_NULL_RET(TAG, delDevCtx, ERROR, OC_STACK_DELETE_TRANSACTION);
     OCStackResult res = OC_STACK_ERROR;
 
     RemoveData_t* removeData = (RemoveData_t*)delDevCtx;
@@ -1731,7 +1692,7 @@ static OCStackApplicationResult SRPSyncDeviceCredCB(void *delDevCtx, OCDoHandle
     //Save the deleted status in delDevCtx
     (void)handle;
     OIC_LOG_V(INFO, TAG, "Inside SRPSyncDeviceCredCB.");
-    VERIFY_NON_NULL(TAG, delDevCtx, ERROR, OC_STACK_DELETE_TRANSACTION);
+    VERIFY_NON_NULL_RET(TAG, delDevCtx, ERROR, OC_STACK_DELETE_TRANSACTION);
     OCStackResult res = OC_STACK_ERROR;
 
     RemoveData_t* removeData = (RemoveData_t*)delDevCtx;
@@ -1805,9 +1766,12 @@ static OCStackApplicationResult SRPSyncDeviceCredCB(void *delDevCtx, OCDoHandle
  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
  */
-static OCStackApplicationResult SRPSyncDeviceACLCB(void *ctx, OCDoHandle handle,
+static OCStackApplicationResult SRPSyncDeviceACLCB(void *ctx, OCDoHandle UNUSED,
         OCClientResponse *clientResponse)
 {
+    (void)ctx;
+    (void)UNUSED;
+    (void)clientResponse;
     return OC_STACK_DELETE_TRANSACTION;
 }
 
@@ -1815,15 +1779,16 @@ static OCStackApplicationResult SRPSyncDeviceACLCB(void *ctx, OCDoHandle handle,
  * Callback handler of device remote reset.
  *
  * @param[in] ctx             ctx value passed to callback from calling function.
- * @param[in] handle          handle to an invocation
+ * @param[in] UNUSED          handle to an invocation
  * @param[in] clientResponse  Response from queries to remote servers.
  * @return  OC_STACK_DELETE_TRANSACTION to delete the transaction
  *          and  OC_STACK_KEEP_TRANSACTION to keep it.
  */
-static OCStackApplicationResult SRPResetDeviceCB(void *ctx, OCDoHandle handle,
+static OCStackApplicationResult SRPResetDeviceCB(void *ctx, OCDoHandle UNUSED,
         OCClientResponse *clientResponse)
 {
     OIC_LOG(DEBUG, TAG, "IN SRPResetDeviceCB");
+    (void)UNUSED;
     if(OC_STACK_OK == clientResponse->result)
     {
         OIC_LOG(DEBUG, TAG, "Change Target Device Pstat Cm SUCCEEDED");
@@ -1881,7 +1846,7 @@ error:
 }
 
 static OCStackResult GetListofDevToReqDeleteCred(const OCProvisionDev_t* pRevokeTargetDev,
-                                                 OCProvisionDev_t* pOwnedDevList,
+                                                 const OCProvisionDev_t* pOwnedDevList,
                                                  OCUuidList_t* pLinkedUuidList,
                                                  OCProvisionDev_t** ppLinkedDevList,
                                                  size_t *numOfLinkedDev)
@@ -1902,13 +1867,14 @@ static OCStackResult GetListofDevToReqDeleteCred(const OCProvisionDev_t* pRevoke
         if (OC_STACK_OK != res)
         {
             OIC_LOG(FATAL, TAG, "PDMSetLinkStale() FAIL: PDB is an obsolete one.");
-            return OC_STACK_INCONSISTENT_DB;
+            return OC_STACK_SVR_DB_NOT_EXIST;
         }
 
         if (pOwnedDevList)
         {
             // If this linked device is alive (power-on), add the deivce to the list.
-            OCProvisionDev_t *curDev = NULL, *tmpDev = NULL;
+            const OCProvisionDev_t *curDev = NULL;
+            const OCProvisionDev_t *tmpDev = NULL;
             LL_FOREACH_SAFE(pOwnedDevList, curDev, tmpDev)
             {
                 if (memcmp(curDev->doxm->deviceID.id, curUuid->dev.id, sizeof(curUuid->dev.id)) == 0)
@@ -2517,7 +2483,7 @@ static OCStackApplicationResult SRPGetCredResourceCB(void *ctx, OCDoHandle UNUSE
 {
     OIC_LOG_V(INFO, TAG, "Inside SRPGetCredResourceCB.");
     (void)UNUSED;
-    VERIFY_NON_NULL(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
+    VERIFY_NON_NULL_RET(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
     GetSecData_t *GetSecData = (GetSecData_t*)ctx;
     OCProvisionResultCB resultCallback = GetSecData->resultCallback;
 
@@ -2529,6 +2495,8 @@ static OCStackApplicationResult SRPGetCredResourceCB(void *ctx, OCDoHandle UNUSE
             size_t size = ((OCSecurityPayload*)clientResponse->payload)->payloadSize;
 
             OIC_LOG_BUFFER(DEBUG, TAG, payload, size);
+            (void)size;
+            (void)payload;
 
             registerResultForGetCredResourceCB(GetSecData, OC_STACK_OK);
             ((OCProvisionResultCB)(resultCallback))(GetSecData->ctx, GetSecData->numOfResults,
@@ -2555,8 +2523,8 @@ static OCStackApplicationResult SRPGetCredResourceCB(void *ctx, OCDoHandle UNUSE
 OCStackResult SRPGetCredResource(void *ctx, const OCProvisionDev_t *selectedDeviceInfo,
         OCProvisionResultCB resultCallback)
 {
-    VERIFY_NON_NULL(TAG, selectedDeviceInfo, ERROR,  OC_STACK_INVALID_PARAM);
-    VERIFY_NON_NULL(TAG, resultCallback, ERROR,  OC_STACK_INVALID_CALLBACK);
+    VERIFY_NON_NULL_RET(TAG, selectedDeviceInfo, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL_RET(TAG, resultCallback, ERROR,  OC_STACK_INVALID_CALLBACK);
 
     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
     if(!PMGenerateQuery(true,
@@ -2604,7 +2572,7 @@ OCStackResult SRPGetCredResource(void *ctx, const OCProvisionDev_t *selectedDevi
         OICFree(GetSecData->resArr);
         OICFree(GetSecData);
     }
-    VERIFY_SUCCESS(TAG, (OC_STACK_OK == ret), ERROR, OC_STACK_ERROR);
+    VERIFY_SUCCESS_RET(TAG, (OC_STACK_OK == ret), ERROR, OC_STACK_ERROR);
     OIC_LOG(DEBUG, TAG, "OUT SRPGetCredResource");
 
     return OC_STACK_OK;
@@ -2638,7 +2606,7 @@ static OCStackApplicationResult SRPGetACLResourceCB(void *ctx, OCDoHandle UNUSED
 {
     OIC_LOG_V(INFO, TAG, "Inside SRPGetACLResourceCB.");
     (void)UNUSED;
-    VERIFY_NON_NULL(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
+    VERIFY_NON_NULL_RET(TAG, ctx, ERROR, OC_STACK_DELETE_TRANSACTION);
     GetSecData_t *GetSecData = (GetSecData_t*)ctx;
     OCProvisionResultCB resultCallback = GetSecData->resultCallback;
 
@@ -2650,6 +2618,8 @@ static OCStackApplicationResult SRPGetACLResourceCB(void *ctx, OCDoHandle UNUSED
             size_t size = ((OCSecurityPayload*)clientResponse->payload)->payloadSize;
 
             OIC_LOG_BUFFER(DEBUG, TAG, payload, size);
+            (void)payload;
+            (void)size;
 
             registerResultForGetACLResourceCB(GetSecData, OC_STACK_OK);
             ((OCProvisionResultCB)(resultCallback))(GetSecData->ctx, GetSecData->numOfResults,
@@ -2676,8 +2646,8 @@ static OCStackApplicationResult SRPGetACLResourceCB(void *ctx, OCDoHandle UNUSED
 OCStackResult SRPGetACLResource(void *ctx, const OCProvisionDev_t *selectedDeviceInfo,
         OCProvisionResultCB resultCallback)
 {
-    VERIFY_NON_NULL(TAG, selectedDeviceInfo, ERROR,  OC_STACK_INVALID_PARAM);
-    VERIFY_NON_NULL(TAG, resultCallback, ERROR,  OC_STACK_INVALID_CALLBACK);
+    VERIFY_NON_NULL_RET(TAG, selectedDeviceInfo, ERROR,  OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL_RET(TAG, resultCallback, ERROR,  OC_STACK_INVALID_CALLBACK);
 
     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
     if(!PMGenerateQuery(true,
@@ -2725,7 +2695,7 @@ OCStackResult SRPGetACLResource(void *ctx, const OCProvisionDev_t *selectedDevic
         OICFree(GetSecData->resArr);
         OICFree(GetSecData);
     }
-    VERIFY_SUCCESS(TAG, (OC_STACK_OK == ret), ERROR, OC_STACK_ERROR);
+    VERIFY_SUCCESS_RET(TAG, (OC_STACK_OK == ret), ERROR, OC_STACK_ERROR);
     OIC_LOG(DEBUG, TAG, "OUT SRPGetACLResource");
 
     return OC_STACK_OK;
index 34132fb..1b5cd5f 100644 (file)
@@ -52,14 +52,12 @@ sptest_env.PrependUnique(CPPPATH = [
                '../../../security/provisioning/include/internal',
                '../../../../oc_logger/include',
                '../include/oxm',
-               '../../../../../extlibs/tinydtls',
                '../../../../../extlibs/cjson',
                '../../../../../extlibs/base64',
                '../../../connectivity/inc',
                '../../../connectivity/inc/pkix',
                '../../../connectivity/common/inc',
-               '../../../connectivity/api',
-               '../../../../../extlibs/tinydtls'
+               '../../../connectivity/api'
                ])
 sptest_env.AppendUnique(LIBPATH = [sptest_env.get('BUILD_DIR')])
 sptest_env.PrependUnique(LIBS = [   'ocpmapi',
@@ -71,13 +69,12 @@ sptest_env.PrependUnique(LIBS = [   'ocpmapi',
 
 if sptest_env.get('SECURED') == '1':
     sptest_env.AppendUnique(LIBS = ['mbedtls', 'mbedx509','mbedcrypto'])
-    sptest_env.AppendUnique(LIBS = ['tinydtls'])
 
 if not sptest_env.get('RELEASE'):
        sptest_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
 
 if sptest_env.get('MULTIPLE_OWNER') == '1':
-       sptest_env.AppendUnique(CPPDEFINES=['_ENABLE_MULTIPLE_OWNER_'])
+       sptest_env.AppendUnique(CPPDEFINES=['MULTIPLE_OWNER'])
 
 if target_os in ['msys_nt', 'windows']:
     sptest_env.AppendUnique(LINKFLAGS = ['/subsystem:CONSOLE'])
index 69c4c67..1bbcfa7 100644 (file)
@@ -32,9 +32,9 @@
 #include "oxmmanufacturercert.h"
 #include "securevirtualresourcetypes.h"
 #include "provisioningdatabasemanager.h"
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 #include "multipleownershiptransfermanager.h"
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 #include "srmutility.h"
 #include "doxmresource.h"
 #include "pmtypes.h"
@@ -240,10 +240,10 @@ static pid_t g_myPID2;
 static const char* g_otmCtx = "Test User Context";
 static OCProvisionDev_t* g_unownedDevices = NULL;
 static OCProvisionDev_t* g_ownedDevices = NULL;
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 static OCProvisionDev_t* g_motEnabledDevices = NULL;
 static OCProvisionDev_t* g_multiplOwnedDevices = NULL;
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
 static void GetCurrentWorkingDirectory(char* buf, size_t bufsize)
 {
@@ -303,7 +303,7 @@ static void ownershipTransferCB(void* ctx, int UNUSED1, OCProvisionResult_t* UNU
     g_doneCB = true;
 }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 static void updateDoxmForMOTCB(void* ctx, int nOfRes, OCProvisionResult_t* arr, bool hasError)
 {
     if(!hasError)
@@ -331,7 +331,7 @@ static void provisionPreconfiguredPinCB(void* ctx, int nOfRes, OCProvisionResult
     g_callbackResult = !hasError;
     g_doneCB = true;
 }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
 // callback function(s) for provisioning client using C-level provisioning API
 static void removeDeviceCB(void* ctx, int UNUSED1, OCProvisionResult_t* UNUSED2, bool hasError)
@@ -646,7 +646,7 @@ TEST(PerformUnlinkDevices, NullParam)
     EXPECT_EQ(OC_STACK_OK, result);
 }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 TEST(RegisterPreconfiguredPIN, NullParam)
 {
     OCStackResult result = SetPreconfigPin("12341234", strlen("12341234"));
@@ -759,7 +759,7 @@ TEST(DiscoverMultipleOwnedDevices, NullParam)
     EXPECT_TRUE(NULL != g_multiplOwnedDevices);
 }*/
 
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
 TEST(PerformRemoveDevice, NullParam)
 {
index 5b1fc82..bd85794 100644 (file)
@@ -121,21 +121,21 @@ static uint8_t DEFAULT_SVR_DB[] = {
     0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x62, 0x72, 0x74, 0x81, 0x6B, 0x6F, 0x69, 0x63,
     0x2E, 0x72, 0x2E, 0x70, 0x73, 0x74, 0x61, 0x74, 0x62, 0x69, 0x66, 0x81, 0x6F, 0x6F, 0x69, 0x63,
     0x2E, 0x69, 0x66, 0x2E, 0x62, 0x61, 0x73, 0x65, 0x6C, 0x69, 0x6E, 0x65, 0x64, 0x64, 0x6F, 0x78,
-    0x6D, 0x58, 0xE8, 0xAA, 0x64, 0x6F, 0x78, 0x6D, 0x73, 0x81, 0x00, 0x66, 0x6F, 0x78, 0x6D, 0x73,
-    0x65, 0x6C, 0x00, 0x63, 0x73, 0x63, 0x74, 0x01, 0x65, 0x6F, 0x77, 0x6E, 0x65, 0x64, 0xF4, 0x6A,
-    0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x75, 0x75, 0x69, 0x64, 0x78, 0x24, 0x31, 0x31, 0x31, 0x31,
-    0x31, 0x31, 0x31, 0x31, 0x2D, 0x31, 0x31, 0x31, 0x31, 0x2D, 0x31, 0x31, 0x31, 0x31, 0x2D, 0x31,
-    0x31, 0x31, 0x31, 0x2D, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
-    0x6C, 0x64, 0x65, 0x76, 0x6F, 0x77, 0x6E, 0x65, 0x72, 0x75, 0x75, 0x69, 0x64, 0x78, 0x24, 0x30,
-    0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30,
-    0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
-    0x30, 0x30, 0x30, 0x6A, 0x72, 0x6F, 0x77, 0x6E, 0x65, 0x72, 0x75, 0x75, 0x69, 0x64, 0x78, 0x24,
-    0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x2D, 0x31, 0x31, 0x31, 0x31, 0x2D, 0x31, 0x31,
-    0x31, 0x31, 0x2D, 0x31, 0x31, 0x31, 0x31, 0x2D, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
-    0x31, 0x31, 0x31, 0x31, 0x72, 0x78, 0x2E, 0x6F, 0x72, 0x67, 0x2E, 0x69, 0x6F, 0x74, 0x69, 0x76,
-    0x69, 0x74, 0x79, 0x2E, 0x64, 0x70, 0x63, 0xF5, 0x62, 0x72, 0x74, 0x81, 0x6A, 0x6F, 0x69, 0x63,
-    0x2E, 0x72, 0x2E, 0x64, 0x6F, 0x78, 0x6D, 0x62, 0x69, 0x66, 0x81, 0x6F, 0x6F, 0x69, 0x63, 0x2E,
-    0x69, 0x66, 0x2E, 0x62, 0x61, 0x73, 0x65, 0x6C, 0x69, 0x6E, 0x65, 0xFF
+    0x6D, 0x58, 0xEB, 0xAA, 0x64, 0x6F, 0x78, 0x6D, 0x73, 0x82, 0x00, 0x19, 0xFF, 0x00, 0x66, 0x6F,
+    0x78, 0x6D, 0x73, 0x65, 0x6C, 0x00, 0x63, 0x73, 0x63, 0x74, 0x01, 0x65, 0x6F, 0x77, 0x6E, 0x65,
+    0x64, 0xF4, 0x6A, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x75, 0x75, 0x69, 0x64, 0x78, 0x24, 0x31,
+    0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x2D, 0x31, 0x31, 0x31, 0x31, 0x2D, 0x31, 0x31, 0x31,
+    0x31, 0x2D, 0x31, 0x31, 0x31, 0x31, 0x2D, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
+    0x31, 0x31, 0x31, 0x6C, 0x64, 0x65, 0x76, 0x6F, 0x77, 0x6E, 0x65, 0x72, 0x75, 0x75, 0x69, 0x64,
+    0x78, 0x24, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x2D,
+    0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+    0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x6A, 0x72, 0x6F, 0x77, 0x6E, 0x65, 0x72, 0x75, 0x75, 0x69,
+    0x64, 0x78, 0x24, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x2D, 0x31, 0x31, 0x31, 0x31,
+    0x2D, 0x31, 0x31, 0x31, 0x31, 0x2D, 0x31, 0x31, 0x31, 0x31, 0x2D, 0x31, 0x31, 0x31, 0x31, 0x31,
+    0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x72, 0x78, 0x2E, 0x6F, 0x72, 0x67, 0x2E, 0x69, 0x6F,
+    0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2E, 0x64, 0x70, 0x63, 0xF5, 0x62, 0x72, 0x74, 0x81, 0x6A,
+    0x6F, 0x69, 0x63, 0x2E, 0x72, 0x2E, 0x64, 0x6F, 0x78, 0x6D, 0x62, 0x69, 0x66, 0x81, 0x6F, 0x6F,
+    0x69, 0x63, 0x2E, 0x69, 0x66, 0x2E, 0x62, 0x61, 0x73, 0x65, 0x6C, 0x69, 0x6E, 0x65, 0xFF
 };
 
 /* Function that creates a new LED resource by calling the
index bb70573..6964899 100644 (file)
@@ -121,21 +121,21 @@ static uint8_t DEFAULT_SVR_DB[] = {
     0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x62, 0x72, 0x74, 0x81, 0x6B, 0x6F, 0x69, 0x63,
     0x2E, 0x72, 0x2E, 0x70, 0x73, 0x74, 0x61, 0x74, 0x62, 0x69, 0x66, 0x81, 0x6F, 0x6F, 0x69, 0x63,
     0x2E, 0x69, 0x66, 0x2E, 0x62, 0x61, 0x73, 0x65, 0x6C, 0x69, 0x6E, 0x65, 0x64, 0x64, 0x6F, 0x78,
-    0x6D, 0x58, 0xE8, 0xAA, 0x64, 0x6F, 0x78, 0x6D, 0x73, 0x81, 0x00, 0x66, 0x6F, 0x78, 0x6D, 0x73,
-    0x65, 0x6C, 0x00, 0x63, 0x73, 0x63, 0x74, 0x01, 0x65, 0x6F, 0x77, 0x6E, 0x65, 0x64, 0xF4, 0x6A,
-    0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x75, 0x75, 0x69, 0x64, 0x78, 0x24, 0x32, 0x32, 0x32, 0x32,
-    0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32,
-    0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
-    0x6C, 0x64, 0x65, 0x76, 0x6F, 0x77, 0x6E, 0x65, 0x72, 0x75, 0x75, 0x69, 0x64, 0x78, 0x24, 0x30,
-    0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30,
-    0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
-    0x30, 0x30, 0x30, 0x6A, 0x72, 0x6F, 0x77, 0x6E, 0x65, 0x72, 0x75, 0x75, 0x69, 0x64, 0x78, 0x24,
-    0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32,
-    0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
-    0x32, 0x32, 0x32, 0x32, 0x72, 0x78, 0x2E, 0x6F, 0x72, 0x67, 0x2E, 0x69, 0x6F, 0x74, 0x69, 0x76,
-    0x69, 0x74, 0x79, 0x2E, 0x64, 0x70, 0x63, 0xF5, 0x62, 0x72, 0x74, 0x81, 0x6A, 0x6F, 0x69, 0x63,
-    0x2E, 0x72, 0x2E, 0x64, 0x6F, 0x78, 0x6D, 0x62, 0x69, 0x66, 0x81, 0x6F, 0x6F, 0x69, 0x63, 0x2E,
-    0x69, 0x66, 0x2E, 0x62, 0x61, 0x73, 0x65, 0x6C, 0x69, 0x6E, 0x65, 0xFF
+    0x6D, 0x58, 0xEB, 0xAA, 0x64, 0x6F, 0x78, 0x6D, 0x73, 0x82, 0x00, 0x19, 0xFF, 0x00, 0x66, 0x6F,
+    0x78, 0x6D, 0x73, 0x65, 0x6C, 0x00, 0x63, 0x73, 0x63, 0x74, 0x01, 0x65, 0x6F, 0x77, 0x6E, 0x65,
+    0x64, 0xF4, 0x6A, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x75, 0x75, 0x69, 0x64, 0x78, 0x24, 0x32,
+    0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32,
+    0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
+    0x32, 0x32, 0x32, 0x6C, 0x64, 0x65, 0x76, 0x6F, 0x77, 0x6E, 0x65, 0x72, 0x75, 0x75, 0x69, 0x64,
+    0x78, 0x24, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x2D,
+    0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x2D, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+    0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x6A, 0x72, 0x6F, 0x77, 0x6E, 0x65, 0x72, 0x75, 0x75, 0x69,
+    0x64, 0x78, 0x24, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32,
+    0x2D, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x2D, 0x32, 0x32, 0x32, 0x32, 0x32,
+    0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x72, 0x78, 0x2E, 0x6F, 0x72, 0x67, 0x2E, 0x69, 0x6F,
+    0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2E, 0x64, 0x70, 0x63, 0xF5, 0x62, 0x72, 0x74, 0x81, 0x6A,
+    0x6F, 0x69, 0x63, 0x2E, 0x72, 0x2E, 0x64, 0x6F, 0x78, 0x6D, 0x62, 0x69, 0x66, 0x81, 0x6F, 0x6F,
+    0x69, 0x63, 0x2E, 0x69, 0x66, 0x2E, 0x62, 0x61, 0x73, 0x65, 0x6C, 0x69, 0x6E, 0x65, 0xFF
 };
 
 /* Function that creates a new LED resource by calling the
index fdb484a..91b8da1 100644 (file)
  *
  * *****************************************************************/
 #include "gtest/gtest.h"
+extern "C" {
 #include "secureresourceprovider.h"
+#include "psinterface.h"
+}
 
 static OicSecAcl_t acl;
 static OCProvisionDev_t pDev1;
@@ -196,6 +199,7 @@ class SRPTest : public ::testing::Test
 public:
     static void SetUpTestCase()
     {
+        InitPersistentStorageInterface();
         SetPersistentHandler(&ps);
         OCStackResult res = OCRegisterPersistentStorageHandler(&ps);
         ASSERT_TRUE(res == OC_STACK_OK);
@@ -263,9 +267,10 @@ TEST_F(SRPTest, SRPSaveTrustCertChainDER)
     int result;
     uint16_t credId;
 
+    //This test case cannot succeed. because doxm resource has not been initialized.
     result = SRPSaveTrustCertChain(certData, sizeof(certData), OIC_ENCODING_DER, &credId);
 
-    EXPECT_EQ(OC_STACK_OK, result);
+    EXPECT_EQ(OC_STACK_ERROR, result);
 }
 
 TEST_F(SRPTest, SRPSaveTrustCertChainPEM)
@@ -273,9 +278,10 @@ TEST_F(SRPTest, SRPSaveTrustCertChainPEM)
     int result;
     uint16_t credId;
 
+    //This test case cannot succeed. because doxm resource has not been initialized.
     result = SRPSaveTrustCertChain(certData, sizeof(certData), OIC_ENCODING_PEM, &credId);
 
-    EXPECT_EQ(OC_STACK_OK, result);
+    EXPECT_EQ(OC_STACK_ERROR, result);
 }
 
 TEST_F(SRPTest, SRPSaveTrustCertChainNullCertData)
@@ -302,7 +308,7 @@ TEST_F(SRPTest, SRPSaveOwnCertChainTest)
 {
     int result;
     uint16_t credId;
-    OicSecCert_t cert;
+    OicSecKey_t cert;
     OicSecKey_t key;
 
     cert.data = certData;
@@ -334,7 +340,7 @@ TEST_F(SRPTest, SRPSaveOwnCertChainTestNullCertData)
 {
     int result;
     uint16_t credId;
-    OicSecCert_t cert;
+    OicSecKey_t cert;
     OicSecKey_t key;
 
     cert.data = NULL;
@@ -351,7 +357,7 @@ TEST_F(SRPTest, SRPSaveOwnCertChainTestNullKey)
 {
     int result;
     uint16_t credId;
-    OicSecCert_t cert;
+    OicSecKey_t cert;
 
     cert.data = certData;
     cert.len = sizeof(certData);
@@ -365,7 +371,7 @@ TEST_F(SRPTest, SRPSaveOwnCertChainTestNullKeyData)
 {
     int result;
     uint16_t credId;
-    OicSecCert_t cert;
+    OicSecKey_t cert;
     OicSecKey_t key;
 
     cert.data = certData;
@@ -381,7 +387,7 @@ TEST_F(SRPTest, SRPSaveOwnCertChainTestNullKeyData)
 TEST_F(SRPTest, SRPSaveOwnCertChainTestNullCredId)
 {
     int result;
-    OicSecCert_t cert;
+    OicSecKey_t cert;
     OicSecKey_t key;
 
     cert.data = certData;
index 94118bc..f557a09 100644 (file)
@@ -47,7 +47,7 @@
 #include "security_internals.h"
 
 #define TAG  "OIC_SRM_ACL"
-#define NUMBER_OF_SEC_PROV_RSCS 4
+#define NUMBER_OF_SEC_PROV_RSCS 3
 #define NUMBER_OF_DEFAULT_SEC_RSCS 2
 #define STRING_UUID_SIZE (UUID_LENGTH * 2 + 5)
 
@@ -132,7 +132,7 @@ static void FreeACE(OicSecAce_t *ace)
         validity = NULL;
     }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
     OICFree(ace->eownerID);
 #endif
 
@@ -256,7 +256,7 @@ OicSecAce_t* DuplicateACE(const OicSecAce_t* ace)
             }
         }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
         if (ace->eownerID)
         {
             if (NULL == newAce->eownerID)
@@ -362,14 +362,15 @@ OCStackResult AclToCBORPayload(const OicSecAcl_t *secAcl, uint8_t **payload, siz
             {
                 aclMapSize++;
             }
+            validityElts = validityElts->next;
         }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
         if(ace->eownerID)
         {
             aclMapSize++;
         }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
         cborEncoderResult = cbor_encoder_create_map(&acesArray, &oicSecAclMap, aclMapSize);
         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating ACES Map");
@@ -561,7 +562,7 @@ OCStackResult AclToCBORPayload(const OicSecAcl_t *secAcl, uint8_t **payload, siz
             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Validities Array.");
         }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
         // Eownerid -- Not Mandatory
         if(ace->eownerID)
         {
@@ -575,7 +576,7 @@ OCStackResult AclToCBORPayload(const OicSecAcl_t *secAcl, uint8_t **payload, siz
             OICFree(eowner);
             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding eownerId Value.");
         }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
         cborEncoderResult = cbor_encoder_close_container(&acesArray, &oicSecAclMap);
         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing ACES Map.");
@@ -687,6 +688,7 @@ OicSecAcl_t* CBORPayloadToAcl2(const uint8_t *cborPayload, const size_t size)
     cbor_parser_init(cborPayload, size, 0, &parser, &aclCbor);
 
     OicSecAcl_t *acl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
+    VERIFY_NON_NULL(TAG, acl, ERROR);
 
     // Enter ACL Map
     CborValue aclMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
@@ -727,8 +729,6 @@ OicSecAcl_t* CBORPayloadToAcl2(const uint8_t *cborPayload, const size_t size)
                     VERIFY_NON_NULL(TAG, ace, ERROR);
                     LL_APPEND(acl->aces, ace);
 
-                    VERIFY_NON_NULL(TAG, acl, ERROR);
-
                     while (cbor_value_is_valid(&aceMap))
                     {
                         char* name = NULL;
@@ -1254,7 +1254,7 @@ OicSecAcl_t* CBORPayloadToAcl(const uint8_t *cborPayload, const size_t size)
                                             }
                                         }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
                                         // eowner uuid -- Not Mandatory
                                         if (strcmp(name, OIC_JSON_EOWNERID_NAME)  == 0)
                                         {
@@ -1270,7 +1270,7 @@ OicSecAcl_t* CBORPayloadToAcl(const uint8_t *cborPayload, const size_t size)
                                             OICFree(eowner);
                                             VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
                                         }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
                                         OICFree(name);
                                     }
 
@@ -1333,7 +1333,7 @@ exit:
     return acl;
 }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 bool IsValidAclAccessForSubOwner(const OicUuid_t* uuid, const uint8_t *cborPayload, const size_t size)
 {
     bool retValue = false;
@@ -1373,7 +1373,7 @@ exit:
 
     return retValue;
 }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
 /**
  * This method removes ACE for the subject and resource from the ACL
@@ -1390,6 +1390,12 @@ OCStackResult RemoveACE(const OicUuid_t * subject, const char * resource)
 {
     OIC_LOG(DEBUG, TAG, "IN RemoveACE");
 
+    if (!gAcl)
+    {
+        OIC_LOG_V(ERROR, TAG, "%s: gAcl is NULL", __func__);
+        return OC_STACK_INVALID_PARAM;
+    }
+
     OicSecAce_t *ace = NULL;
     OicSecAce_t *tempAce = NULL;
     bool deleteFlag = false;
@@ -1702,7 +1708,7 @@ static bool IsSameValidities(OicSecValidity_t* validities1, OicSecValidity_t* va
     return false;
 }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 static bool IsSameEowner(OicUuid_t* eowner1, OicUuid_t* eowner2)
 {
     if (NULL != eowner1 && NULL != eowner2)
@@ -1746,7 +1752,7 @@ static bool IsSameACE(OicSecAce_t* ace1, OicSecAce_t* ace2)
             return false;
         }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
         if(false == IsSameEowner(ace1->eownerID, ace2->eownerID))
         {
             return false;
@@ -1839,6 +1845,7 @@ static OCStackResult RemoveAllAce(void)
 static OCEntityHandlerResult HandleACLGetRequest(const OCEntityHandlerRequest *ehRequest)
 {
     OIC_LOG(INFO, TAG, "HandleACLGetRequest processing the request");
+
     uint8_t* payload = NULL;
     size_t size = 0;
     OCEntityHandlerResult ehRet;
@@ -1857,7 +1864,16 @@ static OCEntityHandlerResult HandleACLGetRequest(const OCEntityHandlerRequest *e
         const OicSecAce_t *currentAce = NULL;
         OicSecAcl_t targetAcl;
 
-        memcpy(&targetAcl.rownerID, &gAcl->rownerID, sizeof(OicUuid_t));
+        if (NULL != gAcl)
+        {
+            memcpy(&targetAcl.rownerID, &gAcl->rownerID, sizeof(OicUuid_t));
+        }
+        else
+        {
+            OIC_LOG_V(ERROR, TAG, "%s: gAcl is NULL", __func__);
+            goto exit;
+        }
+
         targetAcl.aces = NULL;
 
         // 'Subject' field is MUST for processing a querystring in REST request.
@@ -1945,7 +1961,7 @@ static OCEntityHandlerResult HandleACLPostRequest(const OCEntityHandlerRequest *
         OIC_LOG_BUFFER(DEBUG, TAG, payload, size);
 
         newAcl = CBORPayloadToAcl(payload, size);
-        if (newAcl)
+        if (NULL != newAcl && NULL != gAcl)
         {
             bool isNewAce = true;
             OicSecAce_t* existAce = NULL;
@@ -2004,6 +2020,10 @@ static OCEntityHandlerResult HandleACLPostRequest(const OCEntityHandlerRequest *
                 }
             }
         }
+        else
+        {
+            OIC_LOG_V(ERROR, TAG, "%s: %s", __func__, (NULL == newAcl) ? "no new ACL" : "gAcl is NULL");
+        }
     }
 
     //Send response to request originator
@@ -2488,8 +2508,17 @@ OCStackResult AppendACL2(const OicSecAcl_t* acl)
 {
     OCStackResult ret = OC_STACK_ERROR;
 
+    OIC_LOG_V(DEBUG, TAG, "IN: %s", __func__);
+
     if (!acl)
     {
+        OIC_LOG_V(ERROR, TAG, "%s: acl is NULL", __func__);
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    if (!gAcl)
+    {
+        OIC_LOG_V(ERROR, TAG, "%s: gAcl is NULL", __func__);
         return OC_STACK_INVALID_PARAM;
     }
 
@@ -2520,6 +2549,8 @@ OCStackResult AppendACL2(const OicSecAcl_t* acl)
         OICFree(payload);
     }
 
+    OIC_LOG_V(DEBUG, TAG, "OUT: %s", __func__);
+
     return ret;
 }
 
@@ -2533,10 +2564,19 @@ OCStackResult AppendACL(const uint8_t *cborPayload, const size_t size)
 
 OCStackResult InstallACL(const OicSecAcl_t* acl)
 {
+    OIC_LOG_V(DEBUG, TAG, "IN: %s", __func__);
+
     OCStackResult ret = OC_STACK_ERROR;
 
     if (!acl)
     {
+        OIC_LOG_V(ERROR, TAG, "%s: acl is NULL", __func__);
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    if (!gAcl)
+    {
+        OIC_LOG_V(ERROR, TAG, "%s: gAcl is NULL", __func__);
         return OC_STACK_INVALID_PARAM;
     }
 
@@ -2599,6 +2639,8 @@ OCStackResult InstallACL(const OicSecAcl_t* acl)
         OICFree(newInstallAcl);
     }
 
+    OIC_LOG_V(DEBUG, TAG, "OUT: %s", __func__);
+    
     return ret;
 }
 
@@ -2719,8 +2761,6 @@ OCStackResult UpdateDefaultSecProvACE()
                                strlen(OIC_RSRC_DOXM_URI) + 1) == 0 ||
                        strncmp(rsrc->href, OIC_RSRC_CRED_URI,
                                strlen(OIC_RSRC_CRED_URI) + 1) == 0 ||
-                       strncmp(rsrc->href, OIC_RSRC_ACL_URI,
-                               strlen(OIC_RSRC_ACL_URI) + 1) == 0 ||
                        strncmp(rsrc->href, OIC_RSRC_PSTAT_URI,
                                strlen(OIC_RSRC_PSTAT_URI) + 1) == 0)
                     {
index 2011be0..d4a7c61 100644 (file)
 #include <unistd.h>
 #endif
 
-#ifdef __WITH_DTLS__
-#include "global.h"
-#endif
-
 #define TAG  "OIC_SRM_CREDL"
 
 /** Max credential types number used for TLS */
 static const uint16_t CBOR_SIZE = 2048;
 
 /** Max cbor size payload. */
-static const uint16_t CBOR_MAX_SIZE = 4400;
+//static const uint16_t CBOR_MAX_SIZE = 4400;
 
 /** CRED size - Number of mandatory items. */
 static const uint8_t CRED_ROOT_MAP_SIZE = 4;
 static const uint8_t CRED_MAP_SIZE = 3;
 
-
 static OicSecCred_t        *gCred = NULL;
 static OCResourceHandle    gCredHandle = NULL;
 
+#ifdef MULTIPLE_OWNER
+#define PRECONF_PIN_MIN_SIZE (8)
+#endif
+
 typedef enum CredCompareResult{
     CRED_CMP_EQUAL = 0,
     CRED_CMP_NOT_EQUAL = 1,
@@ -90,14 +89,48 @@ typedef enum CredCompareResult{
 }CredCompareResult_t;
 
 /**
+ * Internal function to check a subject of SIGNED_ASYMMETRIC_KEY(Certificate).
+ * If that subject is NULL or wildcard, set it to own deviceID.
+ * @param cred credential on SVR DB file
+ * @param deviceID own deviceuuid of doxm resource
+ *
+ * @return
+ *     true successfully done
+ *     false Invalid cred
+ */
+static bool CheckSubjectOfCertificate(OicSecCred_t* cred, OicUuid_t deviceID)
+{
+    OicUuid_t emptyUuid = {.id={0}};
+    OIC_LOG(DEBUG, TAG, "IN CheckSubjectOfCertificate");
+    VERIFY_NON_NULL(TAG, cred, ERROR);
+
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+    if ( SIGNED_ASYMMETRIC_KEY == cred->credType)
+    {
+        if((0 == memcmp(cred->subject.id, emptyUuid.id, sizeof(cred->subject.id))) ||
+            (0 == memcmp(cred->subject.id, &WILDCARD_SUBJECT_ID, sizeof(cred->subject.id))))
+        {
+            memcpy(cred->subject.id, deviceID.id, sizeof(deviceID.id));
+        }
+    }
+#endif
+
+    OIC_LOG(DEBUG, TAG, "OUT CheckSubjectOfCertificate");
+    return true;
+exit:
+    OIC_LOG(ERROR, TAG, "OUT CheckSubjectOfCertificate");
+    return false;
+}
+
+/**
  * Internal function to check credential
  */
-static bool IsVaildCredential(const OicSecCred_t* cred)
+static bool IsValidCredential(const OicSecCred_t* cred)
 {
     OicUuid_t emptyUuid = {.id={0}};
 
 
-    OIC_LOG(DEBUG, TAG, "IN IsVaildCredential");
+    OIC_LOG(INFO, TAG, "IN IsValidCredential");
 
     VERIFY_NON_NULL(TAG, cred, ERROR);
     VERIFY_SUCCESS(TAG, 0 != cred->credId, ERROR);
@@ -124,6 +157,10 @@ static bool IsVaildCredential(const OicSecCred_t* cred)
         {
             VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
             VERIFY_SUCCESS(TAG, 0 != cred->publicData.len, ERROR);
+            VERIFY_SUCCESS(TAG, \
+                           (OIC_ENCODING_UNKNOW < cred->publicData.encoding && \
+                            OIC_ENCODING_DER >= cred->publicData.encoding),
+                           ERROR);
             break;
         }
         case SIGNED_ASYMMETRIC_KEY:
@@ -134,10 +171,8 @@ static bool IsVaildCredential(const OicSecCred_t* cred)
             if(NULL != cred->optionalData.data)
             {
                 VERIFY_SUCCESS(TAG, \
-                               (OIC_ENCODING_RAW == cred->optionalData.encoding ||\
-                               OIC_ENCODING_BASE64 == cred->optionalData.encoding || \
-                               OIC_ENCODING_PEM == cred->optionalData.encoding || \
-                               OIC_ENCODING_DER == cred->optionalData.encoding), \
+                               (OIC_ENCODING_UNKNOW < cred->optionalData.encoding && \
+                                OIC_ENCODING_DER >= cred->optionalData.encoding),
                                ERROR);
             }
             break;
@@ -147,10 +182,8 @@ static bool IsVaildCredential(const OicSecCred_t* cred)
             VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
             VERIFY_SUCCESS(TAG, 0 != cred->privateData.len, ERROR);
             VERIFY_SUCCESS(TAG, \
-                           (OIC_ENCODING_RAW == cred->privateData.encoding ||\
-                           OIC_ENCODING_BASE64 == cred->privateData.encoding || \
-                           OIC_ENCODING_PEM == cred->privateData.encoding || \
-                           OIC_ENCODING_DER == cred->privateData.encoding), \
+                           (OIC_ENCODING_UNKNOW < cred->privateData.encoding && \
+                            OIC_ENCODING_DER >= cred->privateData.encoding),
                            ERROR);
             break;
         }
@@ -164,10 +197,10 @@ static bool IsVaildCredential(const OicSecCred_t* cred)
 
     VERIFY_SUCCESS(TAG, 0 != memcmp(emptyUuid.id, cred->subject.id, sizeof(cred->subject.id)), ERROR);
 
-    OIC_LOG(DEBUG, TAG, "OUT IsVaildCredential");
+    OIC_LOG(INFO, TAG, "OUT IsValidCredential : Credential are valid.");
     return true;
 exit:
-    OIC_LOG(WARNING, TAG, "OUT IsVaildCredential : Invalid Credential detected.");
+    OIC_LOG(WARNING, TAG, "OUT IsValidCredential : Invalid Credential detected.");
     return false;
 }
 
@@ -221,7 +254,7 @@ static void FreeCred(OicSecCred_t *cred)
     //Clean Period
     OICFree(cred->period);
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
     //Clean eowner
     OICFree(cred->eownerID);
 #endif
@@ -281,6 +314,261 @@ static size_t OicSecCredCount(const OicSecCred_t *secCred)
     return size;
 }
 
+static char* EncodingValueToString(OicEncodingType_t encoding)
+{
+    char* str = NULL;
+    switch (encoding)
+    {
+        case OIC_ENCODING_RAW:
+            str = (char*)OIC_SEC_ENCODING_RAW;
+            break;
+        case OIC_ENCODING_BASE64:
+            str = (char*)OIC_SEC_ENCODING_BASE64;
+            break;
+        case OIC_ENCODING_DER:
+            str = (char*)OIC_SEC_ENCODING_DER;
+            break;
+        case OIC_ENCODING_PEM:
+            str = (char*)OIC_SEC_ENCODING_PEM;
+            break;
+        default:
+            break;
+    }
+    return str;
+}
+
+static CborError SerializeEncodingToCborInternal(CborEncoder *map, const OicSecKey_t *value)
+{
+    CborError cborEncoderResult = CborNoError;
+    char *encoding = EncodingValueToString(value->encoding);
+    if (encoding)
+    {
+        cborEncoderResult = cbor_encode_text_string(map, OIC_JSON_ENCODING_NAME,
+            strlen(OIC_JSON_ENCODING_NAME));
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Encoding Tag.");
+        cborEncoderResult = cbor_encode_text_string(map, encoding,
+            strlen(encoding));
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Encoding Value.");
+
+        cborEncoderResult = cbor_encode_text_string(map, OIC_JSON_DATA_NAME,
+            strlen(OIC_JSON_DATA_NAME));
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Name Tag.");
+        if (OIC_ENCODING_DER == value->encoding ||
+            OIC_ENCODING_RAW == value->encoding)
+        {
+            cborEncoderResult = cbor_encode_byte_string(map,
+                    value->data, value->len);
+        }
+        else
+        {
+            cborEncoderResult = cbor_encode_text_string(map,
+                    (char*)value->data, value->len);
+        }
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Name Value.");
+    }
+    else
+    {
+        OIC_LOG(ERROR, TAG, "Unknown encoding type.");
+        VERIFY_CBOR_SUCCESS(TAG, CborErrorUnknownType, "Failed Adding Encoding Value.");
+    }
+    exit:
+    return cborEncoderResult;
+}
+
+static CborError SerializeEncodingToCbor(CborEncoder *rootMap, const char* tag, const OicSecKey_t *value)
+{
+    CborError cborEncoderResult = CborNoError;
+    CborEncoder map;
+    const size_t mapSize = 2;
+
+    cborEncoderResult = cbor_encode_text_string(rootMap, tag, strlen(tag));
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
+
+    cborEncoderResult = cbor_encoder_create_map(rootMap, &map, mapSize);
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Map");
+
+    VERIFY_CBOR_SUCCESS(TAG, SerializeEncodingToCborInternal(&map, value),
+                        "Failed adding OicSecKey_t structure");
+
+    cborEncoderResult = cbor_encoder_close_container(rootMap, &map);
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Map.");
+
+    exit:
+    return cborEncoderResult;
+}
+
+static CborError SerializeSecOptToCbor(CborEncoder *rootMap, const char* tag, const OicSecOpt_t *value)
+{
+    CborError cborEncoderResult = CborNoError;
+    CborEncoder map;
+    const size_t mapSize = 3;
+
+    cborEncoderResult = cbor_encode_text_string(rootMap, tag, strlen(tag));
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
+
+    cborEncoderResult = cbor_encoder_create_map(rootMap, &map, mapSize);
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Map");
+
+    OicSecKey_t in;
+    in.data = value->data;
+    in.encoding = value->encoding;
+    in.len = value->len;
+
+    VERIFY_CBOR_SUCCESS(TAG, SerializeEncodingToCborInternal(&map, &in),
+                        "Failed adding OicSecKey_t structure");
+
+    cborEncoderResult = cbor_encode_text_string(&map, OIC_JSON_REVOCATION_STATUS_NAME,
+        strlen(OIC_JSON_REVOCATION_STATUS_NAME));
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional revstat Tag.");
+    cborEncoderResult = cbor_encode_boolean(&map, value->revstat);
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional revstat Value.");
+
+    cborEncoderResult = cbor_encoder_close_container(rootMap, &map);
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Map.");
+
+    exit:
+    return cborEncoderResult;
+}
+
+static CborError DeserializeEncodingFromCborInternal(CborValue *map, char *name, OicSecKey_t *value)
+{
+    size_t len = 0;
+    CborError cborFindResult = CborNoError;
+
+    // data -- Mandatory
+    if (strcmp(name, OIC_JSON_DATA_NAME) == 0)
+    {
+        if(cbor_value_is_byte_string(map))
+        {
+            cborFindResult = cbor_value_dup_byte_string(map, &value->data,
+                &value->len, NULL);
+        }
+        else if(cbor_value_is_text_string(map))
+        {
+            cborFindResult = cbor_value_dup_text_string(map, (char**)(&value->data),
+                &value->len, NULL);
+        }
+        else
+        {
+            cborFindResult = CborErrorUnknownType;
+            OIC_LOG(ERROR, TAG, "Unknown type for private data.");
+        }
+        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PrivateData.");
+    }
+
+    // encoding -- Mandatory
+    if (strcmp(name, OIC_JSON_ENCODING_NAME) == 0)
+    {
+        char* strEncoding = NULL;
+        cborFindResult = cbor_value_dup_text_string(map, &strEncoding, &len, NULL);
+        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding EncodingType");
+
+        if(strcmp(strEncoding, OIC_SEC_ENCODING_RAW) == 0)
+        {
+            value->encoding = OIC_ENCODING_RAW;
+        }
+        else if(strcmp(strEncoding, OIC_SEC_ENCODING_BASE64) == 0)
+        {
+            value->encoding = OIC_ENCODING_BASE64;
+        }
+        else if(strcmp(strEncoding, OIC_SEC_ENCODING_DER) == 0)
+        {
+            value->encoding = OIC_ENCODING_DER;
+        }
+        else if(strcmp(strEncoding, OIC_SEC_ENCODING_PEM) == 0)
+        {
+            value->encoding = OIC_ENCODING_PEM;
+        }
+        else
+        {
+            //For unit test
+            value->encoding = OIC_ENCODING_RAW;
+            OIC_LOG(WARNING, TAG, "Unknown encoding type detected.");
+        }
+        OICFree(strEncoding);
+    }
+    exit:
+    return cborFindResult;
+}
+
+static CborError DeserializeEncodingFromCbor(CborValue *rootMap, OicSecKey_t *value)
+{
+    CborValue map = { .parser = NULL };
+    CborError cborFindResult = cbor_value_enter_container(rootMap, &map);
+    size_t len = 0;
+
+    while (cbor_value_is_valid(&map))
+    {
+        char* name = NULL;
+        CborType type = cbor_value_get_type(&map);
+        if (type == CborTextStringType && cbor_value_is_text_string(&map))
+        {
+            cborFindResult = cbor_value_dup_text_string(&map, &name, &len, NULL);
+            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
+            cborFindResult = cbor_value_advance(&map);
+            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
+        }
+        if (name)
+        {
+            VERIFY_CBOR_SUCCESS(TAG, DeserializeEncodingFromCborInternal(&map, name, value),
+                                "Failed to read OicSecKey_t value");
+        }
+        if (cbor_value_is_valid(&map))
+        {
+            cborFindResult = cbor_value_advance(&map);
+            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Map.");
+        }
+        OICFree(name);
+    }
+    exit:
+    return cborFindResult;
+}
+
+static CborError DeserializeSecOptFromCbor(CborValue *rootMap, OicSecOpt_t *value)
+{
+    CborValue map = { .parser = NULL };
+    CborError cborFindResult = cbor_value_enter_container(rootMap, &map);
+    size_t len = 0;
+    value->revstat = false;
+
+    while (cbor_value_is_valid(&map))
+    {
+        char* name = NULL;
+        CborType type = cbor_value_get_type(&map);
+        if (type == CborTextStringType && cbor_value_is_text_string(&map))
+        {
+            cborFindResult = cbor_value_dup_text_string(&map, &name, &len, NULL);
+            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
+            cborFindResult = cbor_value_advance(&map);
+            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
+        }
+        if (name)
+        {
+            // OptionalData::revstat -- Mandatory
+            if (strcmp(name, OIC_JSON_REVOCATION_STATUS_NAME) == 0)
+            {
+                cborFindResult = cbor_value_get_boolean(&map, &value->revstat);
+                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding revstat Value.")
+            }
+            OicSecKey_t out;
+            VERIFY_CBOR_SUCCESS(TAG, DeserializeEncodingFromCborInternal(&map, name, &out),
+                                "Failed to read OicSecKey_t value");
+
+            value->data = out.data;
+            value->encoding = out.encoding;
+            value->len = out.len;
+        }
+        if (cbor_value_is_valid(&map))
+        {
+            cborFindResult = cbor_value_advance(&map);
+            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing Map.");
+        }
+        OICFree(name);
+    }
+    exit:
+    return cborFindResult;
+}
+
 OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload,
                                 size_t *cborSize, int secureFlag)
 {
@@ -334,12 +622,12 @@ OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload
         }
 
 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
         if(cred->eownerID)
         {
             mapSize++;
         }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
         if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
         {
@@ -372,7 +660,7 @@ OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload
         cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_SUBJECTID_NAME,
             strlen(OIC_JSON_SUBJECTID_NAME));
         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Subject Tag.");
-        inLen = (memcmp(&(cred->subject), &WILDCARD_SUBJECT_ID, WILDCARD_SUBJECT_ID_LEN) == 0) ?
+        inLen = (memcmp(&(cred->subject), &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t)) == 0) ?
             WILDCARD_SUBJECT_ID_LEN : sizeof(OicUuid_t);
         if(inLen == WILDCARD_SUBJECT_ID_LEN)
         {
@@ -401,120 +689,16 @@ OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload
         //PublicData -- Not Mandatory
         if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->publicData.data)
         {
-            CborEncoder publicMap;
-            const size_t publicMapSize = 2;
-
-            cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PUBLICDATA_NAME,
-                strlen(OIC_JSON_PUBLICDATA_NAME));
+            cborEncoderResult = SerializeEncodingToCbor(&credMap,
+                                         OIC_JSON_PUBLICDATA_NAME, &cred->publicData);
             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Tag.");
-
-            cborEncoderResult = cbor_encoder_create_map(&credMap, &publicMap, publicMapSize);
-            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PublicData Map");
-
-            cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_JSON_DATA_NAME,
-                strlen(OIC_JSON_DATA_NAME));
-            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pub Data Tag.");
-            cborEncoderResult = cbor_encode_byte_string(&publicMap, cred->publicData.data,
-                cred->publicData.len);
-            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pub Value.");
-
-            // TODO: Need to data strucure modification for OicSecCert_t.
-            cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_JSON_ENCODING_NAME,
-                strlen(OIC_JSON_ENCODING_NAME));
-            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Encoding Tag.");
-            cborEncoderResult = cbor_encode_text_string(&publicMap, OIC_SEC_ENCODING_DER,
-                strlen(OIC_SEC_ENCODING_DER));
-            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Public Encoding Value.");
-
-            cborEncoderResult = cbor_encoder_close_container(&credMap, &publicMap);
-            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing PublicData Map.");
         }
         //OptionalData -- Not Mandatory
         if (SIGNED_ASYMMETRIC_KEY == cred->credType && cred->optionalData.data)
         {
-            CborEncoder optionalMap;
-            const size_t optionalMapSize = 2;
-
-            cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_OPTDATA_NAME,
-                strlen(OIC_JSON_OPTDATA_NAME));
+            cborEncoderResult = SerializeSecOptToCbor(&credMap,
+                                         OIC_JSON_OPTDATA_NAME, &cred->optionalData);
             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding OptionalData Tag.");
-
-            cborEncoderResult = cbor_encoder_create_map(&credMap, &optionalMap, optionalMapSize);
-            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding OptionalData Map");
-
-            // TODO: Need to data strucure modification for OicSecCert_t.
-            if(OIC_ENCODING_RAW == cred->optionalData.encoding)
-            {
-                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
-                    strlen(OIC_JSON_ENCODING_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
-                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_RAW,
-                    strlen(OIC_SEC_ENCODING_RAW));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");
-
-                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
-                    strlen(OIC_JSON_DATA_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
-                cborEncoderResult = cbor_encode_byte_string(&optionalMap, cred->optionalData.data,
-                    cred->optionalData.len);
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
-            }
-            else if(OIC_ENCODING_BASE64 == cred->optionalData.encoding)
-            {
-                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
-                    strlen(OIC_JSON_ENCODING_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
-                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_BASE64,
-                    strlen(OIC_SEC_ENCODING_BASE64));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");
-
-                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
-                    strlen(OIC_JSON_DATA_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
-                cborEncoderResult = cbor_encode_text_string(&optionalMap, (char*)(cred->optionalData.data),
-                    cred->optionalData.len);
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
-            }
-            else if(OIC_ENCODING_PEM == cred->optionalData.encoding)
-            {
-                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
-                    strlen(OIC_JSON_ENCODING_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
-                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_PEM,
-                    strlen(OIC_SEC_ENCODING_PEM));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");
-
-                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
-                    strlen(OIC_JSON_DATA_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
-                cborEncoderResult = cbor_encode_text_string(&optionalMap, (char*)(cred->optionalData.data),
-                    cred->optionalData.len);
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
-            }
-            else if(OIC_ENCODING_DER == cred->optionalData.encoding)
-            {
-                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_ENCODING_NAME,
-                    strlen(OIC_JSON_ENCODING_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Tag.");
-                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_SEC_ENCODING_DER,
-                    strlen(OIC_SEC_ENCODING_DER));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Encoding Value.");
-
-                cborEncoderResult = cbor_encode_text_string(&optionalMap, OIC_JSON_DATA_NAME,
-                    strlen(OIC_JSON_DATA_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Tag.");
-                cborEncoderResult = cbor_encode_byte_string(&optionalMap, cred->optionalData.data,
-                    cred->optionalData.len);
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding optional Value.");
-            }
-            else
-            {
-                OIC_LOG(ERROR, TAG, "Unknown encoding type for optional data.");
-                VERIFY_CBOR_SUCCESS(TAG, CborErrorUnknownType, "Failed Adding optional Encoding Value.");
-            }
-
-            cborEncoderResult = cbor_encoder_close_container(&credMap, &optionalMap);
-            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing OptionalData Map.");
         }
         //CredUsage -- Not Mandatory
         if(cred->credUsage)
@@ -530,74 +714,9 @@ OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload
         //PrivateData -- Not Mandatory
         if(!secureFlag && cred->privateData.data)
         {
-            CborEncoder privateMap;
-            const size_t privateMapSize = 2;
-
-            cborEncoderResult = cbor_encode_text_string(&credMap, OIC_JSON_PRIVATEDATA_NAME,
-                strlen(OIC_JSON_PRIVATEDATA_NAME));
+            cborEncoderResult = SerializeEncodingToCbor(&credMap,
+                                         OIC_JSON_PRIVATEDATA_NAME, &cred->privateData);
             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Tag.");
-
-            cborEncoderResult = cbor_encoder_create_map(&credMap, &privateMap, privateMapSize);
-            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PrivateData Map");
-
-            // TODO: Need to data strucure modification for OicSecKey_t.
-            // TODO: Added as workaround, will be replaced soon.
-            if(OIC_ENCODING_RAW == cred->privateData.encoding)
-            {
-                cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME,
-                    strlen(OIC_JSON_ENCODING_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag.");
-                cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_RAW,
-                    strlen(OIC_SEC_ENCODING_RAW));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value.");
-
-                cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME,
-                    strlen(OIC_JSON_DATA_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag.");
-                cborEncoderResult = cbor_encode_byte_string(&privateMap, cred->privateData.data,
-                    cred->privateData.len);
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value.");
-            }
-            else if(OIC_ENCODING_BASE64 == cred->privateData.encoding)
-            {
-                cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME,
-                    strlen(OIC_JSON_ENCODING_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag.");
-                cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_BASE64,
-                    strlen(OIC_SEC_ENCODING_BASE64));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value.");
-
-                cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME,
-                    strlen(OIC_JSON_DATA_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag.");
-                cborEncoderResult = cbor_encode_text_string(&privateMap, (char*)(cred->privateData.data),
-                    cred->privateData.len);
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value.");
-            }
-            else if(OIC_ENCODING_DER == cred->privateData.encoding)
-            {
-                cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_ENCODING_NAME,
-                    strlen(OIC_JSON_ENCODING_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Tag.");
-                cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_SEC_ENCODING_DER,
-                    strlen(OIC_SEC_ENCODING_DER));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Private Encoding Value.");
-
-                cborEncoderResult = cbor_encode_text_string(&privateMap, OIC_JSON_DATA_NAME,
-                    strlen(OIC_JSON_DATA_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Tag.");
-                cborEncoderResult = cbor_encode_byte_string(&privateMap, cred->privateData.data,
-                    cred->privateData.len);
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Priv Value.");
-            }
-            else
-            {
-                OIC_LOG(ERROR, TAG, "Unknown encoding type for private data.");
-                VERIFY_CBOR_SUCCESS(TAG, CborErrorUnknownType, "Failed Adding Private Encoding Value.");
-            }
-
-            cborEncoderResult = cbor_encoder_close_container(&credMap, &privateMap);
-            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing PrivateData Map.");
         }
 
         //Period -- Not Mandatory
@@ -611,7 +730,7 @@ OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload
             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Period Name Value.");
         }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
         // Eownerid -- Not Mandatory
         if(cred->eownerID)
         {
@@ -625,7 +744,7 @@ OCStackResult CredToCBORPayload(const OicSecCred_t *credS, uint8_t **cborPayload
             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding eownerId Value.");
             OICFree(eowner);
         }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
         cborEncoderResult = cbor_encoder_close_container(&credArray, &credMap);
         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Cred Map.");
@@ -736,6 +855,7 @@ OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
     cbor_parser_init(cborPayload, size, 0, &parser, &credCbor);
 
     OicSecCred_t *headCred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
+    VERIFY_NON_NULL(TAG, headCred, ERROR);
 
     // Enter CRED Root Map
     CborValue CredRootMap = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
@@ -781,6 +901,7 @@ OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
                     else
                     {
                         cred = (OicSecCred_t *) OICCalloc(1, sizeof(OicSecCred_t));
+                        VERIFY_NON_NULL(TAG, cred, ERROR);
                         OicSecCred_t *temp = headCred;
                         while (temp->next)
                         {
@@ -789,8 +910,6 @@ OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
                         temp->next = cred;
                     }
 
-                    VERIFY_NON_NULL(TAG, cred, ERROR);
-
                     while(cbor_value_is_valid(&credMap) && cbor_value_is_text_string(&credMap))
                     {
                         char* name = NULL;
@@ -832,210 +951,42 @@ OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
                             // credtype
                             if (strcmp(name, OIC_JSON_CREDTYPE_NAME)  == 0)
                             {
+#ifdef __TIZENRT__
+                                cborFindResult = cbor_value_get_int(&credMap, (int *) &cred->credType);
+                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredType.");
+#else
                                 uint64_t credType = 0;
                                 cborFindResult = cbor_value_get_uint64(&credMap, &credType);
                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CredType.");
                                 cred->credType = (OicSecCredType_t)credType;
+#endif
                             }
                             // privatedata
                             if (strcmp(name, OIC_JSON_PRIVATEDATA_NAME)  == 0)
                             {
-                                CborValue privateMap = { .parser = NULL };
-                                cborFindResult = cbor_value_enter_container(&credMap, &privateMap);
+                                cborFindResult = DeserializeEncodingFromCbor(&credMap, &cred->privateData);
+                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to read privateData structure");
 
-                                while (cbor_value_is_valid(&privateMap))
+                                OicEncodingType_t encoding = cred->privateData.encoding;
+                                if (OIC_ENCODING_DER == encoding || OIC_ENCODING_PEM == encoding)
                                 {
-                                    char* privname = NULL;
-                                    CborType type = cbor_value_get_type(&privateMap);
-                                    if (type == CborTextStringType && cbor_value_is_text_string(&privateMap))
-                                    {
-                                        cborFindResult = cbor_value_dup_text_string(&privateMap, &privname,
-                                                &len, NULL);
-                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
-                                        cborFindResult = cbor_value_advance(&privateMap);
-                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
-                                    }
-                                    if (privname)
-                                    {
-                                        // PrivateData::privdata -- Mandatory
-                                        if (strcmp(privname, OIC_JSON_DATA_NAME) == 0)
-                                        {
-                                            if(cbor_value_is_byte_string(&privateMap))
-                                            {
-                                                cborFindResult = cbor_value_dup_byte_string(&privateMap, &cred->privateData.data,
-                                                    &cred->privateData.len, NULL);
-                                            }
-                                            else if(cbor_value_is_text_string(&privateMap))
-                                            {
-                                                cborFindResult = cbor_value_dup_text_string(&privateMap, (char**)(&cred->privateData.data),
-                                                    &cred->privateData.len, NULL);
-                                            }
-                                            else
-                                            {
-                                                cborFindResult = CborErrorUnknownType;
-                                                OIC_LOG(ERROR, TAG, "Unknown type for private data.");
-                                            }
-                                            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PrivateData.");
-                                        }
-
-                                        // PrivateData::encoding -- Mandatory
-                                        if (strcmp(privname, OIC_JSON_ENCODING_NAME) == 0)
-                                        {
-                                            // TODO: Added as workaround. Will be replaced soon.
-                                            char* strEncoding = NULL;
-                                            cborFindResult = cbor_value_dup_text_string(&privateMap, &strEncoding, &len, NULL);
-                                            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding EncodingType");
-
-                                            if(strcmp(strEncoding, OIC_SEC_ENCODING_RAW) == 0)
-                                            {
-                                                cred->privateData.encoding = OIC_ENCODING_RAW;
-                                            }
-                                            else if(strcmp(strEncoding, OIC_SEC_ENCODING_BASE64) == 0)
-                                            {
-                                                cred->privateData.encoding = OIC_ENCODING_BASE64;
-                                            }
-                                            else
-                                            {
-                                                //For unit test
-                                                cred->privateData.encoding = OIC_ENCODING_RAW;
-                                                OIC_LOG(WARNING, TAG, "Unknown encoding type dectected for private data.");
-                                            }
-
-                                            OICFree(strEncoding);
-                                        }
-                                    }
-                                    if (cbor_value_is_valid(&privateMap))
-                                    {
-                                        cborFindResult = cbor_value_advance(&privateMap);
-                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing privatedata Map.");
-                                    }
-                                    OICFree(privname);
+                                    //For unit test
+                                    cred->privateData.encoding = OIC_ENCODING_RAW;
+                                    OIC_LOG(WARNING, TAG, "Unknown encoding type detected for private data.");
                                 }
-
                             }
 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
                             //PublicData -- Not Mandatory
                             if (strcmp(name, OIC_JSON_PUBLICDATA_NAME)  == 0)
                             {
-                                CborValue pubMap = { .parser = NULL };
-                                cborFindResult = cbor_value_enter_container(&credMap, &pubMap);
-
-                                while (cbor_value_is_valid(&pubMap))
-                                {
-                                    char* pubname = NULL;
-                                    CborType type = cbor_value_get_type(&pubMap);
-                                    if (type == CborTextStringType && cbor_value_is_text_string(&pubMap))
-                                    {
-                                        cborFindResult = cbor_value_dup_text_string(&pubMap, &pubname,
-                                                &len, NULL);
-                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
-                                        cborFindResult = cbor_value_advance(&pubMap);
-                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
-                                    }
-                                    if (pubname)
-                                    {
-                                        // PrivateData::privdata -- Mandatory
-                                        if (strcmp(pubname, OIC_JSON_DATA_NAME) == 0 && cbor_value_is_byte_string(&pubMap))
-                                        {
-                                            cborFindResult = cbor_value_dup_byte_string(&pubMap, &cred->publicData.data,
-                                                &cred->publicData.len, NULL);
-                                            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PubData.");
-                                        }
-                                        // PublicData::encoding -- Mandatory
-                                        if (strcmp(pubname, OIC_JSON_ENCODING_NAME) == 0)
-                                        {
-                                            // TODO: Need to update data structure, just ignore encoding value now.
-                                        }
-                                    }
-                                    if (cbor_value_is_valid(&pubMap))
-                                    {
-                                        cborFindResult = cbor_value_advance(&pubMap);
-                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing publicdata Map.");
-                                    }
-                                    OICFree(pubname);
-                                }
+                                cborFindResult = DeserializeEncodingFromCbor(&credMap, &cred->publicData);
+                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to read publicData structure");
                             }
                             //OptionalData -- Not Mandatory
                             if (strcmp(name, OIC_JSON_OPTDATA_NAME)  == 0)
                             {
-                                CborValue optMap = { .parser = NULL };
-                                cborFindResult = cbor_value_enter_container(&credMap, &optMap);
-
-                                while (cbor_value_is_valid(&optMap))
-                                {
-                                    char* optname = NULL;
-                                    CborType type = cbor_value_get_type(&optMap);
-                                    if (type == CborTextStringType && cbor_value_is_text_string(&optMap))
-                                    {
-                                        cborFindResult = cbor_value_dup_text_string(&optMap, &optname,
-                                                &len, NULL);
-                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to get text");
-                                        cborFindResult = cbor_value_advance(&optMap);
-                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to advance value");
-                                    }
-                                    if (optname)
-                                    {
-                                        // OptionalData::optdata -- Mandatory
-                                        if (strcmp(optname, OIC_JSON_DATA_NAME) == 0)
-                                        {
-                                            if(cbor_value_is_byte_string(&optMap))
-                                            {
-                                                cborFindResult = cbor_value_dup_byte_string(&optMap, &cred->optionalData.data,
-                                                    &cred->optionalData.len, NULL);
-                                            }
-                                            else if(cbor_value_is_text_string(&optMap))
-                                            {
-                                                cborFindResult = cbor_value_dup_text_string(&optMap, (char**)(&cred->optionalData.data),
-                                                    &cred->optionalData.len, NULL);
-                                            }
-                                            else
-                                            {
-                                                cborFindResult = CborErrorUnknownType;
-                                                OIC_LOG(ERROR, TAG, "Unknown type for optional data.");
-                                            }
-                                            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding OptionalData.");
-                                        }
-                                        // OptionalData::encoding -- Mandatory
-                                        if (strcmp(optname, OIC_JSON_ENCODING_NAME) == 0)
-                                        {
-                                            // TODO: Added as workaround. Will be replaced soon.
-                                            char* strEncoding = NULL;
-                                            cborFindResult = cbor_value_dup_text_string(&optMap, &strEncoding, &len, NULL);
-                                            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding EncodingType");
-
-                                            if(strcmp(strEncoding, OIC_SEC_ENCODING_RAW) == 0)
-                                            {
-                                                OIC_LOG(INFO,TAG,"cbor_value_is_byte_string");
-                                                cred->optionalData.encoding = OIC_ENCODING_RAW;
-                                            }
-                                            else if(strcmp(strEncoding, OIC_SEC_ENCODING_BASE64) == 0)
-                                            {
-                                                cred->optionalData.encoding = OIC_ENCODING_BASE64;
-                                            }
-                                            else if(strcmp(strEncoding, OIC_SEC_ENCODING_PEM) == 0)
-                                            {
-                                                cred->optionalData.encoding = OIC_ENCODING_PEM;
-                                            }
-                                            else if(strcmp(strEncoding, OIC_SEC_ENCODING_DER) == 0)
-                                            {
-                                                cred->optionalData.encoding = OIC_ENCODING_DER;
-                                            }
-                                            else
-                                            {
-                                                //For unit test
-                                                cred->optionalData.encoding = OIC_ENCODING_RAW;
-                                                OIC_LOG(WARNING, TAG, "Unknown encoding type dectected for optional data.");
-                                            }
-                                            OICFree(strEncoding);
-                                        }
-                                    }
-                                    if (cbor_value_is_valid(&optMap))
-                                    {
-                                        cborFindResult = cbor_value_advance(&optMap);
-                                        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing optdata Map.");
-                                    }
-                                    OICFree(optname);
-                                }
+                                cborFindResult = DeserializeSecOptFromCbor(&credMap, &cred->optionalData);
+                                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to read optionalData structure");
                             }
                             //Credusage -- Not Mandatory
                             if (0 == strcmp(OIC_JSON_CREDUSAGE_NAME, name))
@@ -1051,7 +1002,7 @@ OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
                                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Period.");
                             }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
                             // Eowner uuid -- Not Mandatory
                             if (strcmp(OIC_JSON_EOWNERID_NAME, name)  == 0 && cbor_value_is_text_string(&credMap))
                             {
@@ -1067,7 +1018,7 @@ OCStackResult CBORPayloadToCred(const uint8_t *cborPayload, size_t size,
                                 OICFree(eowner);
                                 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
                             }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
                             if (cbor_value_is_valid(&credMap))
                             {
@@ -1125,7 +1076,7 @@ exit:
     return ret;
 }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 bool IsValidCredentialAccessForSubOwner(const OicUuid_t* uuid, const uint8_t *cborPayload, size_t size)
 {
     OicSecCred_t* cred = NULL;
@@ -1149,10 +1100,10 @@ exit:
     return isValidCred;
 
 }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
 OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t credType,
-                                  const OicSecCert_t * publicData, const OicSecKey_t* privateData,
+                                  const OicSecKey_t * publicData, const OicSecKey_t* privateData,
                                   const OicUuid_t * rownerID, const OicUuid_t * eownerID)
 {
     OIC_LOG(DEBUG, TAG, "IN GenerateCredential");
@@ -1190,41 +1141,22 @@ OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t cr
         VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
         memcpy(cred->privateData.data, privateData->data, privateData->len);
         cred->privateData.len = privateData->len;
-
-        // TODO: Added as workaround. Will be replaced soon.
         cred->privateData.encoding = OIC_ENCODING_RAW;
-
-#if 0
-        // NOTE: Test codes to use base64 for credential.
-        uint32_t outSize = 0;
-        size_t b64BufSize = B64ENCODE_OUT_SAFESIZE((privateData->len + 1));
-        char* b64Buf = (uint8_t *)OICCalloc(1, b64BufSize);
-        VERIFY_NON_NULL(TAG, b64Buf, ERROR);
-        b64Encode(privateData->data, privateData->len, b64Buf, b64BufSize, &outSize);
-
-        OICFree( cred->privateData.data );
-        cred->privateData.data = (uint8_t *)OICCalloc(1, outSize + 1);
-        VERIFY_NON_NULL(TAG, cred->privateData.data, ERROR);
-
-        strcpy(cred->privateData.data, b64Buf);
-        cred->privateData.encoding = OIC_ENCODING_BASE64;
-        cred->privateData.len = outSize;
-        OICFree(b64Buf);
-#endif //End of Test codes
-
     }
 
     VERIFY_NON_NULL(TAG, rownerID, ERROR);
     memcpy(&cred->rownerID, rownerID, sizeof(OicUuid_t));
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
     if(eownerID)
     {
         cred->eownerID = (OicUuid_t*)OICCalloc(1, sizeof(OicUuid_t));
         VERIFY_NON_NULL(TAG, cred->eownerID, ERROR);
         memcpy(cred->eownerID->id, eownerID->id, sizeof(eownerID->id));
     }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#else
+    (void)(eownerID);
+#endif //MULTIPLE_OWNER_
 
     ret = OC_STACK_OK;
 
@@ -1252,7 +1184,7 @@ OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t cr
     {
         OIC_LOG_V(DEBUG, TAG, "GenerateCredential : optionalData len: %d", cred->optionalData.len);
         OIC_LOG_BUFFER(DEBUG, TAG, cred->optionalData.data, cred->optionalData.len);
-
+        OIC_LOG_V(DEBUG, TAG, "GenerateCredential : optionalData revstat: %d", cred->optionalData.revstat);
     }
 #endif //defined(__WITH_DTLS__) || defined(__WITH_TLS__)
 
@@ -1278,7 +1210,7 @@ static bool UpdatePersistentStorage(const OicSecCred_t *cred)
         // This added '512' is arbitrary value that is added to cover the name of the resource, map addition and ending
         size_t size = GetCredKeyDataSize(cred);
         size += (512 * OicSecCredCount(cred));
-        OIC_LOG_V(DEBUG, TAG, "cred size: %" PRIu64, size);
+        OIC_LOG_V(INFO, TAG, "target cred size: %zu - temporal size to make room for encoding", size);
 
         int secureFlag = 0;
         OCStackResult res = CredToCBORPayload(cred, &payload, &size, secureFlag);
@@ -1373,7 +1305,7 @@ static OicSecCred_t* GetCredDefault()
     return NULL;
 }
 
-static bool IsSameSecKey(const OicSecKey_t* sk1, const OicSecKey_t* sk2)
+static bool IsSameSecOpt(const OicSecOpt_t* sk1, const OicSecOpt_t* sk2)
 {
     VERIFY_NON_NULL(TAG, sk1, WARNING);
     VERIFY_NON_NULL(TAG, sk2, WARNING);
@@ -1386,19 +1318,18 @@ exit:
     return false;
 }
 
-#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
-static bool IsSameCert(const OicSecCert_t* cert1, const OicSecCert_t* cert2)
+static bool IsSameSecKey(const OicSecKey_t* sk1, const OicSecKey_t* sk2)
 {
-    VERIFY_NON_NULL(TAG, cert1, WARNING);
-    VERIFY_NON_NULL(TAG, cert2, WARNING);
+    VERIFY_NON_NULL(TAG, sk1, WARNING);
+    VERIFY_NON_NULL(TAG, sk2, WARNING);
 
-    VERIFY_SUCCESS(TAG, (cert1->len == cert2->len), INFO);
-    VERIFY_SUCCESS(TAG, (0 == memcmp(cert1->data, cert2->data, cert1->len)), INFO);
+    VERIFY_SUCCESS(TAG, (sk1->len == sk2->len), INFO);
+    VERIFY_SUCCESS(TAG, (sk1->encoding == sk2->encoding), INFO);
+    VERIFY_SUCCESS(TAG, (0 == memcmp(sk1->data, sk2->data, sk1->len)), INFO);
     return true;
 exit:
     return false;
 }
-#endif //#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
 
 /**
  * Compares credential
@@ -1441,13 +1372,13 @@ static CredCompareResult_t CompareCredential(const OicSecCred_t * l, const OicSe
         {
             if(l->publicData.data && r->publicData.data)
             {
-                VERIFY_SUCCESS(TAG, IsSameCert(&l->publicData, &r->publicData), INFO);
+                VERIFY_SUCCESS(TAG, IsSameSecKey(&l->publicData, &r->publicData), INFO);
                 isCompared = true;
             }
 
             if(l->optionalData.data && r->optionalData.data)
             {
-                VERIFY_SUCCESS(TAG, IsSameSecKey(&l->optionalData, &r->optionalData), INFO);
+                VERIFY_SUCCESS(TAG, IsSameSecOpt(&l->optionalData, &r->optionalData), INFO);
                 isCompared = true;
             }
 
@@ -1469,13 +1400,13 @@ static CredCompareResult_t CompareCredential(const OicSecCred_t * l, const OicSe
 
             if(l->publicData.data && r->publicData.data)
             {
-                VERIFY_SUCCESS(TAG, IsSameCert(&l->publicData, &r->publicData), INFO);
+                VERIFY_SUCCESS(TAG, IsSameSecKey(&l->publicData, &r->publicData), INFO);
                 isCompared = true;
             }
 
             if(l->optionalData.data && r->optionalData.data)
             {
-                VERIFY_SUCCESS(TAG, IsSameSecKey(&l->optionalData, &r->optionalData), INFO);
+                VERIFY_SUCCESS(TAG, IsSameSecOpt(&l->optionalData, &r->optionalData), INFO);
                 isCompared = true;
             }
 
@@ -1484,8 +1415,9 @@ static CredCompareResult_t CompareCredential(const OicSecCred_t * l, const OicSe
 #endif //__WITH_DTLS__ or __WITH_TLS__
         default:
         {
+            OIC_LOG_V(ERROR, TAG, "Invalid CredType(%d)", l->credType);
             cmpResult = CRED_CMP_ERROR;
-            break;
+            goto exit;
         }
     }
 
@@ -1517,7 +1449,7 @@ OCStackResult AddCredential(OicSecCred_t * newCred)
     VERIFY_SUCCESS(TAG, NULL != newCred, ERROR);
     //Assigning credId to the newCred
     newCred->credId = GetCredId();
-    VERIFY_SUCCESS(TAG, true == IsVaildCredential(newCred), ERROR);
+    VERIFY_SUCCESS(TAG, true == IsValidCredential(newCred), ERROR);
 
     //the newCred is not valid if it is empty
 
@@ -1553,6 +1485,7 @@ OCStackResult AddCredential(OicSecCred_t * newCred)
     //Append the new Cred to existing list if new Cred is valid
     if (validFlag)
     {
+        OIC_LOG(INFO, TAG, "New credentials are added to the cred resource");
         LL_APPEND(gCred, newCred);
     }
     if (memcmp(&(newCred->rownerID), &emptyOwner, sizeof(OicUuid_t)) != 0)
@@ -1561,9 +1494,15 @@ OCStackResult AddCredential(OicSecCred_t * newCred)
     }
     if (UpdatePersistentStorage(gCred))
     {
+        OIC_LOG(DEBUG, TAG, "UpdatePersistentStorage() Success");
         ret = OC_STACK_OK;
     }
-
+    else
+    {
+        OIC_LOG(ERROR, TAG, "UpdatePersistentStorage() Failed");
+        LL_DELETE(gCred, newCred);
+        ret = OC_STACK_INCONSISTENT_DB;
+    }
 exit:
     OIC_LOG(DEBUG, TAG, "OUT AddCredential");
     return ret;
@@ -1693,7 +1632,11 @@ static bool FillPrivateDataOfOwnerPSK(OicSecCred_t* receviedCred, const CAEndpoi
     // TODO: Added as workaround, will be replaced soon.
     if(OIC_ENCODING_RAW == receviedCred->privateData.encoding)
     {
+#ifndef __TIZENRT__
         receviedCred->privateData.data = (uint8_t *)OICCalloc(1, OWNER_PSK_LENGTH_128);
+#else
+        receviedCred->privateData.data = (uint8_t *)OICRealloc(receviedCred->privateData.data, OWNER_PSK_LENGTH_128);
+#endif
         VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
         receviedCred->privateData.len = OWNER_PSK_LENGTH_128;
         memcpy(receviedCred->privateData.data, ownerPSK, OWNER_PSK_LENGTH_128);
@@ -1708,8 +1651,11 @@ static bool FillPrivateDataOfOwnerPSK(OicSecCred_t* receviedCred, const CAEndpoi
 
         b64res = b64Encode(ownerPSK, OWNER_PSK_LENGTH_128, b64Buf, b64BufSize, &b64OutSize);
         VERIFY_SUCCESS(TAG, B64_OK == b64res, ERROR);
-
+#ifndef __TIZENRT__
         receviedCred->privateData.data = (uint8_t *)OICCalloc(1, b64OutSize + 1);
+#else
+        receviedCred->privateData.data = (uint8_t *)OICRealloc(receviedCred->privateData.data, b64OutSize + 1);
+#endif
         VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
         receviedCred->privateData.len = b64OutSize;
         strncpy((char*)receviedCred->privateData.data, b64Buf, b64OutSize);
@@ -1739,7 +1685,7 @@ exit:
 }
 
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 /**
  * Internal function to fill private data of SubOwner PSK.
  *
@@ -1810,7 +1756,93 @@ exit:
     OICFree(b64Buf);
     return false;
 }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
+
+
+OCStackResult AddPreconfPinCredential(const char* preconfPin)
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+
+#ifdef MULTIPLE_OWNER
+    OCStackResult res = OC_STACK_INVALID_PARAM;
+    OicSecCred_t* cred = NULL;
+    OicSecCred_t* pinCred = NULL;
+    VERIFY_NON_NULL(TAG, preconfPin, ERROR);
+    VERIFY_SUCCESS(TAG, (strlen(preconfPin) >= PRECONF_PIN_MIN_SIZE), ERROR);
+
+    OIC_LOG(DEBUG, TAG, "Finding previous preconfigured PIN...");
+    //Find the previous PIN
+    LL_FOREACH(gCred, cred)
+    {
+        if(memcmp(cred->subject.id, WILDCARD_SUBJECT_ID.id, sizeof(cred->subject.id)) == 0 &&
+            PIN_PASSWORD == cred->credType)
+        {
+            break;
+        }
+    }
+
+    //If previous PIN is exist, remove it.
+    if (cred)
+    {
+        OIC_LOG_V(DEBUG, TAG, "Preconfigured PIN already exist.");
+        OIC_LOG_V(DEBUG, TAG, "Previous preconfigured PIN will be removed.");
+
+        res = RemoveCredentialByCredId(cred->credId);
+        if (OC_STACK_RESOURCE_DELETED != res)
+        {
+            OIC_LOG_V(ERROR, TAG, "RemoveCredentialByCredId error : %d", res);
+            cred = NULL;
+            goto exit;
+        }
+    }
+
+    OIC_LOG(DEBUG, TAG, "Adding preconfigured PIN...");
+    //Add preconfig PIN
+    res = OC_STACK_NO_MEMORY;
+    //Generate PIN based credential
+    size_t preconfPinLen = strlen(preconfPin);
+    pinCred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
+    VERIFY_NON_NULL(TAG, pinCred, ERROR);
+
+    pinCred->privateData.data = (uint8_t*)OICMalloc(preconfPinLen + 1);
+    VERIFY_NON_NULL(TAG, pinCred->privateData.data, ERROR);
+
+    memcpy(pinCred->privateData.data, preconfPin, preconfPinLen);
+    pinCred->privateData.data[preconfPinLen] = '\0';
+    pinCred->privateData.len = preconfPinLen;
+    pinCred->privateData.encoding = OIC_ENCODING_RAW;
+    pinCred->credType = PIN_PASSWORD;
+    memcpy(pinCred->subject.id, WILDCARD_SUBJECT_ID.id, sizeof(pinCred->subject.id));
+
+    res = AddCredential(pinCred);
+    if (OC_STACK_OK != res)
+    {
+        OIC_LOG_V(ERROR, TAG, "AddCredential error : %d", res);
+        goto exit;
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+    return OC_STACK_OK;
+exit:
+    if (cred)
+    {
+        FreeCred(cred);
+    }
+    if (pinCred)
+    {
+        FreeCred(pinCred);
+    }
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+    return res;
+#else
+    OC_UNUSED(preconfPin);
+    OIC_LOG(DEBUG, TAG, "Multiple Owner is not enabled.");
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+    return OC_STACK_ERROR;
+#endif //MULTIPLE_OWNER
+}
+
+
 #endif // __WITH_DTLS__ or __WITH_TLS__
 
 static OCEntityHandlerResult HandlePostRequest(OCEntityHandlerRequest * ehRequest)
@@ -1838,7 +1870,31 @@ static OCEntityHandlerResult HandlePostRequest(OCEntityHandlerRequest * ehReques
                 case SYMMETRIC_PAIR_WISE_KEY:
                 {
                     OCServerRequest *request = GetServerRequestUsingHandle(ehRequest->requestHandle);
+                    if (NULL == request)
+                    {
+                        OIC_LOG(ERROR, TAG, "Failed to get a server request information.");
+                        ret = OC_EH_ERROR;
+                        break;
+                    }
+#ifdef __TIZENRT__
+                    CAEndpoint_t *ep_addr = (CAEndpoint_t *)malloc(sizeof(CAEndpoint_t));
+                    if(!ep_addr)
+                    {
+                        ret = OC_STACK_NO_MEMORY;
+                        break;
+                    }
+                    ep_addr->adapter=   request->devAddr.adapter;
+                    ep_addr->flags=   request->devAddr.flags;
+                    ep_addr->port  =   request->devAddr.port;
+                    memcpy(ep_addr->addr,request->devAddr.addr,MAX_ADDR_STR_SIZE_CA);
+                    ep_addr->ifindex  =   request->devAddr.ifindex;
+#if defined (ROUTING_GATEWAY) || defined (ROUTING_EP)
+                    memcpy(ep_addr->routeData,request->devAddr.routeData,MAX_ADDR_STR_SIZE_CA);
+#endif
+                    if(FillPrivateDataOfOwnerPSK(cred, ep_addr, doxm))
+#else
                     if(FillPrivateDataOfOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm))
+#endif
                     {
                         if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
                         {
@@ -1861,7 +1917,9 @@ static OCEntityHandlerResult HandlePostRequest(OCEntityHandlerRequest * ehReques
                         OIC_LOG(ERROR, TAG, "Failed to verify receviced OwnerPKS.");
                         ret = OC_EH_ERROR;
                     }
-
+#ifdef __TIZENRT__
+                    free(ep_addr);
+#endif
                     if(OC_EH_CHANGED == ret)
                     {
                         /**
@@ -1893,12 +1951,17 @@ static OCEntityHandlerResult HandlePostRequest(OCEntityHandlerRequest * ehReques
                             OIC_LOG(INFO, TAG, "Anonymous cipher suite is DISABLED");
                         }
 
-                        if(CA_STATUS_OK !=
-                           CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256, ehRequest->devAddr.adapter))
+                        if (CA_STATUS_OK != CASelectCipherSuite(
+                                    MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, CA_ADAPTER_IP))
                         {
-                            OIC_LOG(ERROR, TAG, "Failed to select cipher suite");
+                            OIC_LOG(ERROR, TAG, "Failed to enable PSK cipher suite");
                             ret = OC_EH_ERROR;
                         }
+                        else
+                        {
+                            OIC_LOG(INFO, TAG, "PSK cipher suite is ENABLED");
+                        }
+
                     }
 
                     break;
@@ -1937,6 +2000,10 @@ static OCEntityHandlerResult HandlePostRequest(OCEntityHandlerRequest * ehReques
                         if((OC_ADAPTER_IP == ehRequest->devAddr.adapter && previousMsgId != ehRequest->messageID)
                            || OC_ADAPTER_TCP == ehRequest->devAddr.adapter)
                         {
+#if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
+                            InvokeOtmEventHandler(ehRequest->devAddr.addr, ehRequest->devAddr.port,
+                                                  NULL, OIC_OTM_ERROR);
+#endif
                             RestoreDoxmToInitState();
                             RestorePstatToInitState();
                             OIC_LOG(WARNING, TAG, "DOXM will be reverted.");
@@ -1949,11 +2016,13 @@ static OCEntityHandlerResult HandlePostRequest(OCEntityHandlerRequest * ehReques
                 }
             }
         }
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
         // In case SubOwner Credential
         else if(doxm && doxm->owned && doxm->mom &&
                 OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode &&
-                0 == cred->privateData.len)
+                0 == cred->privateData.len &&
+                0 == cred->optionalData.len &&
+                0 == cred->publicData.len )
         {
             switch(cred->credType)
             {
@@ -2004,7 +2073,7 @@ static OCEntityHandlerResult HandlePostRequest(OCEntityHandlerRequest * ehReques
                 }
             }
         }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
         else
         {
             if(IsEmptyCred(cred))
@@ -2212,7 +2281,7 @@ OCStackResult InitCredResource()
     }
     if (data)
     {
-        // Read ACL resource from PS
+        // Read Cred resource from PS
         ret = CBORPayloadToCred(data, size, &gCred);
     }
 
@@ -2226,18 +2295,49 @@ OCStackResult InitCredResource()
         gCred = GetCredDefault();
     }
 
-    //Add a log to track the invalid credential.
-    LL_FOREACH(gCred, cred)
+    if (gCred)
     {
-        if (false == IsVaildCredential(cred))
+        OicUuid_t deviceID;
+        OicUuid_t emptyUuid = {.id={0}};
+
+        ret = GetDoxmDeviceID(&deviceID);
+        if (ret != OC_STACK_OK)
         {
-            OIC_LOG(WARNING, TAG, "Invalid credential data was dectected while InitCredResource");
-            OIC_LOG_V(WARNING, TAG, "Invalid credential ID = %d", cred->credId);
+            OIC_LOG_V(WARNING, TAG, "%s: GetDoxmDeviceID failed, error %d", __func__, ret);
+            //Unit tests expect error code OC_STACK_INVALID_PARAM.
+            ret = OC_STACK_INVALID_PARAM;
+            goto exit;
+        }
+
+        //Add a log to track the invalid credential.
+        LL_FOREACH(gCred, cred)
+        {
+            if (false == CheckSubjectOfCertificate(cred, deviceID))
+            {
+                OIC_LOG(WARNING, TAG, "Check subject of Certificate was failed while InitCredResource");
+            }
+            if (false == IsValidCredential(cred))
+            {
+                OIC_LOG(WARNING, TAG, "Invalid credential data was dectected while InitCredResource");
+                OIC_LOG_V(WARNING, TAG, "Invalid credential ID = %d", cred->credId);
+            }
         }
-    }
 
+        if (0 == memcmp(&gCred->rownerID, &emptyUuid, sizeof(OicUuid_t)))
+        {
+            memcpy(&gCred->rownerID, &deviceID, sizeof(OicUuid_t));
+        }
+
+        if (!UpdatePersistentStorage(gCred))
+        {
+            OIC_LOG(FATAL, TAG, "UpdatePersistentStorage failed!");
+        }
+    }
     //Instantiate 'oic.sec.cred'
     ret = CreateCredResource();
+
+exit:
+    OIC_LOG(DEBUG, TAG, "OUT InitCredResource.");
     OICClearMemory(data, size);
     OICFree(data);
     return ret;
@@ -2313,16 +2413,17 @@ OicSecCred_t* GetCredEntryByCredId(const uint16_t credId)
                 cred->privateData.len = tmpCred->privateData.len;
                 cred->privateData.encoding = tmpCred->privateData.encoding;
             }
-#if defined(__WITH_X509__) || defined(__WITH_TLS__)
-            else if (tmpCred->publicData.data)
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+            if (tmpCred->publicData.data)
             {
                 cred->publicData.data = (uint8_t *)OICCalloc(1, tmpCred->publicData.len);
                 VERIFY_NON_NULL(TAG, cred->publicData.data, ERROR);
 
                 memcpy(cred->publicData.data, tmpCred->publicData.data, tmpCred->publicData.len);
                 cred->publicData.len = tmpCred->publicData.len;
+                cred->publicData.encoding = tmpCred->publicData.encoding;
             }
-            else if (tmpCred->optionalData.data)
+            if (tmpCred->optionalData.data)
             {
                 cred->optionalData.data = (uint8_t *)OICCalloc(1, tmpCred->optionalData.len);
                 VERIFY_NON_NULL(TAG, cred->optionalData.data, ERROR);
@@ -2330,13 +2431,13 @@ OicSecCred_t* GetCredEntryByCredId(const uint16_t credId)
                 memcpy(cred->optionalData.data, tmpCred->optionalData.data, tmpCred->optionalData.len);
                 cred->optionalData.len = tmpCred->optionalData.len;
                 cred->optionalData.encoding = tmpCred->optionalData.encoding;
+                cred->optionalData.revstat= tmpCred->optionalData.revstat;
             }
-
             if (tmpCred->credUsage)
             {
                 cred->credUsage = OICStrdup(tmpCred->credUsage);
             }
-#endif /* __WITH_X509__  or __WITH_TLS__*/
+#endif /* __WITH_DTLS__  or __WITH_TLS__*/
 
             return cred;
         }
@@ -2444,7 +2545,7 @@ int32_t GetDtlsPskCredentials(CADtlsPskCredType_t type,
                 }
                 OIC_LOG(DEBUG, TAG, "Can not find subject matched credential.");
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
                 const OicSecDoxm_t* doxm = GetDoxmResourceData();
                 if(doxm && doxm->mom && OIC_MULTIPLE_OWNER_DISABLE != doxm->mom->mode)
                 {
@@ -2540,7 +2641,7 @@ int32_t GetDtlsPskCredentials(CADtlsPskCredType_t type,
                         }
                     }
                 }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
             }
             break;
     }
@@ -2594,7 +2695,7 @@ OCStackResult AddTmpPskWithPIN(const OicUuid_t* tmpSubject, OicSecCredType_t cre
     ret = AddCredential(cred);
     if( OC_STACK_OK != ret)
     {
-        RemoveCredential(tmpSubject);
+        FreeCred(cred);
         OIC_LOG(ERROR, TAG, "GeneratePskWithPIN() : Failed to add credential");
     }
     OIC_LOG(DEBUG, TAG, "AddTmpPskWithPIN OUT");
@@ -2668,24 +2769,25 @@ void GetDerCaCert(ByteArray_t * crt, const char * usage)
         return;
     }
     crt->len = 0;
-    OicSecCred_t * temp = NULL;
+    OicSecCred_t* temp = NULL;
 
     LL_FOREACH(gCred, temp)
     {
-        if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
-            0 == strcmp(temp->credUsage, usage))
+        if ((SIGNED_ASYMMETRIC_KEY == temp->credType) &&
+            (0 == strcmp(temp->credUsage, usage)) && (false == temp->optionalData.revstat))
         {
             if(OIC_ENCODING_BASE64 == temp->optionalData.encoding)
             {
                 size_t bufSize = B64DECODE_OUT_SAFESIZE((temp->optionalData.len + 1));
-                uint8 * buf = OICCalloc(1, bufSize);
+                uint8_t * buf = OICCalloc(1, bufSize);
                 if(NULL == buf)
                 {
                     OIC_LOG(ERROR, TAG, "Failed to allocate memory");
                     return;
                 }
                 uint32_t outSize;
-                if(B64_OK != b64Decode(temp->optionalData.data, temp->optionalData.len, buf, bufSize, &outSize))
+                if(B64_OK != b64Decode((char*)(temp->optionalData.data),
+                                       temp->optionalData.len, buf, bufSize, &outSize))
                 {
                     OICFree(buf);
                     OIC_LOG(ERROR, TAG, "Failed to decode base64 data");
@@ -2823,3 +2925,157 @@ void InitCipherSuiteListInternal(bool * list, const char * usage)
     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
 }
 #endif
+
+
+//Added as workaround by Chul Lee
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+OCStackResult CredSaveTrustCertChain(const OicUuid_t* subject, uint8_t *trustCertChain, size_t chainSize,
+                                            OicEncodingType_t encodingType,  const char* usage, uint16_t *credId)
+{
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
+    if(NULL == trustCertChain || NULL == credId || NULL == usage || NULL == subject)
+    {
+        OIC_LOG_V(ERROR, TAG, "Invaild param");
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    OCStackResult res = OC_STACK_ERROR;
+    OicSecCred_t *cred = (OicSecCred_t*)OICCalloc(1, sizeof(OicSecCred_t));
+    if(NULL == cred)
+    {
+        OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
+        res = OC_STACK_NO_MEMORY;
+        goto error;
+    }
+    cred->credId = 0;
+    memcpy(cred->subject.id, subject->id, sizeof(cred->subject.id));
+
+    cred->credUsage = OICStrdup(usage);
+    if (NULL == cred->credUsage)
+    {
+        OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
+        res = OC_STACK_NO_MEMORY;
+        goto error;
+    }
+
+    cred->credType = SIGNED_ASYMMETRIC_KEY;
+
+    if (encodingType == OIC_ENCODING_PEM)
+    {
+        cred->optionalData.data = (uint8_t *)OICCalloc(1, chainSize + 1);
+        if(NULL == cred->optionalData.data)
+        {
+            OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
+            res = OC_STACK_NO_MEMORY;
+            goto error;
+        }
+        cred->optionalData.len = chainSize + 1;
+    }
+    else
+    {
+        cred->optionalData.data = (uint8_t *)OICCalloc(1, chainSize);
+        if(NULL == cred->optionalData.data)
+        {
+            OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
+            res = OC_STACK_NO_MEMORY;
+            goto error;
+        }
+        cred->optionalData.len = chainSize;
+    }
+    memcpy(cred->optionalData.data, trustCertChain, chainSize);
+    cred->optionalData.encoding = encodingType;
+    cred->optionalData.revstat = false;
+
+    res = AddCredential(cred);
+    if(res != OC_STACK_OK)
+    {
+        goto error;
+    }
+    *credId = cred->credId;
+
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+
+    return res;
+
+error:
+    DeleteCredList(cred);
+    OIC_LOG_V(ERROR, TAG, "OUT %s : error = %d", __func__, (int)res);
+    return res;
+}
+
+OCStackResult CredSaveOwnCert(const OicUuid_t* subject, OicSecKey_t * cert, OicSecKey_t * key,
+                                    const char* usage, uint16_t *credId)
+{
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
+    if(NULL == cert || NULL == cert->data || NULL == key || NULL == key->data ||
+       NULL == credId || NULL == usage || NULL == subject)
+    {
+        OIC_LOG_V(ERROR, TAG, "Invalid param");
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    OCStackResult res = OC_STACK_ERROR;
+    OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(OicSecCred_t));
+    if(NULL == cred)
+    {
+        OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
+        res = OC_STACK_NO_MEMORY;
+        goto error;
+    }
+    cred->credId = 0;
+    memcpy(cred->subject.id, subject->id, sizeof(cred->subject.id));
+
+    cred->credUsage = OICStrdup(usage);
+    if (NULL == cred->credUsage)
+    {
+        OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
+        res = OC_STACK_NO_MEMORY;
+        goto error;
+    }
+
+    cred->credType = SIGNED_ASYMMETRIC_KEY;
+
+    OicSecKey_t *publicData = &cred->publicData;
+    publicData->data = (uint8_t *)OICCalloc(1, cert->len);
+    if(NULL == publicData->data)
+    {
+        OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
+        res = OC_STACK_NO_MEMORY;
+        goto error;
+    }
+    memcpy(publicData->data, cert->data, cert->len);
+    publicData->encoding = cert->encoding;
+    publicData->len = cert->len;
+
+    OicSecKey_t *privateData = &cred->privateData;
+    privateData->data = (uint8_t *)OICCalloc(1, key->len);
+    if(NULL == privateData->data)
+    {
+        OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
+        res = OC_STACK_NO_MEMORY;
+        goto error;
+    }
+    memcpy(privateData->data, key->data, key->len);
+    privateData->len = key->len;
+    privateData->encoding = key->encoding;
+
+    res = AddCredential(cred);
+    if(res != OC_STACK_OK)
+    {
+        goto error;
+    }
+    *credId = cred->credId;
+
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+
+    return res;
+
+error:
+    DeleteCredList(cred);
+    OIC_LOG_V(ERROR, TAG, "OUT %s : error = %d", __func__, (int)res);
+    return res;
+}
+
+#endif // defined(__WITH_DTLS__) || defined(__WITH_TLS__)
index 9e12aac..a59df3b 100644 (file)
@@ -75,7 +75,7 @@ void DeleteCrl(OicSecCrl_t *crl)
     }
 }
 
-void printCrl(OicSecCrl_t *crl)
+void printCrl(const OicSecCrl_t *crl)
 {
     if (NULL == crl)
     {
@@ -362,16 +362,6 @@ OCStackResult CrlToCBORPayload(const OicSecCrl_t *crl, uint8_t **payload, size_t
     ret = OC_STACK_OK;
 
 exit:
-    if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE))
-    {
-        // reallocate and try again!
-        OICFree(outPayload);
-        // Since the allocated initial memory failed, double the memory.
-        cborLen += cbor_encoder_get_buffer_size(&encoder, encoder.end);
-        cborEncoderResult = CborNoError;
-        ret = CrlToCBORPayload(crl, payload, &cborLen, lastUpdate);
-    }
-
     if ((CborNoError != cborEncoderResult) || (OC_STACK_OK != ret))
     {
         OICFree(outPayload);
@@ -379,6 +369,13 @@ exit:
         *payload = NULL;
         *size = 0;
         ret = OC_STACK_ERROR;
+        if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE))
+        {
+            // Since the allocated initial memory failed, double the memory.
+            cborLen += cbor_encoder_get_buffer_size(&encoder, encoder.end);
+            cborEncoderResult = CborNoError;
+            ret = CrlToCBORPayload(crl, payload, &cborLen, lastUpdate);
+        }
     }
 
     return ret;
@@ -807,12 +804,12 @@ void GetDerCrl(ByteArray_t* out)
         {
             OIC_LOG (ERROR, TAG, "Base64 decoding failed.");
         }
+        OICFree(out);
     }
 
     out->len = 0;
 
-    char *str = "Can't allocate memory for out->data";
-    out->data = OICMalloc(crl->len);
+    out->data = OICRealloc(out->data, crl->len);
     if (out->data)
     {
         memcpy(out->data, crl->data, crl->len);
@@ -820,7 +817,7 @@ void GetDerCrl(ByteArray_t* out)
     }
     else
     {
-        OIC_LOG_V(ERROR, TAG, "%s", str);
+        OIC_LOG(ERROR, TAG, "Can't allocate memory for out->data");
     }
     DeleteCrl(crlRes);
 }
index f7b4d14..7fa8bb2 100644 (file)
 #include "oic_malloc.h"
 #include "oic_string.h"
 #include "logger.h"
+#if defined (__TIZENRT__)
+#include <apps/netutils/cJSON.h>
+#else
 #include "cJSON.h"
+#endif
 #include "utlist.h"
 #include "ocpayload.h"
 #include "payload_logging.h"
 
 #include "srmutility.h"
 
-#ifdef __WITH_DTLS__
-#include "global.h"
-#endif
-
-
 #define TAG ("OIC_DP")
 static const uint16_t CBOR_SIZE = 1024;
 
@@ -397,12 +396,6 @@ static OCStackApplicationResult DirectPairingFinalizeHandler(void *ctx, OCDoHand
             {
                 OIC_LOG(INFO, TAG, "Fail to close temporary dtls session");
             }
-
-            caResult = CASelectCipherSuite(TLS_NULL_WITH_NULL_NULL, CA_ADAPTER_IP);
-            if(CA_STATUS_OK != caResult)
-            {
-                OIC_LOG(ERROR, TAG, "Failed to select TLS_NULL_WITH_NULL_NULL");
-            }
 #endif // __WITH_DTLS__ or __WITH_TLS__
 
             OIC_LOG(INFO, TAG, "Direct-Papring was successfully completed.");
@@ -638,7 +631,7 @@ static OCStackApplicationResult DirectPairingHandler(void *ctx, OCDoHandle UNUSE
             caresult = CAEnableAnonECDHCipherSuite(false);
             VERIFY_SUCCESS(TAG, CA_STATUS_OK == caresult, ERROR);
 
-            caresult = CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256, CA_ADAPTER_IP);
+            caresult = CASelectCipherSuite(MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, CA_ADAPTER_IP);
             VERIFY_SUCCESS(TAG, CA_STATUS_OK == caresult, ERROR);
 
             //Register proceeding peer info. & DTLS event handler to catch the dtls event while handshake
@@ -683,6 +676,8 @@ exit:
             RemoveCredential(&dpairData->peer->deviceID);
             OICFree(dpairData);
             g_dp_proceed_ctx = NULL;
+            OIC_LOG_V(INFO, TAG, "OUT DirectPairingHandler.");
+            return OC_STACK_DELETE_TRANSACTION;
         }
 
         resultCallback(dpairData->userCtx, dpairData->peer, res);
index fa210a7..43aeb54 100644 (file)
 #include <strings.h>
 #endif
 
-#ifdef __WITH_DTLS__
-#include "global.h"
-#endif
-
 #include "ocstack.h"
 #include "oic_malloc.h"
 #include "payload_logging.h"
 #include "credresource.h"
 #include "srmutility.h"
 #include "pinoxmcommon.h"
+#include "oxmverifycommon.h"
 
 #if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
 #include "pkix_interface.h"
+#include "ca_adapter_net_ssl.h"
 #endif
 
 #define TAG  "OIC_SRM_DOXM"
@@ -66,6 +64,32 @@ static const uint16_t CBOR_SIZE = 512;
 /** Max cbor size payload. */
 static const uint16_t CBOR_MAX_SIZE = 4400;
 
+#if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
+/** MAX uuid seed size */
+#define MAX_UUID_SEED_SIZE (64)
+/** MIN uuid seed size */
+#define MIN_UUID_SEED_SIZE (8)
+
+/** Buffer to save the seed of device UUID */
+static uint8_t gUuidSeed[MAX_UUID_SEED_SIZE];
+static size_t gUuidSeedSize = 0;
+#endif
+
+#ifdef MULTIPLE_OWNER
+#define MAX_SUBOWNER_SIZE (64)
+#define MIN_SUBOWNER_SIZE (1)
+#define DEFAULT_SUBOWNER_SIZE (32)
+
+static size_t gMaxSubOwnerSize = DEFAULT_SUBOWNER_SIZE;
+#endif
+
+typedef enum ConfirmState{
+    CONFIRM_STATE_READY = 0,
+    CONFIRM_STATE_WAIT = 1,
+    CONFIRM_STATE_ACCEPTED = 2,
+    CONFIRM_STATE_DENIED = 3
+}ConfirmState_t;
+
 static OicSecDoxm_t        *gDoxm = NULL;
 static OCResourceHandle    gDoxmHandle = NULL;
 
@@ -82,13 +106,17 @@ static OicSecDoxm_t gDefaultDoxm =
     {.id = {0}},            /* OicUuid_t deviceID */
     false,                  /* bool dpc */
     {.id = {0}},            /* OicUuid_t owner */
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
     NULL,                   /* OicSecSubOwner_t sub-owner list */
     NULL,                   /* OicSecMomType_t multiple owner mode */
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
     {.id = {0}},            /* OicUuid_t rownerID */
 };
 
+static uint16_t gConfirmMsgId = 0;
+static ConfirmState_t gConfirmState = CONFIRM_STATE_READY;
+
+
 /**
  * This method is internal method.
  * the param roParsed is optionally used to know whether cborPayload has
@@ -111,7 +139,7 @@ void DeleteDoxmBinData(OicSecDoxm_t* doxm)
         //clean oxm
         OICFree(doxm->oxm);
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
         //clean mom
         OICFree(doxm->mom);
 
@@ -126,7 +154,7 @@ void DeleteDoxmBinData(OicSecDoxm_t* doxm)
                 OICFree(subowner);
             }
         }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
         //Clean doxm itself
         OICFree(doxm);
@@ -240,7 +268,7 @@ OCStackResult DoxmToCBORPayload(const OicSecDoxm_t *doxm, uint8_t **payload, siz
         strUuid = NULL;
     }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
     //Device SubOwnerID -- Not Mandatory
     if(doxm->subOwners)
     {
@@ -281,7 +309,7 @@ OCStackResult DoxmToCBORPayload(const OicSecDoxm_t *doxm, uint8_t **payload, siz
         cborEncoderResult = cbor_encode_int(&doxmMap, (int64_t)doxm->mom->mode);
         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding mom Value.");
     }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
     //devownerid -- Mandatory
     cborEncoderResult = cbor_encode_text_string(&doxmMap, OIC_JSON_DEVOWNERID_NAME,
@@ -352,6 +380,7 @@ exit:
         OIC_LOG(DEBUG, TAG, "Memory getting reallocated.");
         // reallocate and try again!
         OICFree(outPayload);
+        outPayload = NULL;
         // Since the allocated initial memory failed, double the memory.
         cborLen += cbor_encoder_get_buffer_size(&encoder, encoder.end);
         OIC_LOG_V(DEBUG, TAG, "Doxm reallocation size : %zd.", cborLen);
@@ -551,7 +580,7 @@ static OCStackResult CBORPayloadToDoxmBin(const uint8_t *cborPayload, size_t siz
         memcpy(doxm->owner.id, gDoxm->owner.id, sizeof(doxm->owner.id));
     }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
     cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_MOM_NAME, &doxmMap);
     if(CborNoError == cborFindResult && cbor_value_is_integer(&doxmMap))
     {
@@ -625,7 +654,7 @@ static OCStackResult CBORPayloadToDoxmBin(const uint8_t *cborPayload, size_t siz
             LL_APPEND(doxm->subOwners, subOwnerId);
         }
     }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
     cborFindResult = cbor_value_map_find_value(&doxmCbor, OIC_JSON_ROWNERID_NAME, &doxmMap);
     if (CborNoError == cborFindResult && cbor_value_is_text_string(&doxmMap))
@@ -712,10 +741,9 @@ static bool ValidateQuery(const char * query)
     bool bDeviceIDMatch = false;    // does 'deviceid' query matches with doxm.deviceid ?
     bool bInterfaceQry = false;      // does querystring contains 'if' query ?
     bool bInterfaceMatch = false;    // does 'if' query matches with oic.if.baseline ?
-#ifdef _ENABLE_MULTIPLE_OWNER_
-    bool bMotQry = false;         // does querystring contains 'mom' and 'owned' query ?
+#ifdef MULTIPLE_OWNER
     bool bMotMatch = false;       // does 'mom' query value is not '0' && does query value matches with doxm.owned status?
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
     OicParseQueryIter_t parseIter = {.attrPos = NULL};
 
@@ -738,10 +766,9 @@ static bool ValidateQuery(const char * query)
             }
         }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
         if (strncasecmp((char *)parseIter.attrPos, OIC_JSON_MOM_NAME, strlen(OIC_JSON_MOM_NAME)) == 0)
         {
-            bMotQry = true;
             OicSecMomType_t momMode = (OicSecMomType_t)(parseIter.valPos[0] - CHAR_ZERO);
             if(NULL != gDoxm->mom && momMode != gDoxm->mom->mode)
             {
@@ -759,7 +786,7 @@ static bool ValidateQuery(const char * query)
             }
             return bMotMatch;
         }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
         if (strncasecmp((char *)parseIter.attrPos, OIC_JSON_DEVICE_ID_NAME, parseIter.attrLen) == 0)
         {
@@ -784,14 +811,8 @@ static bool ValidateQuery(const char * query)
         }
     }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
-    return ((bOwnedQry ? bOwnedMatch : true) &&
-            (bDeviceIDQry ? bDeviceIDMatch : true) &&
-            (bMotQry ? bMotMatch : true));
-#else
     return ((bOwnedQry ? bOwnedMatch : true) &&
             (bDeviceIDQry ? bDeviceIDMatch : true));
-#endif //_ENABLE_MULTIPLE_OWNER_
 }
 
 static OCEntityHandlerResult HandleDoxmGetRequest (const OCEntityHandlerRequest * ehRequest)
@@ -862,7 +883,7 @@ static void updateWriteableProperty(const OicSecDoxm_t* src, OicSecDoxm_t* dst)
             dst->owned = src->owned;
         }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
         if(src->mom)
         {
             OIC_LOG(DEBUG, TAG, "dectected 'mom' property");
@@ -875,27 +896,74 @@ static void updateWriteableProperty(const OicSecDoxm_t* src, OicSecDoxm_t* dst)
                 }
             }
         }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
     }
 }
 
 #if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
+/**
+ * Internal function to get number of sub-owner
+ */
+static size_t GetSubOwnerSize()
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+
+    size_t numberOfSubOwner = 0;
+
+    if (gDoxm && gDoxm->subOwners)
+    {
+        OicSecSubOwner_t* subowner = NULL;
+        LL_FOREACH(gDoxm->subOwners, subowner)
+        {
+            numberOfSubOwner++;
+        }
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "Numer of registered sub-owner=%d", numberOfSubOwner);
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+
+    return numberOfSubOwner;
+}
+
 /**
  * Callback function to handle MOT DTLS handshake result.
- * @param[out]   object           remote device information.
+ * @param[out]   endpoint           remote device information.
  * @param[out]   errorInfo        CA Error information.
  */
-void MultipleOwnerDTLSHandshakeCB(const CAEndpoint_t *object,
+void MultipleOwnerDTLSHandshakeCB(const CAEndpoint_t *endpoint,
                                 const CAErrorInfo_t *errorInfo)
 {
-    OIC_LOG(DEBUG, TAG, "IN MultipleOwnerDTLSHandshakeCB");
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+    if (!endpoint || !errorInfo)
+    {
+        OIC_LOG(ERROR, TAG, "Invalid param");
+        return;
+    }
+
+    if (!gDoxm)
+    {
+        OIC_LOG_V(ERROR, TAG, "%s: gDoxm is NULL", __func__);
+        return;
+    }
 
-    if(CA_STATUS_OK == errorInfo->result)
+    if ((CA_STATUS_OK == errorInfo->result) && (true == gDoxm->owned)
+        && (OIC_PRECONFIG_PIN == gDoxm->oxmSel) && (NULL != gDoxm->mom)
+        && (OIC_MULTIPLE_OWNER_DISABLE != gDoxm->mom->mode) && (CA_ADAPTER_TCP != endpoint->adapter))
     {
-        const CASecureEndpoint_t* authenticatedSubOwnerInfo = CAGetSecureEndpointData(object);
-        if(authenticatedSubOwnerInfo)
+        OIC_LOG_V(INFO, TAG, "DTLS session established for sub-owner authentication : (%s:%d)",
+                  endpoint->addr, endpoint->port);
+
+        const CASecureEndpoint_t* authenticatedSubOwnerInfo = CAGetSecureEndpointData(endpoint);
+        if (authenticatedSubOwnerInfo)
         {
+            if (0 == memcmp(authenticatedSubOwnerInfo->identity.id, gDoxm->owner.id,
+                            authenticatedSubOwnerInfo->identity.id_length))
+            {
+                OIC_LOG(WARNING, TAG, "Super owner tried MOT, this request will be ignored.");
+                return;
+            }
+
             OicSecSubOwner_t* subOwnerInst = NULL;
             LL_FOREACH(gDoxm->subOwners, subOwnerInst)
             {
@@ -907,19 +975,48 @@ void MultipleOwnerDTLSHandshakeCB(const CAEndpoint_t *object,
                 }
             }
 
-            if(NULL == subOwnerInst)
+            if (NULL == subOwnerInst)
             {
                 subOwnerInst = (OicSecSubOwner_t*)OICCalloc(1, sizeof(OicSecSubOwner_t));
-                if(subOwnerInst)
+                if (subOwnerInst)
                 {
-                    OIC_LOG(DEBUG, TAG, "Adding New SubOwner");
-                    memcpy(subOwnerInst->uuid.id, authenticatedSubOwnerInfo->identity.id,
-                           authenticatedSubOwnerInfo->identity.id_length);
-                    LL_APPEND(gDoxm->subOwners, subOwnerInst);
-                    if(!UpdatePersistentStorage(gDoxm))
+                    char* strUuid = NULL;
+                    if (OC_STACK_OK != ConvertUuidToStr(&subOwnerInst->uuid, &strUuid))
                     {
-                        OIC_LOG(ERROR, TAG, "Failed to register SubOwner UUID into Doxm");
+                        OIC_LOG(WARNING, TAG, "ConvertUuidToStr error");
                     }
+                    OIC_LOG_V(DEBUG, TAG, "Adding New SubOwner(%s)", strUuid);
+
+                    if (gMaxSubOwnerSize > GetSubOwnerSize())
+                    {
+                        memcpy(subOwnerInst->uuid.id, authenticatedSubOwnerInfo->identity.id,
+                               authenticatedSubOwnerInfo->identity.id_length);
+                        LL_APPEND(gDoxm->subOwners, subOwnerInst);
+                        if (!UpdatePersistentStorage(gDoxm))
+                        {
+                            OIC_LOG(ERROR, TAG, "Failed to register SubOwner UUID into Doxm");
+                        }
+                    }
+                    else
+                    {
+                        OIC_LOG_V(ERROR, TAG, "Number of sub-owner exceeded : (MAX SIZE=%d)", gMaxSubOwnerSize);
+
+                        //Close DTLS session
+                        if (CA_STATUS_OK != CAcloseSslSession(endpoint))
+                        {
+                            OIC_LOG_V(ERROR, TAG, "CAcloseSslSession error for [%s:%d]", endpoint->addr, endpoint->port);
+                        }
+
+                        //Remove credential
+                        if (OC_STACK_RESOURCE_DELETED != RemoveCredential(&subOwnerInst->uuid))
+                        {
+                            OIC_LOG_V(ERROR, TAG, "RemoveCredential error for [%s]", strUuid);
+                        }
+
+                        // TODO: How to send error to client side?
+                    }
+
+                    OICFree(strUuid);
                 }
             }
         }
@@ -930,9 +1027,9 @@ void MultipleOwnerDTLSHandshakeCB(const CAEndpoint_t *object,
         OIC_LOG(WARNING, TAG, "Failed to revert the DTLS credential handler");
     }
 
-    OIC_LOG(DEBUG, TAG, "OUT MultipleOwnerDTLSHandshakeCB");
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
 }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 #endif // defined(__WITH_DTLS__) || defined (__WITH_TLS__)
 
 /**
@@ -980,6 +1077,7 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe
     OCEntityHandlerResult ehRet = OC_EH_ERROR;
     OicUuid_t emptyOwner = {.id = {0} };
     static uint16_t previousMsgId = 0;
+    bool isDuplicatedMsg = false;
 
     /*
      * Convert CBOR Doxm data into binary. This will also validate
@@ -995,6 +1093,34 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe
         OCStackResult res = CBORPayloadToDoxmBin(payload, size, &newDoxm, &roParsed);
         if (newDoxm && OC_STACK_OK == res)
         {
+            /*
+             * message ID is supported for CoAP over UDP only according to RFC 7252
+             * So we should check message ID to prevent duplicate request handling in case of OC_ADAPTER_IP.
+             * In case of other transport adapter, duplicate message check is not required.
+             */
+            if (OC_ADAPTER_IP == ehRequest->devAddr.adapter &&
+                 previousMsgId == ehRequest->messageID)
+            {
+                isDuplicatedMsg = true;
+            }
+
+            if (isDuplicatedMsg && ehRequest->messageID == gConfirmMsgId)
+            {
+                if (CONFIRM_STATE_WAIT == gConfirmState)
+                {
+                    OIC_LOG(DEBUG, TAG, "Confirm callback already invoked.");
+                    OIC_LOG(DEBUG, TAG, "This request will be ignored.");
+                    DeleteDoxmBinData(newDoxm);
+                    return OC_EH_OK;
+                }
+                else
+                {
+                    OIC_LOG_V(DEBUG, TAG, "Confirm request already done, Confirm Result = %s", (CONFIRM_STATE_ACCEPTED == gConfirmState ? "ACCEPTED" : "DENIED"));
+                    ehRet = (CONFIRM_STATE_ACCEPTED == gConfirmState ? OC_EH_OK : OC_EH_NOT_ACCEPTABLE);
+                    goto exit;
+                }
+            }
+
             // Check request on RO property
             if (true == roParsed)
             {
@@ -1003,6 +1129,8 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe
                 goto exit;
             }
 
+            VERIFY_NON_NULL(TAG, gDoxm, ERROR);
+
             // in owned state
             if (true == gDoxm->owned)
             {
@@ -1016,7 +1144,7 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe
                 updateWriteableProperty(newDoxm, gDoxm);
 
 #if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
                 //handle mom
                 if(gDoxm->mom)
                 {
@@ -1029,7 +1157,7 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe
                             VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
                             OIC_LOG(INFO, TAG, "ECDH_ANON CipherSuite is DISABLED");
 
-                            caRes = CASelectCipherSuite((uint16_t)TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256, ehRequest->devAddr.adapter);
+                            caRes = CASelectCipherSuite((uint16_t)MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, ehRequest->devAddr.adapter);
                             VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
                             OIC_LOG(INFO, TAG, "ECDHE_PSK CipherSuite will be used for MOT");
 
@@ -1077,7 +1205,7 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe
                         LL_APPEND(gDoxm->subOwners, subowner);
                     }
                 }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 #endif // defined(__WITH_DTLS__) || defined (__WITH_TLS__)
 
                 //Update new state in persistent storage
@@ -1103,7 +1231,15 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe
                     goto exit;
                 }
 
-                if (OIC_JUST_WORKS == newDoxm->oxmSel)
+#if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
+                if (memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) == 0)
+                {
+                    InvokeOtmEventHandler(ehRequest->devAddr.addr, ehRequest->devAddr.port,
+                                          NULL, OIC_OTM_STARTED);
+                }
+#endif
+
+                if (OIC_JUST_WORKS == newDoxm->oxmSel || OIC_MV_JUST_WORKS == newDoxm->oxmSel)
                 {
                     /*
                      * If current state of the device is un-owned, enable
@@ -1112,6 +1248,18 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe
                      */
                     if (memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) == 0)
                     {
+                        gDoxm->oxmSel = newDoxm->oxmSel;
+                        //Update new state in persistent storage
+                        if ((UpdatePersistentStorage(gDoxm) == true))
+                        {
+                            ehRet = OC_EH_OK;
+                        }
+                        else
+                        {
+                            OIC_LOG(WARNING, TAG, "Failed to update DOXM in persistent storage");
+                            ehRet = OC_EH_ERROR;
+                            goto exit;
+                        }
                         OIC_LOG (INFO, TAG, "Doxm EntityHandle  enabling AnonECDHCipherSuite");
 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
                         ehRet = (CAEnableAnonECDHCipherSuite(true) == CA_STATUS_OK) ? OC_EH_OK : OC_EH_ERROR;
@@ -1133,6 +1281,7 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe
                         {
                             OIC_LOG(ERROR, TAG, "Failed to update DOXM in persistent storage");
                             ehRet = OC_EH_ERROR;
+                            goto exit;
                         }
 
                         /*
@@ -1144,6 +1293,59 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe
                         VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
                         OIC_LOG(INFO, TAG, "ECDH_ANON CipherSuite is DISABLED");
 
+                        //In case of Mutual Verified Just-Works, verify mutualVerifNum
+                        if (OIC_MV_JUST_WORKS == newDoxm->oxmSel && false == newDoxm->owned &&
+                            false == isDuplicatedMsg)
+                        {
+                            uint8_t preMutualVerifNum[OWNER_PSK_LENGTH_128] = {0};
+                            uint8_t mutualVerifNum[MUTUAL_VERIF_NUM_LEN] = {0};
+                            OicUuid_t deviceID = {.id = {0}};
+
+                            //Generate mutualVerifNum
+                            OCServerRequest * request = GetServerRequestUsingHandle(ehRequest->requestHandle);
+
+                            char label[LABEL_LEN] = {0};
+                            snprintf(label, LABEL_LEN, "%s%s", MUTUAL_VERIF_NUM, OXM_MV_JUST_WORKS);
+                            if (OC_STACK_OK != GetDoxmDeviceID(&deviceID))
+                            {
+                                OIC_LOG(ERROR, TAG, "Error while retrieving Owner's device ID");
+                                ehRet = OC_EH_ERROR;
+                                goto exit;
+
+                            }
+
+                            CAResult_t pskRet = CAGenerateOwnerPSK((CAEndpoint_t *)&request->devAddr,
+                                    (uint8_t *)label,
+                                    strlen(label),
+                                    gDoxm->owner.id, sizeof(gDoxm->owner.id),
+                                    gDoxm->deviceID.id, sizeof(gDoxm->deviceID.id),
+                                    preMutualVerifNum, OWNER_PSK_LENGTH_128);
+                            if (CA_STATUS_OK != pskRet)
+                            {
+                                OIC_LOG(WARNING, TAG, "Failed to remove the invaild owner credential");
+                                ehRet = OC_EH_ERROR;
+                                goto exit;
+
+                            }
+
+                            memcpy(mutualVerifNum, preMutualVerifNum + OWNER_PSK_LENGTH_128 - sizeof(mutualVerifNum),
+                                    sizeof(mutualVerifNum));
+
+                            gConfirmMsgId = ehRequest->messageID;
+                            gConfirmState = CONFIRM_STATE_WAIT;
+                            //Wait for user confirmation
+                            if (OC_STACK_OK != VerifyOwnershipTransfer(mutualVerifNum, DISPLAY_NUM | USER_CONFIRM))
+                            {
+                                ehRet = OC_EH_NOT_ACCEPTABLE;
+                                gConfirmState = CONFIRM_STATE_DENIED;
+                            }
+                            else
+                            {
+                                ehRet = OC_EH_OK;
+                                gConfirmState = CONFIRM_STATE_ACCEPTED;
+                            }
+                        }
+
 #endif // __WITH_DTLS__ or __WITH_TLS__
                     }
                 }
@@ -1175,37 +1377,14 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe
                         VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
                         OIC_LOG(INFO, TAG, "ECDH_ANON CipherSuite is DISABLED");
 
-                        caRes = CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256,
+                        caRes = CASelectCipherSuite(MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256,
                                                     ehRequest->devAddr.adapter);
                         VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
 
-                        char ranPin[OXM_RANDOM_PIN_MAX_SIZE + 1] = {0};
-                         //TODO ehRequest->messageID for copa over TCP always is null. Find reason why.
-                        if(ehRequest->devAddr.adapter == OC_ADAPTER_IP && previousMsgId != ehRequest->messageID)
-                        {
-                            if(OC_STACK_OK == GeneratePin(ranPin, sizeof(ranPin)))
-                            {
-                                //Set the device id to derive temporal PSK
-                                SetUuidForPinBasedOxm(&gDoxm->deviceID);
-
-                                /**
-                                 * Since PSK will be used directly by DTLS layer while PIN based ownership transfer,
-                                 * Credential should not be saved into SVR.
-                                 * For this reason, use a temporary get_psk_info callback to random PIN OxM.
-                                 */
-                                caRes = CAregisterPskCredentialsHandler(GetDtlsPskForRandomPinOxm);
-                                VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
-                                ehRet = OC_EH_OK;
-                            }
-                            else
-                            {
-                                OIC_LOG(ERROR, TAG, "Failed to generate random PIN");
-                                ehRet = OC_EH_ERROR;
-                            }
-                        }
-                        else if(OC_ADAPTER_TCP == ehRequest->devAddr.adapter)
+                        if (!isDuplicatedMsg)
                         {
-                            if(OC_STACK_OK == GeneratePin(ranPin, sizeof(ranPin)))
+                            char ranPin[OXM_RANDOM_PIN_MAX_SIZE + 1] = {0};
+                            if (OC_STACK_OK == GeneratePin(ranPin, sizeof(ranPin)))
                             {
                                 //Set the device id to derive temporal PSK
                                 SetUuidForPinBasedOxm(&gDoxm->deviceID);
@@ -1224,7 +1403,6 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe
                                 OIC_LOG(ERROR, TAG, "Failed to generate random PIN");
                                 ehRet = OC_EH_ERROR;
                             }
-
                         }
 #endif // __WITH_DTLS__ or __WITH_TLS__
                     }
@@ -1234,6 +1412,12 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe
                         //Save the owner's UUID to derive owner credential
                         memcpy(&(gDoxm->owner), &(newDoxm->owner), sizeof(OicUuid_t));
 
+                        // In case of random-pin based OTM, close the PIN display if callback is registered.
+                        if (!isDuplicatedMsg)
+                        {
+                            ClosePinDisplay();
+                        }
+
                         //Update new state in persistent storage
                         if (UpdatePersistentStorage(gDoxm) == true)
                         {
@@ -1248,8 +1432,28 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe
 #endif // __WITH_DTLS__ or __WITH_TLS__
                 }
 #if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
-                else if (OIC_MANUFACTURER_CERTIFICATE ==  newDoxm->oxmSel)
+                else if (OIC_MANUFACTURER_CERTIFICATE ==  newDoxm->oxmSel || OIC_CON_MFG_CERT == newDoxm->oxmSel)
                 {
+                    //Get user confirmation
+                    if (false == newDoxm->owned &&
+                        false == isDuplicatedMsg &&
+                        memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) != 0)
+                    {
+                        gConfirmMsgId = ehRequest->messageID;
+                        gConfirmState = CONFIRM_STATE_WAIT;
+                        if (OC_STACK_OK != VerifyOwnershipTransfer(NULL, USER_CONFIRM))
+                        {
+                            ehRet = OC_EH_NOT_ACCEPTABLE;
+                            gConfirmState = CONFIRM_STATE_DENIED;
+                            goto exit;
+                        }
+                        else
+                        {
+                            ehRet = OC_EH_OK;
+                            gConfirmState = CONFIRM_STATE_ACCEPTED;
+                        }
+                    }
+
                     //Save the owner's UUID to derive owner credential
                     memcpy(&(gDoxm->owner), &(newDoxm->owner), sizeof(OicUuid_t));
                     gDoxm->oxmSel = newDoxm->oxmSel;
@@ -1267,6 +1471,11 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe
                     VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
                     OIC_LOG(INFO, TAG, "ECDH_ANON CipherSuite is DISABLED");
 
+                    //Unset pre-selected ciphersuite, if any
+                    caRes = CASelectCipherSuite(0, ehRequest->devAddr.adapter);
+                    VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
+                    OIC_LOG(DEBUG, TAG, "No ciphersuite preferred");
+
                     VERIFY_SUCCESS(TAG, CA_STATUS_OK == CAregisterPkixInfoHandler(GetManufacturerPkixInfo), ERROR);
                     VERIFY_SUCCESS(TAG, CA_STATUS_OK == CAregisterGetCredentialTypesHandler(InitManufacturerCipherSuiteList), ERROR);
                 }
@@ -1306,18 +1515,6 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe
                     ehRet = OC_EH_ERROR;
                     goto exit;
                 }
-                ownerRes = SetDpairingRownerId(&gDoxm->owner);
-                if(OC_STACK_OK != ownerRes && OC_STACK_NO_RESOURCE != ownerRes)
-                {
-                    ehRet = OC_EH_ERROR;
-                    goto exit;
-                }
-                ownerRes = SetPconfRownerId(&gDoxm->owner);
-                if(OC_STACK_OK != ownerRes && OC_STACK_NO_RESOURCE != ownerRes)
-                {
-                    ehRet = OC_EH_ERROR;
-                    goto exit;
-                }
 
                 gDoxm->owned = true;
                 memcpy(&gDoxm->rownerID, &gDoxm->owner, sizeof(OicUuid_t));
@@ -1342,11 +1539,15 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe
                     ehRet = OC_EH_ERROR;
                 }
 #if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
-                if (OIC_MANUFACTURER_CERTIFICATE == gDoxm->oxmSel)
+                if (OIC_MANUFACTURER_CERTIFICATE == gDoxm->oxmSel ||
+                                            OIC_CON_MFG_CERT== gDoxm->oxmSel)
                 {
                     CAregisterPkixInfoHandler(GetPkixInfo);
                     CAregisterGetCredentialTypesHandler(InitCipherSuiteList);
                 }
+
+                InvokeOtmEventHandler(ehRequest->devAddr.addr, ehRequest->devAddr.port,
+                                      &gDoxm->owner, OIC_OTM_DONE);
 #endif // __WITH_DTLS__ or __WITH_TLS__
             }
         }
@@ -1355,7 +1556,6 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe
 exit:
     if(OC_EH_OK != ehRet)
     {
-
         /*
          * If some error is occured while ownership transfer,
          * ownership transfer related resource should be revert back to initial status.
@@ -1366,9 +1566,12 @@ exit:
             {
                 OIC_LOG(WARNING, TAG, "The operation failed during handle DOXM request");
 
-                if((OC_ADAPTER_IP == ehRequest->devAddr.adapter && previousMsgId != ehRequest->messageID)
-                   || OC_ADAPTER_TCP == ehRequest->devAddr.adapter)
+                if (!isDuplicatedMsg)
                 {
+#if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
+                    InvokeOtmEventHandler(ehRequest->devAddr.addr, ehRequest->devAddr.port,
+                                          NULL, OIC_OTM_ERROR);
+#endif
                     RestoreDoxmToInitState();
                     RestorePstatToInitState();
                     OIC_LOG(WARNING, TAG, "DOXM will be reverted.");
@@ -1380,20 +1583,92 @@ exit:
             OIC_LOG(ERROR, TAG, "Invalid DOXM resource.");
         }
     }
+
+    previousMsgId = ehRequest->messageID;
+
+#if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
+    CAEndpoint_t peer = {0};
+    OCDevAddr devAddr =  ehRequest->devAddr;
+
+    memcpy(&peer.addr, &devAddr.addr, sizeof(peer.addr));
+    peer.port = devAddr.port;
+    peer.adapter = (CATransportAdapter_t)devAddr.adapter;
+
+    if ((devAddr.flags & OC_FLAG_SECURE) && (false == CAIsExistSslPeer(&peer)))
+    {
+        OIC_LOG_V(WARNING, TAG, "Not Exist Peer");
+        ehRet = OC_EH_OK;
+    }
     else
     {
-        previousMsgId = ehRequest->messageID++;
+        //Send payload to request originator
+        ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
+            OC_EH_OK : OC_EH_ERROR;
     }
-
+#else
     //Send payload to request originator
     ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
-                   OC_EH_OK : OC_EH_ERROR;
+        OC_EH_OK : OC_EH_ERROR;
+#endif
 
     DeleteDoxmBinData(newDoxm);
 
     return ehRet;
 }
 
+#ifdef MULTIPLE_OWNER
+static OCEntityHandlerResult HandleDoxmDeleteRequest(const OCEntityHandlerRequest *ehRequest)
+{
+    OIC_LOG(DEBUG, TAG, "Processing DoxmDeleteRequest");
+
+    OCEntityHandlerResult ehRet = OC_EH_BAD_REQ;
+
+    if (NULL == ehRequest->query)
+    {
+        return ehRet;
+    }
+
+    OicParseQueryIter_t parseIter = { .attrPos=NULL };
+    OicUuid_t subject = {.id={0}};
+
+    //Parsing REST query to get the subject
+    ParseQueryIterInit((unsigned char *)ehRequest->query, &parseIter);
+    while (GetNextQuery(&parseIter))
+    {
+        if (strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBOWNERID_NAME,
+                parseIter.attrLen) == 0)
+        {
+            if (0 == strncmp((const char*)parseIter.valPos, WILDCARD_RESOURCE_URI,
+                             strlen(WILDCARD_RESOURCE_URI)))
+            {
+                if(OC_STACK_RESOURCE_DELETED == RemoveSubOwner(&WILDCARD_SUBJECT_ID))
+                {
+                    ehRet = OC_EH_RESOURCE_DELETED;
+                }
+            }
+            else
+            {
+                OCStackResult ret = ConvertStrToUuid((const char*)parseIter.valPos, &subject);
+                VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+                if(OC_STACK_RESOURCE_DELETED == RemoveSubOwner(&subject))
+                {
+                    ehRet = OC_EH_RESOURCE_DELETED;
+                }
+            }
+        }
+    }
+
+    //Send response to request originator
+    ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
+                   OC_EH_OK : OC_EH_ERROR;
+
+    return ehRet;
+exit:
+    return OC_EH_ERROR;
+}
+#endif //MULTIPLE_OWNER
+
 OCEntityHandlerResult DoxmEntityHandler(OCEntityHandlerFlag flag,
                                         OCEntityHandlerRequest * ehRequest,
                                         void* callbackParam)
@@ -1420,6 +1695,12 @@ OCEntityHandlerResult DoxmEntityHandler(OCEntityHandlerFlag flag,
                 ehRet = HandleDoxmPostRequest(ehRequest);
                 break;
 
+#ifdef MULTIPLE_OWNER
+            case OC_REST_DELETE:
+                ehRet = HandleDoxmDeleteRequest(ehRequest);
+                break;
+#endif //MULTIPLE_OWNER
+
             default:
                 ehRet = ((SendSRMResponse(ehRequest, ehRet, NULL, 0)) == OC_STACK_OK) ?
                                OC_EH_OK : OC_EH_ERROR;
@@ -1456,8 +1737,17 @@ OCStackResult CreateDoxmResource()
  */
 static OCStackResult CheckDeviceID()
 {
+    OIC_LOG_V(DEBUG, TAG, "IN: %s", __func__);
+
     OCStackResult ret = OC_STACK_ERROR;
     bool validId = false;
+
+    if (!gDoxm)
+    {
+        OIC_LOG_V(ERROR, TAG, "%s: gDoxm is NULL", __func__);
+        return OC_STACK_INVALID_PARAM;
+    }
+
     for (uint8_t i = 0; i < UUID_LENGTH; i++)
     {
         if (gDoxm->deviceID.id[i] != 0)
@@ -1469,12 +1759,64 @@ static OCStackResult CheckDeviceID()
 
     if (!validId)
     {
-        if (OCGenerateUuid(gDoxm->deviceID.id) != RAND_UUID_OK)
+        char* strUuid = NULL;
+#if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
+        //If seed value is exist, generate UUID using seed with SHA256
+        if (0 != gUuidSeedSize)
+        {
+            uint8_t hashVal[MBEDTLS_MD_MAX_SIZE] = {0};
+            mbedtls_md_context_t sha_ctx;
+            int mbedret = 1;
+
+            OIC_LOG(DEBUG, TAG, "UUID will be generated using seed w/ SHA256");
+            OIC_LOG(DEBUG, TAG, "Seed value : ");
+            OIC_LOG_BUFFER(DEBUG, TAG, gUuidSeed, gUuidSeedSize);
+
+            mbedtls_md_init( &sha_ctx );
+            mbedret = mbedtls_md_setup( &sha_ctx, mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ), 1 );
+            if (0 == mbedret)
+            {
+                mbedtls_md_starts( &sha_ctx );
+                mbedtls_md_update( &sha_ctx, gUuidSeed, gUuidSeedSize);
+                mbedtls_md_finish(&sha_ctx, (unsigned char*)hashVal);
+                memcpy(gDoxm->deviceID.id, hashVal, sizeof(gDoxm->deviceID.id));
+                ret = OC_STACK_OK;
+            }
+            else
+            {
+                OIC_LOG_V(ERROR, TAG,  "mbedtls_md_setup() returned -0x%04x\n", -mbedret);
+                ret = OC_STACK_ERROR;
+            }
+            mbedtls_md_free( &sha_ctx );
+        }
+        else
+        {
+            if (RAND_UUID_OK != OCGenerateUuid(gDoxm->deviceID.id))
+            {
+                OIC_LOG(FATAL, TAG, "Generate UUID for Server Instance failed!");
+                return OC_STACK_ERROR;
+            }
+            ret = OC_STACK_OK;
+        }
+#else
+        if (RAND_UUID_OK != OCGenerateUuid(gDoxm->deviceID.id))
         {
             OIC_LOG(FATAL, TAG, "Generate UUID for Server Instance failed!");
             return ret;
         }
         ret = OC_STACK_OK;
+#endif
+
+        if (OC_STACK_OK == ConvertUuidToStr(&gDoxm->deviceID, &strUuid))
+        {
+            OIC_LOG_V(DEBUG, TAG, "Generated device UUID is [%s]", strUuid);
+            OICFree(strUuid);
+        }
+        else
+        {
+            OIC_LOG(WARNING, TAG, "Failed to convert UUID to string");
+        }
+
 
         if (!UpdatePersistentStorage(gDoxm))
         {
@@ -1486,6 +1828,9 @@ static OCStackResult CheckDeviceID()
     {
         ret = OC_STACK_OK;
     }
+
+    OIC_LOG_V(DEBUG, TAG, "OUT: %s", __func__);
+
     return ret;
 }
 
@@ -1505,7 +1850,7 @@ const OicSecDoxm_t* GetDoxmResourceData()
     return gDoxm;
 }
 
-#if defined(__WITH_DTLS__) && defined(_ENABLE_MULTIPLE_OWNER_)
+#if defined(__WITH_DTLS__) && defined(MULTIPLE_OWNER)
 /**
  * Internal API to prepare MOT
  */
@@ -1526,10 +1871,10 @@ static void PrepareMOT(const OicSecDoxm_t* doxm)
             VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
             OIC_LOG(INFO, TAG, "ECDH_ANON CipherSuite is DISABLED");
 
-            caRes = CASelectCipherSuite((uint16_t)TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256, CA_ADAPTER_IP);
+            caRes = CASelectCipherSuite((uint16_t)MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, CA_ADAPTER_IP);
             VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
 #ifdef __WITH_TLS__
-            caRes = CASelectCipherSuite((uint16_t)TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256, CA_ADAPTER_TCP);
+            caRes = CASelectCipherSuite((uint16_t)MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, CA_ADAPTER_TCP);
             VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
 #endif
             OIC_LOG(INFO, TAG, "ECDHE_PSK CipherSuite will be used for MOT");
@@ -1551,12 +1896,15 @@ static void PrepareMOT(const OicSecDoxm_t* doxm)
 exit:
     OIC_LOG(WARNING, TAG, "Error in PrepareMOT");
 }
-#endif //defined(__WITH_DTLS__) && defined(_ENABLE_MULTIPLE_OWNER_)
+#endif //defined(__WITH_DTLS__) && defined(MULTIPLE_OWNER)
 
 OCStackResult InitDoxmResource()
 {
     OCStackResult ret = OC_STACK_ERROR;
 
+    gConfirmState = CONFIRM_STATE_READY;
+    gConfirmMsgId = 0;
+
     //Read DOXM resource from PS
     uint8_t *data = NULL;
     size_t size = 0;
@@ -1582,10 +1930,13 @@ OCStackResult InitDoxmResource()
     }
 
     //In case of the server is shut down unintentionally, we should initialize the owner
-    if(false == gDoxm->owned)
+    if(gDoxm && (false == gDoxm->owned))
     {
         OicUuid_t emptyUuid = {.id={0}};
         memcpy(&gDoxm->owner, &emptyUuid, sizeof(OicUuid_t));
+#if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
+        InvokeOtmEventHandler(NULL, 0, NULL, OIC_OTM_READY);
+#endif
     }
 
     ret = CheckDeviceID();
@@ -1601,13 +1952,13 @@ OCStackResult InitDoxmResource()
     }
     OICFree(data);
 
-#if defined(__WITH_DTLS__) && defined(_ENABLE_MULTIPLE_OWNER_)
+#if defined(__WITH_DTLS__) && defined(MULTIPLE_OWNER)
     //if MOT is enabled, MOT should be prepared.
     if(gDoxm && gDoxm->owned)
     {
         PrepareMOT(gDoxm);
     }
-#endif // defined(__WITH_DTLS__) && defined(_ENABLE_MULTIPLE_OWNER_)
+#endif // defined(__WITH_DTLS__) && defined(MULTIPLE_OWNER)
 
     return ret;
 }
@@ -1651,26 +2002,55 @@ OCStackResult GetDoxmIsOwned(bool *isOwned)
     return OC_STACK_ERROR;
 }
 
-OCStackResult SetDoxmDeviceID(const OicUuid_t *deviceID)
+#if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
+OCStackResult SetDoxmDeviceIDSeed(const uint8_t* seed, size_t seedSize)
 {
-    bool isPT = false;
+    OIC_LOG_V(INFO, TAG, "In %s", __func__);
 
-    if(NULL == deviceID)
+    if (NULL == seed)
     {
         return OC_STACK_INVALID_PARAM;
     }
-    if(NULL == gDoxm)
+    if (MAX_UUID_SEED_SIZE < seedSize)
+    {
+        OIC_LOG_V(ERROR, TAG, "Seed size is too long (MAX size is %d bytes)", MAX_UUID_SEED_SIZE);
+        return OC_STACK_INVALID_PARAM;
+    }
+    if (MIN_UUID_SEED_SIZE > seedSize)
+    {
+        OIC_LOG_V(ERROR, TAG, "Seed size is too small (MIN size is %d bytes)", MIN_UUID_SEED_SIZE);
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    memset(gUuidSeed, 0x00, sizeof(gUuidSeed));
+    memcpy(gUuidSeed, seed, seedSize);
+    gUuidSeedSize = seedSize;
+
+    OIC_LOG_V(INFO, TAG, "Out %s", __func__);
+
+    return OC_STACK_OK;
+}
+
+#endif
+
+OCStackResult SetDoxmDeviceID(const OicUuid_t *deviceID)
+{
+    bool isOwnerUpdated = false;
+    bool isRownerUpdated = false;
+    if (NULL == deviceID)
+    {
+        return OC_STACK_INVALID_PARAM;
+    }
+    if (NULL == gDoxm)
     {
         OIC_LOG(ERROR, TAG, "Doxm resource is not initialized.");
         return OC_STACK_NO_RESOURCE;
     }
 
-    //Check the device's OTM state
-
 #ifdef __WITH_DTLS__
     //for normal device.
-    if(true == gDoxm->owned &&
-       memcmp(gDoxm->deviceID.id, gDoxm->owner.id, sizeof(gDoxm->owner.id)) != 0)
+    if (true == gDoxm->owned &&
+        memcmp(gDoxm->deviceID.id, gDoxm->owner.id, sizeof(gDoxm->owner.id)) != 0)
     {
         OIC_LOG(ERROR, TAG, "This device owned by owner's device.");
         OIC_LOG(ERROR, TAG, "Device UUID cannot be changed to guarantee the reliability of the connection.");
@@ -1679,27 +2059,40 @@ OCStackResult SetDoxmDeviceID(const OicUuid_t *deviceID)
 #endif //__WITH_DTLS
 
     //Save the previous UUID
-    OicUuid_t tempUuid;
-    memcpy(tempUuid.id, gDoxm->deviceID.id, sizeof(tempUuid.id));
+    OicUuid_t prevUuid;
+    memcpy(prevUuid.id, gDoxm->deviceID.id, sizeof(prevUuid.id));
 
-    //Change the UUID
+    //Change the device UUID
     memcpy(gDoxm->deviceID.id, deviceID->id, sizeof(deviceID->id));
-    if(isPT)
+
+    //Change the owner ID if necessary
+    if (memcmp(gDoxm->owner.id, prevUuid.id, sizeof(prevUuid.id)) == 0)
     {
         memcpy(gDoxm->owner.id, deviceID->id, sizeof(deviceID->id));
+        isOwnerUpdated = true;
+    }
+    //Change the resource owner ID if necessary
+    if (memcmp(gDoxm->rownerID.id, prevUuid.id, sizeof(prevUuid.id)) == 0)
+    {
         memcpy(gDoxm->rownerID.id, deviceID->id, sizeof(deviceID->id));
+        isRownerUpdated = true;
     }
+    // TODO: T.B.D Change resource owner for pstat, acl and cred
 
     //Update PS
-    if(!UpdatePersistentStorage(gDoxm))
+    if (!UpdatePersistentStorage(gDoxm))
     {
-        //revert UUID in case of update error
-        memcpy(gDoxm->deviceID.id, tempUuid.id, sizeof(tempUuid.id));
-        if(isPT)
+        //revert UUID in case of PSI error
+        memcpy(gDoxm->deviceID.id, prevUuid.id, sizeof(prevUuid.id));
+        if (isOwnerUpdated)
+        {
+            memcpy(gDoxm->owner.id, prevUuid.id, sizeof(prevUuid.id));
+        }
+        if (isRownerUpdated)
         {
-            memcpy(gDoxm->owner.id, tempUuid.id, sizeof(tempUuid.id));
-            memcpy(gDoxm->rownerID.id, tempUuid.id, sizeof(tempUuid.id));
+            memcpy(gDoxm->rownerID.id, prevUuid.id, sizeof(prevUuid.id));
         }
+        // TODO: T.B.D Revert resource owner for pstat, acl and cred
 
         OIC_LOG(ERROR, TAG, "Failed to update persistent storage");
         return OC_STACK_ERROR;
@@ -1737,7 +2130,7 @@ OCStackResult GetDoxmRownerId(OicUuid_t *rowneruuid)
     return retVal;
 }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 /**
  * Compare the UUID to SubOwner.
  *
@@ -1749,17 +2142,22 @@ bool IsSubOwner(const OicUuid_t* uuid)
 {
     bool retVal = false;
 
-    if(NULL == uuid)
+    if (NULL == uuid)
     {
         return retVal;
     }
 
     if (gDoxm && gDoxm->subOwners)
     {
+        if (memcmp(gDoxm->owner.id, uuid->id, sizeof(gDoxm->owner.id)) == 0)
+        {
+            return false;
+        }
+
         OicSecSubOwner_t* subOwner = NULL;
         LL_FOREACH(gDoxm->subOwners, subOwner)
         {
-            if(memcmp(subOwner->uuid.id, uuid->id, sizeof(uuid->id)) == 0)
+            if (memcmp(subOwner->uuid.id, uuid->id, sizeof(uuid->id)) == 0)
             {
                 return true;
             }
@@ -1767,7 +2165,164 @@ bool IsSubOwner(const OicUuid_t* uuid)
     }
     return retVal;
 }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
+
+OCStackResult SetMOTStatus(bool enable)
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+#ifdef MULTIPLE_OWNER
+    OCStackResult ret = OC_STACK_NO_MEMORY;
+    uint8_t *cborPayload = NULL;
+    size_t size = 0;
+    bool isDeallocateRequired = false;
+
+    VERIFY_NON_NULL(TAG, gDoxm, ERROR);
+    
+    if (NULL == gDoxm->mom && !enable)
+    {
+        OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+        return OC_STACK_OK;
+    }
+
+    if (NULL == gDoxm->mom)
+    {
+        gDoxm->mom = (OicSecMom_t*)OICCalloc(1, sizeof(OicSecMom_t));
+        VERIFY_NON_NULL(TAG, gDoxm->mom, ERROR);
+        isDeallocateRequired = true;
+    }
+
+    gDoxm->mom->mode = (enable ? OIC_MULTIPLE_OWNER_ENABLE : OIC_MULTIPLE_OWNER_DISABLE);
+    gDoxm->oxmSel = OIC_PRECONFIG_PIN;
+
+    ret = DoxmToCBORPayload(gDoxm, &cborPayload, &size, false);
+    VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+    ret = UpdateSecureResourceInPS(OIC_JSON_DOXM_NAME, cborPayload, size);
+    VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+    isDeallocateRequired = false;
+
+exit:
+    if (isDeallocateRequired)
+    {
+        OICFree(gDoxm->mom);
+    }
+    if (cborPayload)
+    {
+        OICFree(cborPayload);
+    }
+    OIC_LOG_V(DEBUG, TAG, "Out %s : %d", __func__, ret);
+    return ret;
+#else
+    OC_UNUSED(enable);
+    OIC_LOG(DEBUG, TAG, "Multiple Owner is not enabled.");
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+    return OC_STACK_ERROR;
+#endif //MULTIPLE_OWNER
+}
+
+OCStackResult RemoveSubOwner(const OicUuid_t* subOwner)
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+#ifdef MULTIPLE_OWNER
+    OCStackResult ret = OC_STACK_ERROR;
+    bool isDeleted = false;
+
+    if (NULL == subOwner)
+    {
+        OIC_LOG(ERROR, TAG, "Invalid sub owner UUID.");
+        return OC_STACK_INVALID_PARAM;
+    }
+    if (NULL == gDoxm)
+    {
+        OIC_LOG(ERROR, TAG, "Doxm resource is NULL");
+        return OC_STACK_NO_RESOURCE;
+    }
+    if ( NULL == gDoxm->subOwners)
+    {
+        OIC_LOG(WARNING, TAG, "Sub Owner list is empty.");
+        return OC_STACK_ERROR;
+    }
+
+    OicSecSubOwner_t* curSubOwner = NULL;
+    OicSecSubOwner_t* tempSubOwner = NULL;
+    LL_FOREACH_SAFE(gDoxm->subOwners, curSubOwner, tempSubOwner)
+    {
+        if (memcmp(curSubOwner->uuid.id, subOwner->id, sizeof(subOwner->id)) == 0 ||
+            memcmp(WILDCARD_SUBJECT_ID.id, subOwner->id, sizeof(OicUuid_t)) == 0)
+        {
+            char* strUuid = NULL;
+            ret = ConvertUuidToStr(&curSubOwner->uuid, &strUuid);
+            if (OC_STACK_OK != ret)
+            {
+                OIC_LOG_V(ERROR, TAG, "ConvertUuidToStr error : %d", ret);
+                break;
+            }
+
+            OIC_LOG_V(INFO, TAG, "[%s] will be removed from sub owner list.", strUuid);
+            LL_DELETE(gDoxm->subOwners, curSubOwner);
+
+            //Remove the cred for sub owner
+            ret = RemoveCredential(&curSubOwner->uuid);
+            if (OC_STACK_RESOURCE_DELETED != ret)
+            {
+                OIC_LOG_V(WARNING, TAG, "RemoveCredential error for [%s] : %d", strUuid, ret);
+                break;
+            }
+
+            // TODO: Remove the ACL for sub owner (Currently ACL is not required for sub-owner)
+
+            OICFree(strUuid);
+
+            isDeleted = true;
+        }
+    }
+
+    if (isDeleted)
+    {
+        //Update persistent storage
+        if (UpdatePersistentStorage(gDoxm))
+        {
+            ret = OC_STACK_RESOURCE_DELETED;
+        }
+        else
+        {
+            OIC_LOG(ERROR, TAG, "UpdatePersistentStorage error");
+            ret = OC_STACK_ERROR;
+        }
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+    return ret;
+#else
+    OC_UNUSED(subOwner);
+    OIC_LOG(DEBUG, TAG, "Multiple Owner is not enabled.");
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+    return OC_STACK_ERROR;
+#endif //MULTIPLE_OWNER
+
+}
+
+OCStackResult SetNumberOfSubOwner(size_t numOfSubOwner)
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+#ifdef MULTIPLE_OWNER
+    if (MAX_SUBOWNER_SIZE < numOfSubOwner || MIN_SUBOWNER_SIZE > numOfSubOwner)
+    {
+        OIC_LOG_V(ERROR, TAG, "Invalid number of sub owner : %d", numOfSubOwner);
+        return OC_STACK_INVALID_PARAM;
+    }
+    gMaxSubOwnerSize = numOfSubOwner;
+    OIC_LOG_V(DEBUG, TAG, "Number of SubOwner = %d", gMaxSubOwnerSize);
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+    return OC_STACK_OK;
+#else
+    OC_UNUSED(numOfSubOwner);
+    OIC_LOG(DEBUG, TAG, "Multiple Owner is not enabled.");
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+    return OC_STACK_ERROR;
+#endif //MULTIPLE_OWNER
+}
 
 /**
  * Function to restore doxm resurce to initial status.
@@ -1775,6 +2330,10 @@ bool IsSubOwner(const OicUuid_t* uuid)
  */
 void RestoreDoxmToInitState()
 {
+
+    gConfirmState = CONFIRM_STATE_READY;
+    gConfirmMsgId = 0;
+
     if(gDoxm)
     {
         OIC_LOG(INFO, TAG, "DOXM resource will revert back to initial status.");
@@ -1790,3 +2349,38 @@ void RestoreDoxmToInitState()
         }
     }
 }
+
+OCStackResult SetDoxmSelfOwnership(const OicUuid_t* newROwner)
+{
+    OCStackResult ret = OC_STACK_ERROR;
+    uint8_t *cborPayload = NULL;
+    size_t size = 0;
+
+    if(NULL == gDoxm)
+    {
+        ret = OC_STACK_NO_RESOURCE;
+        return ret;
+    }
+
+    if( newROwner && (false == gDoxm->owned) )
+    {
+        gDoxm->owned = true;
+        memcpy(gDoxm->owner.id, newROwner->id, sizeof(newROwner->id));
+        memcpy(gDoxm->rownerID.id, newROwner->id, sizeof(newROwner->id));
+
+        ret = DoxmToCBORPayload(gDoxm, &cborPayload, &size, false);
+        VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+        ret = UpdateSecureResourceInPS(OIC_JSON_DOXM_NAME, cborPayload, size);
+        VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+        OICFree(cborPayload);
+    }
+
+    return ret;
+
+exit:
+    OICFree(cborPayload);
+    return ret;
+}
+
index fddcf7a..8f03b9a 100644 (file)
 #include "logger.h"
 #include "oic_malloc.h"
 #include "oic_string.h"
+#if defined (__TIZENRT__)
+#include <apps/netutils/cJSON.h>
+#else
 #include "cJSON.h"
+#endif
 #include "base64.h"
 #include "resourcemanager.h"
 #include "dpairingresource.h"
 #include <strings.h>
 #endif
 
-#ifdef __WITH_DTLS__
-#include "global.h"
-#endif
-
 #define TAG  "OIC_SRM_DPAIRING"
 
 /** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
@@ -254,6 +254,7 @@ exit:
     {
        // reallocate and try again!
        OICFree(outPayload);
+       outPayload = NULL;
        // Since the allocated initial memory failed, double the memory.
        cborLen += cbor_encoder_get_buffer_size(&encoder, encoder.end);
        cborEncoderResult = CborNoError;
@@ -462,7 +463,7 @@ static OCEntityHandlerResult HandleDpairingPostRequest (const OCEntityHandlerReq
 
             // Prepare to establish a secure channel with Pin-based PSK cipher suite
             if (CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false) ||
-                CA_STATUS_OK != CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256, CA_ADAPTER_IP))
+                CA_STATUS_OK != CASelectCipherSuite(MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, CA_ADAPTER_IP))
             {
                 OIC_LOG_V(ERROR, TAG, "Failed to select TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256");
                 goto exit;
@@ -548,6 +549,7 @@ static OCEntityHandlerResult HandleDpairingPutRequest (const OCEntityHandlerRequ
 
 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
         OCServerRequest *request = GetServerRequestUsingHandle(ehRequest->requestHandle);
+        VERIFY_NON_NULL(TAG, request, ERROR);
         VERIFY_SUCCESS(TAG, (request->devAddr.flags | OC_FLAG_SECURE), ERROR);
 
         //Generate new credential
index 7fff31d..ad70a43 100644 (file)
@@ -18,7 +18,9 @@
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
+#ifndef __TIZENRT__
 #include <memory.h>
+#endif
 
 #include "ocstack.h"
 #include "ocrandom.h"
@@ -40,6 +42,7 @@
 
 static GeneratePinCallback gGenPinCallback = NULL;
 static InputPinCallback gInputPinCallback = NULL;
+static ClosePinDisplayCallback gClosePinDispalyCallback = NULL;
 
 typedef struct PinOxmData {
     uint8_t pinData[OXM_RANDOM_PIN_MAX_SIZE + 1];
@@ -110,6 +113,18 @@ void SetGeneratePinCB(GeneratePinCallback pinCB)
     gGenPinCallback = pinCB;
 }
 
+void SetClosePinDisplayCB(ClosePinDisplayCallback closeCB)
+{
+    if (NULL == closeCB)
+    {
+        OIC_LOG(ERROR, TAG, "Failed to set a callback for closing a pin.");
+        return;
+    }
+
+    gClosePinDispalyCallback = closeCB;
+}
+
+
 void UnsetInputPinCB()
 {
     gInputPinCallback = NULL;
@@ -120,6 +135,19 @@ void UnsetGeneratePinCB()
     gGenPinCallback = NULL;
 }
 
+void UnsetClosePinDisplayCB()
+{
+    gClosePinDispalyCallback = NULL;
+}
+
+void ClosePinDisplay()
+{
+    if (gClosePinDispalyCallback)
+    {
+        gClosePinDispalyCallback();
+    }
+}
+
 /**
  * Internal function to generate PIN element according to pinType.
  * This function assumes the pinType is valid.
@@ -157,6 +185,10 @@ static char GenerateRandomPinElement(OicSecPinType_t pinType)
     {
         return defaultRetValue;
     }
+    else
+    {
+        curIndex -= 1;
+    }
 
     return allowedCharacters[OCGetRandomRange(0, curIndex)];
 }
@@ -241,8 +273,8 @@ OCStackResult InputPin(char* pinBuffer, size_t bufferSize)
     if(gInputPinCallback)
     {
         gInputPinCallback(pinBuffer, bufferSize);
-        OICStrcpy(g_PinOxmData.pinData, OXM_RANDOM_PIN_MAX_SIZE + 1, pinBuffer);
-        g_PinOxmData.pinSize = strlen(g_PinOxmData.pinData);
+        OICStrcpy((char*)(g_PinOxmData.pinData), OXM_RANDOM_PIN_MAX_SIZE + 1, pinBuffer);
+        g_PinOxmData.pinSize = strlen((char*)(g_PinOxmData.pinData));
     }
     else
     {
@@ -254,7 +286,7 @@ OCStackResult InputPin(char* pinBuffer, size_t bufferSize)
     return OC_STACK_OK;
 }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 OCStackResult SetPreconfigPin(const char *pinBuffer, size_t pinLength)
 {
     if(NULL == pinBuffer || OXM_PRECONFIG_PIN_MAX_SIZE < pinLength)
@@ -267,7 +299,7 @@ OCStackResult SetPreconfigPin(const char *pinBuffer, size_t pinLength)
 
     return OC_STACK_OK;
 }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
 #ifdef __WITH_DTLS__
 
@@ -354,7 +386,7 @@ int32_t GetDtlsPskForRandomPinOxm( CADtlsPskCredType_t type,
     return ret;
 }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 int32_t GetDtlsPskForMotRandomPinOxm( CADtlsPskCredType_t type,
               const unsigned char *UNUSED1, size_t UNUSED2,
               unsigned char *result, size_t result_length)
@@ -617,6 +649,6 @@ int32_t GetDtlsPskForMotPreconfPinOxm( CADtlsPskCredType_t type,
 
     return ret;
 }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
 #endif //__WITH_DTLS__
diff --git a/resource/csdk/security/src/oxmverifycommon.c b/resource/csdk/security/src/oxmverifycommon.c
new file mode 100644 (file)
index 0000000..b8470e9
--- /dev/null
@@ -0,0 +1,170 @@
+//******************************************************************
+//
+// Copyright 2016 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 "ocstack.h"
+#include "logger.h"
+#include "base64.h"
+#include "securevirtualresourcetypes.h"
+#include "srmresourcestrings.h"
+#include "cainterface.h"
+#include "oxmverifycommon.h"
+
+#define TAG "OIC_VERIFY_COMMON"
+
+static VerifyOptionBitmask_t gVerifyOption = (DISPLAY_NUM | USER_CONFIRM);
+
+static DisplayNumContext_t gDisplayNumContext = { .callback = NULL, .context = NULL };
+static UserConfirmContext_t gUserConfirmContext = { .callback = NULL, .context = NULL };
+static InputStateContext_t gInputStateContext = { .callback = NULL, .context = NULL };
+
+void SetDisplayNumCB(void * ptr, DisplayNumCallback displayNumCB)
+{
+    OIC_LOG(DEBUG, TAG, "IN SetDisplayNumCB");
+    if (NULL == displayNumCB)
+    {
+        OIC_LOG(ERROR, TAG, "Failed to set callback for displaying mutualVerifNum");
+        return;
+    }
+    gDisplayNumContext.callback = displayNumCB;
+    gDisplayNumContext.context = ptr;
+    OIC_LOG(DEBUG, TAG, "OUT SetDisplayNumCB");
+}
+
+void* UnsetDisplayNumCB()
+{
+    OIC_LOG(DEBUG, TAG, "IN UnsetDisplayNumCB");
+    void *prevctx = gDisplayNumContext.context;
+    gDisplayNumContext.callback = NULL;
+    gDisplayNumContext.context= NULL;
+    OIC_LOG(DEBUG, TAG, "OUT UnsetDisplayNumCB");
+    return prevctx;
+}
+
+void SetUserConfirmCB(void * ptr, UserConfirmCallback userConfirmCB)
+{
+    OIC_LOG(DEBUG, TAG, "IN SetUserConfirmCB");
+    if (NULL == userConfirmCB)
+    {
+        OIC_LOG(ERROR, TAG, "Failed to set callback to confirm mutualVerifNum");
+        return;
+    }
+    gUserConfirmContext.callback = userConfirmCB;
+    gUserConfirmContext.context = ptr;
+    OIC_LOG(DEBUG, TAG, "OUT SetUserConfirmCB");
+}
+
+void* UnsetUserConfirmCB()
+{
+    OIC_LOG(DEBUG, TAG, "IN UnsetUserConfirmCB");
+    void *prevctx = gUserConfirmContext.context;
+    gUserConfirmContext.callback = NULL;
+    gUserConfirmContext.context = NULL;
+    OIC_LOG(DEBUG, TAG, "OUT UnsetUserConfirmCB");
+    return prevctx;
+}
+
+void SetInputStateCB(void * ptr, InputStateCallback inputStateCB)
+{
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+    if (NULL == inputStateCB)
+    {
+        OIC_LOG(ERROR, TAG, "Failed to set callback to notify user input state");
+        return;
+    }
+    gInputStateContext.callback = inputStateCB;
+    gInputStateContext.context = ptr;
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+}
+
+void* UnsetInputStateCB()
+{
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+    void *prevctx = gInputStateContext.context;
+    gInputStateContext.callback = NULL;
+    gInputStateContext.context = NULL;
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+    return prevctx;
+}
+
+void SetVerifyOption(VerifyOptionBitmask_t verifyOption)
+{
+    OIC_LOG(DEBUG, TAG, "IN SetVerifyOption");
+    gVerifyOption = verifyOption;
+    OIC_LOG_V(DEBUG, TAG, "VerifyOption set to %d", (int) gVerifyOption);
+    OIC_LOG(DEBUG, TAG, "OUT SetVerifyOption");
+}
+
+OCStackResult VerifyOwnershipTransfer(uint8_t mutualVerifNum [MUTUAL_VERIF_NUM_LEN],
+                                    VerifyOptionBitmask_t verifyOption)
+{
+    OIC_LOG(DEBUG, TAG, "IN VerifyOwnershipTransfer");
+    OIC_LOG_V(DEBUG, TAG, "gVerifyOption: %d", (int) gVerifyOption);
+    verifyOption = (VerifyOptionBitmask_t)(verifyOption & gVerifyOption);
+    if (verifyOption & DISPLAY_NUM)
+    {
+        if (!gDisplayNumContext.callback)
+        {
+            OIC_LOG(ERROR, TAG, "Callback for displaying verification PIN not registered");
+            return OC_STACK_ERROR;
+        }
+        OIC_LOG(DEBUG, TAG, "calling displayNumCallback");
+        if (OC_STACK_OK != gDisplayNumContext.callback(gDisplayNumContext.context, mutualVerifNum))
+        {
+            OIC_LOG(ERROR, TAG, "Failed to display verification PIN");
+            return OC_STACK_ERROR;
+        }
+    }
+    if (verifyOption & USER_CONFIRM)
+    {
+        if (!gUserConfirmContext.callback)
+        {
+            OIC_LOG(ERROR, TAG, "Callback to get user confirmation not registered");
+            return OC_STACK_ERROR;
+        }
+        OIC_LOG(DEBUG, TAG, "calling userConfirmCallback");
+        if (OC_STACK_OK != gUserConfirmContext.callback(gUserConfirmContext.context))
+        {
+            OIC_LOG(ERROR, TAG, "Failed to get user confirmation");
+            return OC_STACK_USER_DENIED_REQ;
+        }
+    }
+    OIC_LOG(DEBUG, TAG, "OUT VerifyOwnershipTransfer");
+    return OC_STACK_OK;
+}
+
+OCStackResult NotifyInputState(void)
+{
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+
+    if (!gInputStateContext.callback)
+    {
+        OIC_LOG(INFO, TAG, "Callback for notifying user input state not registered");
+        return OC_STACK_OK;
+    }
+    OIC_LOG(INFO, TAG, "calling inputStateCallback");
+    if (OC_STACK_OK != gInputStateContext.callback(gInputStateContext.context))
+    {
+        OIC_LOG(ERROR, TAG, "Failed to notify user input state");
+        return OC_STACK_ERROR;
+    }
+    OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
+    return OC_STACK_OK;
+}
+
index 9bbd760..0f3da99 100644 (file)
-//******************************************************************
-//
-// 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.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+/******************************************************************
+*
+* Copyright 2016 Microsoft 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 <string.h>
-#include <math.h>
-#include "platform_features.h"
-#include "pbkdf2.h"
-#include "hmac.h"
-#include "debug.h"
 #include "logger.h"
+#include "mbedtls/pkcs5.h"
+#include "mbedtls/md.h"
 
-#define TAG "OIC_PBDKF2"
-#define XOR_BUF(in, out, bufSize)\
-do \
-{\
-    size_t i=0;\
-    for (i=0; i< (bufSize); i++)\
-    {\
-        (out)[i] = (in)[i] ^ (out)[i];\
-    }\
-} while(0)\
+#define TAG "OIC_SEC_PBDKF2"
 
-static int isLittle()
-{
-    static int a = 1;
-    static int flag = -1;
-    if (flag == -1)
-    {
-        if (  ((uint8_t *)&a)[0]  == 0x1) // little
-            flag = 1;
-        else
-            flag = 0;
-    }
-    return flag;
-}
-
-static void GetBigEndianBuf(uint8_t *buf, int num)
-{
-    uint8_t *nBuf = (uint8_t *)&num;
-    if ( isLittle() == 1 )
-    {
-        size_t i = 0;
-        for (i = 0; i < sizeof(int); i++)
-        {
-            buf[i] = nBuf[ sizeof(int) - i - 1];
-        }
-    }
-    else
-    {
-        memcpy(buf, nBuf, sizeof(int));
-    }
-}
-
-// TODO: Add comments to explain implementation.
 int DeriveCryptoKeyFromPassword(const unsigned char *passwd, size_t pLen,
-                                const uint8_t *salt, const size_t saltLen,
-                                const size_t iterations,
-                                const size_t keyLen, uint8_t *derivedKey)
+    const uint8_t *salt, const size_t saltLen,
+    const size_t iterations,
+    const size_t keyLen, uint8_t *derivedKey)
 {
-    int res = 0;
-    uint8_t buf[DTLS_HMAC_DIGEST_SIZE] = {0,};
-    uint8_t uBuf[DTLS_HMAC_DIGEST_SIZE] = {0,};
+    mbedtls_md_context_t sha_ctx;
+    const mbedtls_md_info_t *info_sha;
+    int ret = -1;
 
-    size_t nBlocks = 0;
-    size_t nOctetInLastBlock = 0;
+    /* Setup the hash/HMAC function, for the PBKDF2 function. */
+    mbedtls_md_init(&sha_ctx);
 
-    nBlocks = (size_t)ceil ((double)keyLen / (double)DTLS_HMAC_DIGEST_SIZE);
-    nOctetInLastBlock = keyLen - (nBlocks - 1) * DTLS_HMAC_DIGEST_SIZE;
-
-    dtls_hmac_context_t *ctx = NULL;
-    ctx = dtls_hmac_new( (const unsigned char *)passwd, pLen);
-    if (NULL == ctx)
+    info_sha = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
+    if (info_sha == NULL)
     {
-        OIC_LOG(ERROR, TAG, "DTLS HMAC Context is NULL");
-        goto bail;
+        OIC_LOG(ERROR, TAG, "Failed to get hash information");
+        return ret;
     }
 
-    size_t i = 1;
-    size_t idx = 0; //index for buffer
-    size_t counter = 0;
-    while (i != nBlocks + 1)
+    ret = mbedtls_md_setup(&sha_ctx, info_sha, 1);
+    if (ret != 0)
     {
-        counter = 0 ;
-        dtls_hmac_init(ctx, (const unsigned char *)passwd, pLen);
-        while (counter != iterations)
-        {
-            if (counter == 0)
-            {
-                uint8_t intBuf[4] = {0x00, 0x00, 0x00, 0x00};
-                dtls_hmac_update(ctx, salt, saltLen);
-                GetBigEndianBuf(intBuf, i);
-                dtls_hmac_update(ctx, intBuf, 4);
-
-                int len = dtls_hmac_finalize(ctx, buf);
-                if (DTLS_HMAC_DIGEST_SIZE != len)
-                {
-                    OIC_LOG(ERROR, TAG, "DTLS HMAC is failed");
-                    res = -1;
-                }
-                memcpy(uBuf, buf, DTLS_HMAC_DIGEST_SIZE);
-            }
-            else
-            {
-                dtls_hmac_init(ctx, (const unsigned char *)passwd, pLen);
-                dtls_hmac_update(ctx, buf, DTLS_HMAC_DIGEST_SIZE);
-                int len = dtls_hmac_finalize(ctx, buf);
-                if (DTLS_HMAC_DIGEST_SIZE != len)
-                {
-                    OIC_LOG(ERROR, TAG, "DTLS HMAC is failed");
-                    res = -1;
-                }
-                XOR_BUF(buf, uBuf, DTLS_HMAC_DIGEST_SIZE);
-            }
-            counter++;
-        }
-
+        OIC_LOG(ERROR, TAG, "Failed to setup hash function");
+        return ret;
+    }
 
-        if (i == nBlocks)
-        {
-            memcpy(derivedKey + idx, uBuf, nOctetInLastBlock);
-        }
-        else
-        {
-            memcpy(derivedKey + idx, uBuf, DTLS_HMAC_DIGEST_SIZE);
-            idx += DTLS_HMAC_DIGEST_SIZE;
-        }
-        i++;
+    ret = mbedtls_pkcs5_pbkdf2_hmac(&sha_ctx, passwd, pLen, salt, saltLen, iterations, keyLen, derivedKey);
+    if (ret != 0)
+    {
+        OIC_LOG(ERROR, TAG, "Call to mbedtls PBKDF2 function failed");
     }
 
-bail:
-    dtls_hmac_free(ctx);
-    return res;
+    mbedtls_md_free(&sha_ctx);
+    return ret;
 }
-
index ab89e3c..da0b9c0 100644 (file)
 #include "logger.h"
 #include "oic_malloc.h"
 #include "oic_string.h"
+#if defined (__TIZENRT__)
+#include <apps/netutils/cJSON.h>
+#else
 #include "cJSON.h"
+#endif
 #include "base64.h"
 #include "ocpayload.h"
 #include "ocpayloadcbor.h"
@@ -818,6 +822,7 @@ static OCEntityHandlerResult HandlePconfGetRequest (const OCEntityHandlerRequest
 {
     uint8_t* payload = NULL;
     size_t size = 0;
+    const OicSecDoxm_t *m_doxm = NULL;
     OCEntityHandlerResult ehRet = OC_EH_OK;
 
     OicSecPconf_t pconf;
@@ -825,7 +830,13 @@ static OCEntityHandlerResult HandlePconfGetRequest (const OCEntityHandlerRequest
 
     OIC_LOG (DEBUG, TAG, "Pconf EntityHandle processing GET request");
 
-    if (true == GetDoxmResourceData()->dpc)
+    m_doxm = GetDoxmResourceData();
+    if (NULL == m_doxm)
+    {
+      OIC_LOG (DEBUG, TAG, "Doxm resource Data is NULL");
+    }
+
+    if ((m_doxm) && (true == m_doxm->dpc))
     {
         //Making response elements for Get request
         if( (true == gPconf->edp) &&
index 7c4daaa..dc807d3 100644 (file)
-//******************************************************************
-//
-// Copyright 2016 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.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+/*****************************************************************
+ *
+ * Copyright 2016 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 "pkix_interface.h"
 #include "credresource.h"
 #include "crlresource.h"
 #include "srmresourcestrings.h"
+#include "casecurityinterface.h"
 #include "logger.h"
+#ifdef __TIZENRT__
+#include "oic_malloc.h"
+#endif
 
 #define TAG "OIC_SRM_PKIX_INTERFACE"
 
-void GetPkixInfo(PkiInfo_t * inf)
+static HWPkixContext_t gHwPkixCtx = {
+    .getHwKeyContext = NULL,
+    .freeHwKeyContext = NULL,
+    .getOwnCertCb = NULL,
+    .setupPkContextCb = NULL,
+    .hwKeyCtx = NULL
+};
+
+/*
+ * returns the number of removed zeros
+ */
+static size_t remove_useless_leading_zeros(uint8_t *asn_integer_buf, uint32_t size)
+{
+    /*
+    */
+    uint8_t buf[32 + 4];
+    uint8_t tag = asn_integer_buf[0];
+    uint8_t len = asn_integer_buf[1];
+    uint8_t *p = asn_integer_buf + 2;
+    uint32_t idx = 0;
+
+    if (size < 2)
+    {
+        return 0;
+    }
+
+    if (tag != MBEDTLS_ASN1_INTEGER)
+    {
+        return 0;
+    }
+
+    if ((uint32_t)len + 2 != size || sizeof(buf) < size)
+    {
+        return 0;
+    }
+
+    for (idx = 0; idx < (uint32_t)len - 1; idx++)
+    {
+        if (p[idx] != 0)
+        {
+            break;
+        }
+        if (p[idx] == 0 && ((p[idx + 1] & 0x80) != 0)) // 00000000 1XXXXXXXX (bit)
+        {
+            break;
+        }
+    }
+
+    if (idx == 0)
+    {
+        return 0;
+    }
+
+    len -= idx;
+    asn_integer_buf[1] = len;
+
+    memcpy(buf, p + idx, len);
+    memcpy(p, buf, len);
+
+    return idx;
+}
+
+void CheckInvalidDERSignature(uint8_t *crtBuf, size_t *crtBufLen)
 {
     OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+    if (NULL == crtBuf)
+    {
+        OIC_LOG(ERROR, TAG, "Param buf is NULL");
+        return;
+    }
+    if (NULL == crtBufLen)
+    {
+        OIC_LOG(ERROR, TAG, "Param bufLen is NULL");
+        return;
+    }
+
+    mbedtls_x509_crt deviceCert;
+    int ret = 0;
+
+    // check only first(i.e., device) certificate
+    if (crtBuf[0] == 0x30 && crtBuf[1] == 0x82)
+    {
+        uint8_t *sign_ptr = NULL;
+        /**
+        * structure of r_buf & s_buf
+        * +---------------+-------------+----------------------------+
+        * | tag (INTEGER) | length (1B) | value (r or s in integer)  |
+        * +---------------+-------------+----------------------------+
+        */
+        uint8_t r_buf[32 + 4]; // for ECC 256 sign
+        uint8_t s_buf[32 + 4];
+        uint32_t r_len = 0;
+        uint32_t s_len = 0;
+        size_t sign_len = 0;
+        uint32_t removed = 0;
+        uint32_t removed_total = 0;
+        size_t org_len = 0;
+
+        mbedtls_x509_crt_init(&deviceCert);
+
+        unsigned char * tmp = (unsigned char *)crtBuf + 1;
+        if ( 0 != mbedtls_asn1_get_len(&tmp, crtBuf + *crtBufLen, &org_len))
+        {
+            OIC_LOG(ERROR, TAG, "Invalid parsed length");
+            goto exit;
+        }
+
+        if (org_len < *crtBufLen)
+        {
+            ret = mbedtls_x509_crt_parse_der(&deviceCert, crtBuf, org_len + 4);
+            if (0 != ret)
+            {
+                OIC_LOG_V(ERROR, TAG, "mbedtls_x509_crt_parse_der returned -0x%04x", -(ret));
+                goto exit;
+            }
+
+            if (NULL == deviceCert.sig.p)
+            {
+                OIC_LOG(ERROR, TAG, "Cert's signature is NULL");
+                goto exit;
+            }
+            sign_ptr = (uint8_t*)deviceCert.sig.p;
+            ret = mbedtls_asn1_get_tag(&sign_ptr, deviceCert.sig.p + deviceCert.sig.len, &sign_len,
+                MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
+            if (0 != ret)
+            {
+                OIC_LOG_V(ERROR, TAG, "mbedtls_asn1_get_tag error : %d", ret);
+                goto exit;
+            }
+            if (sign_ptr)
+            {
+                r_len = sign_ptr[1] + 2; // including header itself
+            }
+            if (r_len > deviceCert.sig.len)
+            {
+                OIC_LOG_V(ERROR, TAG, "signature length check error #1 : %d", ret);
+                goto exit;
+            }
+            OIC_LOG_V(DEBUG, TAG, "r_len = %d", r_len);
+            memcpy(r_buf, sign_ptr, r_len);
+            removed = remove_useless_leading_zeros(r_buf, r_len);
+
+            /* Do not change order */
+            sign_ptr += r_len;
+            r_len -= removed;
+            removed_total += removed;
+            if (sign_ptr)
+            {
+                s_len = sign_ptr[1] + 2; // including header itself
+            }
+            if (s_len + r_len > deviceCert.sig.len)
+            {
+                OIC_LOG_V(ERROR, TAG, "signature length check error #2 : %d", ret);
+                goto exit;
+            }
+            OIC_LOG_V(DEBUG, TAG, "s_len = %d", s_len);
+            memcpy(s_buf, sign_ptr, s_len);
+            removed = remove_useless_leading_zeros(s_buf, s_len);
+            s_len -= removed;
+            removed_total += removed;
+
+            if (removed_total > 0)
+            {
+                // if length of signature is incorrect.
+                OIC_LOG_V(INFO, TAG, "Cert Length (Before) : %lu", *crtBufLen);
+                OIC_LOG(INFO, TAG, "Invalid length of signature is dectected.");
+                OIC_LOG(INFO, TAG, "Update signature...");
+
+                uint16_t crt_len = 0;
+                /* change bitstring length */
+                {
+                    uint8_t *sign_len_ptr = deviceCert.sig.p + 1;
+                    *sign_len_ptr -= removed_total;
+                }
+                /* change signature length */
+                {
+                    uint8_t *sign_len_ptr = deviceCert.sig.p - 1;
+                    if (*sign_len_ptr == 0)
+                    {
+                        sign_len_ptr--;
+                    }
+                    *sign_len_ptr -= removed_total;
+                }
+                /* change signature */
+                {
+                    memcpy(deviceCert.sig.p + 2, r_buf, r_len);
+                    memcpy(deviceCert.sig.p + 2 + r_len, s_buf, s_len);
+                }
+                /* change certificate length */
+                {
+                    uint8_t *crt_len_ptr = deviceCert.raw.p + 2;
+                    crt_len = (crt_len_ptr[0] << 8) & 0x0000FF00;
+                    crt_len |= (crt_len_ptr[1] & 0x000000FF);
+                    crt_len -= removed_total;
+                    crt_len_ptr[0] = (uint8_t)(crt_len >> 8);
+                    crt_len_ptr[1] = (uint8_t)(crt_len);
+                }
+                crt_len += 4; // include header and length field
+                /* change raw data and crt parse cert again */
+                {
+                    mbedtls_x509_crt crt_cpy;
+                    mbedtls_x509_crt_init( &crt_cpy );
+                    if ((ret = mbedtls_x509_crt_parse_der(&crt_cpy, deviceCert.raw.p, (size_t)crt_len)) != 0)
+                    {
+                        OIC_LOG_V(ERROR, TAG, "mbedtls_x509_crt_parse error : %d", ret);
+                        mbedtls_x509_crt_free(&crt_cpy);
+                        goto exit;
+                    }
+
+                    org_len += 4; // include header and length field
+                    size_t remained_len = (*crtBufLen - org_len);
+                    memcpy(crtBuf, deviceCert.raw.p, crt_len);
+                    memcpy(crtBuf + crt_len, crtBuf + org_len, remained_len);
+                    *crtBufLen = (size_t)crt_len + remained_len;
+
+                    mbedtls_x509_crt_free(&crt_cpy);
+                    OIC_LOG_V(INFO, TAG, "Dev cert : %lu -> %lu", org_len, crt_len);
+                    OIC_LOG_V(INFO, TAG, "Remained chain : %lu", remained_len);
+                    OIC_LOG_V(INFO, TAG, "Cert Length (After) : %lu", *crtBufLen);
+                }
+            }
+            else
+            {
+                // if length of signature is correct.
+                OIC_LOG(INFO, TAG, "Don't need to update signature...");
+            }
+
+        }
+    }
+    else
+    {
+        OIC_LOG(ERROR, TAG, "PEM or invalid cert format detected. finish to check");
+    }
+
+exit:
+    mbedtls_x509_crt_free(&deviceCert);
+    OIC_LOG_V(DEBUG, TAG, "Cert chain length = %d", *crtBufLen);
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+}
+
+/**
+ * Internal API to load the key/cert from HW PKI
+ *
+ * @return true on HW PKI is available
+ */
+static bool GetPkixInfoFromHw(PkiInfo_t * inf)
+{
+    OIC_LOG_V(INFO, TAG, "In %s", __func__);
+
+    if (!gHwPkixCtx.hwKeyCtx && gHwPkixCtx.getHwKeyContext)
+    {
+        gHwPkixCtx.hwKeyCtx = gHwPkixCtx.getHwKeyContext(
+                                                        HWKEY_SVC_IOTIVITY,
+                                                        HWKEY_USAGE_PRIMARY, NULL);
+        if (!gHwPkixCtx.hwKeyCtx)
+        {
+            OIC_LOG(WARNING, TAG, "gHwPkixCtx.getHwKeyContext return null");
+        }
+    }
+
+    if (gHwPkixCtx.hwKeyCtx && gHwPkixCtx.getOwnCertCb)
+    {
+        int ret = gHwPkixCtx.getOwnCertCb(gHwPkixCtx.hwKeyCtx, &inf->crt.data, &inf->crt.len);
+        if (0 != ret)
+        {
+            OIC_LOG_V(ERROR, TAG, "gHwPkixCtx.getOwnCertCb error : %d", ret);
+            OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+            return false;
+        }
+
+        // check and fix invalid cert signature
+        CheckInvalidDERSignature(inf->crt.data, &inf->crt.len);
+
+        OIC_LOG_V(INFO, TAG, "Cert chain length = %d", inf->crt.len);
+        OIC_LOG_V(INFO, TAG, "Out %s", __func__);
+        return true;
+    }
+    OIC_LOG_V(INFO, TAG, "Out %s", __func__);
+    return false;
+}
+
+void GetPkixInfo(PkiInfo_t * inf)
+{
+    OIC_LOG_V(INFO, TAG, "In %s", __func__);
     if (NULL == inf)
     {
         OIC_LOG(ERROR, TAG, "NULL passed");
         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
         return;
     }
-    GetDerOwnCert(&inf->crt, PRIMARY_CERT);
-    GetDerKey(&inf->key, PRIMARY_CERT);
+
+    if (GetPkixInfoFromHw(inf))
+    {
+        OIC_LOG(INFO, TAG, "H/W based PKI will be used.");
+    }
+    else
+    {
+        GetDerOwnCert(&inf->crt, PRIMARY_CERT);
+        GetDerKey(&inf->key, PRIMARY_CERT);
+    }
     GetDerCaCert(&inf->ca, TRUST_CA);
     GetDerCrl(&inf->crl);
-    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+
+    OIC_LOG_V(INFO, TAG, "Out %s", __func__);
 }
 
 void GetManufacturerPkixInfo(PkiInfo_t * inf)
 {
-    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+    OIC_LOG_V(INFO, TAG, "In %s", __func__);
     if (NULL == inf)
     {
         OIC_LOG(ERROR, TAG, "NULL passed");
         OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
         return;
     }
-    GetDerOwnCert(&inf->crt, MF_PRIMARY_CERT);
-    GetDerKey(&inf->key, MF_PRIMARY_CERT);
+
+    if (GetPkixInfoFromHw(inf))
+    {
+        OIC_LOG(INFO, TAG, "H/W based PKI will be used.");
+    }
+    else
+    {
+        GetDerOwnCert(&inf->crt, MF_PRIMARY_CERT);
+        GetDerKey(&inf->key, MF_PRIMARY_CERT);
+    }
     GetDerCaCert(&inf->ca, MF_TRUST_CA);
     // CRL not provided
+#ifdef __TIZENRT__
+    OICFree(inf->crl.data);
+#endif
     inf->crl.data = NULL;
     inf->crl.len = 0;
-    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+    OIC_LOG_V(INFO, TAG, "Out %s", __func__);
 }
 
 void InitCipherSuiteList(bool * list)
@@ -70,6 +375,10 @@ void InitCipherSuiteList(bool * list)
         return;
     }
     InitCipherSuiteListInternal(list, TRUST_CA);
+    if (gHwPkixCtx.getOwnCertCb)
+    {
+        list[1] = true;
+    }
     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
 }
 
@@ -83,5 +392,68 @@ void InitManufacturerCipherSuiteList(bool * list)
         return;
     }
     InitCipherSuiteListInternal(list, MF_TRUST_CA);
+    if (gHwPkixCtx.getOwnCertCb)
+    {
+        list[1] = true;
+    }
     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
 }
+
+int SetupHwPkContext(mbedtls_pk_context* pkCtx)
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+    if (NULL == pkCtx)
+    {
+        OIC_LOG(ERROR, TAG, "NULL passed");
+        OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+        return -1;
+    }
+
+    if (gHwPkixCtx.setupPkContextCb)
+    {
+        OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+        return gHwPkixCtx.setupPkContextCb(pkCtx, gHwPkixCtx.hwKeyCtx);
+    }
+    else
+    {
+        OIC_LOG(ERROR, TAG, "gHwPkixCallbacks.setupPkContextCb is NULL");
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+
+    return -1;
+}
+
+int SetHwPkixCallbacks(GetHwKeyContext getHwKeyContext,
+                        FreeHwKeyContext freeHwKeyContext,
+                        GetOwnCertFromHwCallback getOwnCertCb,
+                        SetupPkContextFromHwCallback setupPkContextCb)
+{
+    OIC_LOG_V(INFO, TAG, "In %s", __func__);
+
+    if (NULL == getHwKeyContext || NULL == freeHwKeyContext
+        || NULL == getOwnCertCb || NULL == setupPkContextCb)
+    {
+        OIC_LOG(ERROR, TAG, "NULL Passed");
+        OIC_LOG(ERROR, TAG, "Callback function parameters can not be null");
+        return -1;
+    }
+
+    gHwPkixCtx.getHwKeyContext = getHwKeyContext;
+    gHwPkixCtx.freeHwKeyContext = freeHwKeyContext;
+    gHwPkixCtx.getOwnCertCb = getOwnCertCb;
+    gHwPkixCtx.setupPkContextCb = setupPkContextCb;
+
+    if (gHwPkixCtx.hwKeyCtx)
+    {
+        gHwPkixCtx.freeHwKeyContext(gHwPkixCtx.hwKeyCtx);
+    }
+    gHwPkixCtx.hwKeyCtx = NULL;
+
+    // setup pkcontext handler
+    CAregisterSetupPkContextHandler(SetupHwPkContext);
+
+    OIC_LOG_V(INFO, TAG, "Out %s", __func__);
+    return 0;
+}
+
index d5ba721..e38fc38 100644 (file)
@@ -152,7 +152,7 @@ static bool IsRequestFromDevOwner(PEContext_t *context)
 }
 
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
 /**
  * Compare the request's subject to SubOwner.
  *
@@ -209,8 +209,8 @@ static bool IsValidRequestFromSubOwner(PEContext_t *context)
             }
             break;
         case OIC_R_PSTAT_TYPE:
-            //SubOwner has full permsion for PSTAT
-            isValidRequest = true;
+            //SubOwner has full permsion for PSTAT except RESET
+            isValidRequest = IsValidPstatAccessForSubOwner(context->payload, context->payloadSize);
             break;
         case OIC_R_CRED_TYPE:
             //SubOwner can only access the credential which is registered as the eowner.
@@ -237,7 +237,7 @@ static bool IsValidRequestFromSubOwner(PEContext_t *context)
 
     return isValidRequest;
 }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
 
 // TODO - remove these function placeholders as they are implemented
@@ -262,13 +262,6 @@ OCStackResult GetSaclRownerId(OicUuid_t *rowner)
     return OC_STACK_ERROR;
 }
 
-OCStackResult GetSvcRownerId(OicUuid_t *rowner)
-{
-    OC_UNUSED(rowner);
-    rowner = NULL;
-    return OC_STACK_ERROR;
-}
-
 static GetSvrRownerId_t GetSvrRownerId[OIC_SEC_SVR_TYPE_COUNT] = {
     GetAclRownerId,
     GetAmaclRownerId,
@@ -279,7 +272,6 @@ static GetSvrRownerId_t GetSvrRownerId[OIC_SEC_SVR_TYPE_COUNT] = {
     GetPconfRownerId,
     GetPstatRownerId,
     GetSaclRownerId,
-    GetSvcRownerId
 };
 
 /**
@@ -494,6 +486,17 @@ static void ProcessAccessRequest(PEContext_t *context)
         // Start out assuming subject not found.
         context->retVal = ACCESS_DENIED_SUBJECT_NOT_FOUND;
 
+        char *strUuid = NULL;
+        if (OC_STACK_OK == ConvertUuidToStr(&context->subject, &strUuid))
+        {
+            OIC_LOG_V(DEBUG, TAG, "%s: subject : %s" ,__func__, strUuid);
+            OICFree(strUuid);
+        }
+        else
+        {
+            OIC_LOG(ERROR, TAG, "Can't convert subject uuid to string");
+        }
+
         // Loop through all ACLs with a matching Subject searching for the right
         // ACL for this request.
         do
@@ -587,7 +590,13 @@ SRMAccessResponse_t CheckPermission(PEContext_t     *context,
         {
             context->retVal = ACCESS_GRANTED;
         }
-#ifdef _ENABLE_MULTIPLE_OWNER_
+        // If not granted via DevOwner status and not a subowner,
+        // then check if request is for a SVR and coming from rowner
+        else if (IsRequestFromResourceOwner(context))
+        {
+            context->retVal = ACCESS_GRANTED;
+        }
+#ifdef MULTIPLE_OWNER
         //Then check if request from SubOwner
         else if(IsRequestFromSubOwner(context))
         {
@@ -596,13 +605,7 @@ SRMAccessResponse_t CheckPermission(PEContext_t     *context,
                 context->retVal = ACCESS_GRANTED;
             }
         }
-#endif //_ENABLE_MULTIPLE_OWNER_
-        // If not granted via DevOwner status and not a subowner,
-        // then check if request is for a SVR and coming from rowner
-        else if (IsRequestFromResourceOwner(context))
-        {
-            context->retVal = ACCESS_GRANTED;
-        }
+#endif //MULTIPLE_OWNER
         // Else request is a "normal" request that must be tested against ACL
         else
         {
index 9eed75c..c24f05a 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 
 #include "cainterface.h"
 #include "logger.h"
 #include "srmresourcestrings.h"
 #include "srmutility.h"
 #include "pstatresource.h"
+#include "psiutils.h"
+#include "psinterface.h"
 #include "doxmresource.h"
+#include "octhread.h"
 
 #define TAG  "OIC_SRM_PSI"
 
-//SVR database buffer block size
+// SVR database buffer block size
 #ifdef _WIN32
 #define DB_FILE_SIZE_BLOCK 1023
 #else
 const size_t DB_FILE_SIZE_BLOCK = 1023;
 #endif
+//the Secure Virtual Database file size
+static size_t g_svrDbFileSize = 0;
+//mutex for the Secure Virtual Database
+static oc_mutex g_mutexDb = NULL;
+
+// Persistent Storage status
+static PSStatus_t g_psStatus = PS_NO_EXTERNAL_DB_SET;
+
+/**
+ * Update the Persistent Storage Database size.
+ */
+void UpdateSizePSI(size_t size)
+{
+    oc_mutex_lock(g_mutexDb);
+    g_svrDbFileSize = size;
+    oc_mutex_unlock(g_mutexDb);
+}
+/**
+ * Init the Persistent Storage Database.
+ */
+OCStackResult InitPersistentStorageInterface(void)
+{
+    if (!g_mutexDb)
+    {
+        g_mutexDb = oc_mutex_new();
+        if(!g_mutexDb)
+        {
+            return OC_STACK_ERROR;
+        }
+    }
+
+    UpdateSizePSI(0);
+
+    return OC_STACK_OK;
+}
 
 /**
- * Gets the Secure Virtual Database size
+ * DeInit the Persistent Storage Database.
+ */
+void DeinitPersistentStorageInterface(void)
+{
+    g_svrDbFileSize = 0;
+    oc_mutex_free(g_mutexDb);
+    g_mutexDb = NULL;
+}
+
+/**
+ * Gets the database size
  *
- * @param ps - pointer of OCPersistentStorage for the Secure Virtual Resource(s)
+ * @param ps            is a pointer to OCPersistentStorage for the Virtual Resource(s).
  *
- * @return size_t - total size of the SVR database
+ * @return size_t - total size of the database
  */
-static size_t GetSVRDatabaseSize(const OCPersistentStorage *ps)
+static size_t GetPSIDatabaseSizeWithoutCaching(const OCPersistentStorage *ps)
 {
     if (!ps)
     {
@@ -78,6 +127,428 @@ static size_t GetSVRDatabaseSize(const OCPersistentStorage *ps)
     return size;
 }
 
+
+/**
+ * Gets the the Persistent Storage Database size
+ *
+ * @param ps - pointer of OCPersistentStorage for the Secure Virtual Resource(s)
+ *
+ * @return size_t - total size of the SVR database
+ */
+static size_t GetPSIDatabaseSize(const OCPersistentStorage *ps)
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+
+    if (!ps)
+    {
+        return 0;
+    }
+
+    if (!g_svrDbFileSize)
+    {
+        size_t size = 0;
+        char buffer[DB_FILE_SIZE_BLOCK];  // can not initialize with declaration
+                                          // but maybe not needed to initialize
+        FILE *fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb");
+        if (fp)
+        {
+            size_t bytesRead = 0;
+            do
+            {
+                bytesRead = ps->read(buffer, 1, DB_FILE_SIZE_BLOCK, fp);
+                size += bytesRead;
+            } while (bytesRead);
+            ps->close(fp);
+        }
+        else
+        {
+            OIC_LOG_V(ERROR, TAG, "%s: File open failed.", __func__);
+        }
+
+        UpdateSizePSI(size);
+    }
+    else
+    {
+        OIC_LOG_V(INFO, TAG, "%s get size from cache", __func__);
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+
+    return g_svrDbFileSize;
+}
+
+#ifdef __SECURE_PSI__
+static OCStackResult getPlaintextFromDB(const OCPersistentStorage *ps, uint8_t **pt,
+        size_t *pt_len)
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+    OCStackResult ret = OC_STACK_ERROR;
+
+    uint8_t *plaintext = NULL;
+
+    FILE *fp = NULL;
+    fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb");
+    if (NULL == fp)
+    {
+        OIC_LOG(ERROR, TAG, "ps->open() Failed");
+        return OC_STACK_ERROR;
+    }
+
+    // Get fileSize of plaintext
+    char buffer[DB_FILE_SIZE_BLOCK];
+    size_t bytesRead = 0;
+    size_t fileSize = 0;
+    do
+    {
+        bytesRead = ps->read(buffer, 1, DB_FILE_SIZE_BLOCK, fp);
+        fileSize += bytesRead;
+    } while (bytesRead);
+
+    // Get plaintext
+    ret = OC_STACK_NO_MEMORY;
+    plaintext = (uint8_t*)OICCalloc(1, fileSize);
+    VERIFY_NON_NULL(TAG, plaintext, ERROR);
+
+    ps->close(fp);
+    fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb");
+    if (NULL == fp)
+    {
+        OIC_LOG(ERROR, TAG, "ps->open() Failed");
+        return OC_STACK_ERROR;
+    }
+
+    if (fileSize != ps->read(plaintext, 1, fileSize, fp))
+    {
+        OIC_LOG_V(ERROR, TAG, "ps->read() Failed");
+        ret = OC_STACK_ERROR;
+        goto exit;
+    }
+
+    *pt = plaintext;
+    *pt_len = fileSize;
+    ps->close(fp);
+
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+
+    return OC_STACK_OK;
+exit:
+    OICFree(plaintext);
+    if (fp)
+    {
+        ps->close(fp);
+    }
+    return ret;
+}
+
+static OCStackResult OTEncrypt(const OCPersistentStorage *psForPlain,
+        const OCPersistentStorage *psForEncrypted)
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+
+    uint8_t *plaintext = NULL;
+    size_t pt_len = 0;
+    OCStackResult ret = getPlaintextFromDB(psForPlain, &plaintext, &pt_len);
+    if (OC_STACK_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "getPlaintextFromDB() Failed");
+        return ret;
+    }
+
+    // Encrypt plaintext
+    uint8_t *ciphertext = NULL;
+    size_t ct_len = 0;
+    if (0 != psForEncrypted->encrypt(plaintext, pt_len, &ciphertext, &ct_len))
+    {
+        OIC_LOG(ERROR, TAG, "psForEncrypted->encrypt() Failed");
+        OICFree(plaintext);
+        return OC_STACK_ERROR;
+    }
+    OICFree(plaintext);
+
+    // Write Ciphertext
+    FILE *fp2 = psForEncrypted->open(SVR_DB_DAT_FILE_NAME, "wb");
+    if (NULL == fp2)
+    {
+        OIC_LOG(ERROR, TAG, "psForEncrypted->open() Failed");
+        OICFree(ciphertext);
+        return OC_STACK_ERROR;
+    }
+
+    if (ct_len != psForEncrypted->write(ciphertext, 1, ct_len, fp2))
+    {
+        OIC_LOG(ERROR, TAG, "psForEncrypted->write() Failed");
+        OICFree(ciphertext);
+        return OC_STACK_ERROR;
+    }
+    psForEncrypted->close(fp2);
+
+    // Remove plain DB
+    if (psForPlain->unlink)
+    {
+        psForPlain->unlink(SVR_DB_DAT_FILE_NAME);
+    }
+
+    OICFree(ciphertext);
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+
+    return OC_STACK_OK;
+}
+
+OCStackResult setSecurePSI(const unsigned char *key, const OCPersistentStorage *psPlain,
+        const OCPersistentStorage *psEnc, const OCPersistentStorage *psRescue)
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+
+    if (!key || !psEnc)
+    {
+        OIC_LOG_V(ERROR, TAG, "%s: %s is NULL", __func__, !key ? "key" : "psEnc");
+        return OC_STACK_INVALID_PARAM;
+    }
+    if (!(psEnc->encrypt && psEnc->decrypt))
+    {
+        OIC_LOG(ERROR, TAG, "psEnc->encrypt && psEnc->decrypt should be set");
+        return OC_STACK_INVALID_PARAM;
+    }
+    if (psPlain && !(psPlain->open && psPlain->read && psPlain->close
+                && psPlain->unlink))
+    {
+        OIC_LOG(ERROR, TAG, "open/read/close/unlink funcion for plain should be set");
+        return OC_STACK_INVALID_PARAM;
+    }
+    if (psRescue && !(psRescue->open && psRescue->read && psRescue->close))
+    {
+        OIC_LOG(ERROR, TAG, "open/read/close funcion for rescue should be set");
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    OCStackResult ret;
+    ret = psiSetKey(key);
+    if (OC_STACK_OK != ret)
+    {
+        OIC_LOG(ERROR, TAG, "psiSetKey() Failed");
+        return ret;
+    }
+    OIC_LOG(DEBUG, TAG, "key is set");
+
+    // if there is new plain db
+    FILE *fp = NULL;
+    if (psPlain && (fp = psPlain->open(SVR_DB_DAT_FILE_NAME, "rb")))
+    {
+        psPlain->close(fp);
+        fp = NULL;
+
+        ret = OTEncrypt(psPlain, psEnc);
+        if (OC_STACK_OK != ret)
+        {
+            OIC_LOG(ERROR, TAG, "OTEncrypt() Failed");
+            return ret;
+        }
+    }
+
+    // check ps & rescue
+    if (psRescue)
+    {
+        ret = CheckPersistentStorage((OCPersistentStorage*)psEnc);
+        if (OC_STACK_OK != ret)
+        {
+            fp = psRescue->open(SVR_DB_DAT_FILE_NAME, "rb");
+            if (NULL == fp)
+            {
+                OIC_LOG(ERROR, TAG, "psRescue->open() Failed");
+                return OC_STACK_ERROR;
+            }
+            psRescue->close(fp);
+            fp = NULL;
+
+            ret = OTEncrypt(psRescue, psEnc);
+            if (OC_STACK_OK != ret)
+            {
+                OIC_LOG_V(ERROR, TAG, "ps is currupted but NOT rescued(%d)", ret);
+                return ret;
+            }
+            OIC_LOG(INFO, TAG, "ps is currupted and rescued");
+        }
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+
+    return OC_STACK_OK;
+
+}
+#endif // __SECURE_PSI__
+
+/**
+ * Write the Persistent Storage
+ *
+ * @param payload - pointer of payload
+ * @param psize   - size of payload
+ *
+ * @return OCStackResult - OC_STACK_OK sucsess, other - OC_STACK_ERROR
+ */
+OCStackResult WritePSIDatabase(const uint8_t *payload, size_t size)
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+
+    if (!payload || !size || !g_mutexDb)
+    {
+        OIC_LOG_V(ERROR, TAG, "%s: %s is NULL",
+                   __func__, !payload ? "payload" : !size ? "size" : "mutex");
+        OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    OCPersistentStorage *ps = NULL;
+    FILE *fp = NULL;
+    OCStackResult ret = OC_STACK_SVR_DB_NOT_EXIST;
+
+    ps = SRMGetPersistentStorageHandler();
+    VERIFY_NON_NULL(TAG, ps, ERROR);
+
+#ifdef __SECURE_PSI__
+    if (psiIsKeySet() && ps->encrypt && ps->decrypt)
+    {
+        OIC_LOG(DEBUG, TAG, "ps->encrypt !");
+
+        uint8_t *ciphertext = NULL;
+        size_t ct_len = 0;
+
+        if (0 != ps->encrypt(payload, size, &ciphertext, &ct_len))
+        {
+            OIC_LOG(ERROR, TAG, "ps->encrypt() Failed");
+            ret = OC_STACK_ERROR;
+            goto exit;
+        }
+
+        payload = ciphertext;
+        size = ct_len;
+    }
+#endif // __SECURE_PSI__
+
+    OIC_LOG_V(INFO, TAG, "Writing in the file: %zu", size);
+
+    fp = ps->open(SVR_DB_DAT_FILE_NAME, "wb");
+    VERIFY_NON_NULL(TAG, fp, ERROR);
+
+    oc_mutex_lock(g_mutexDb);
+    g_svrDbFileSize = ps->write(payload, 1, size, fp);
+    ps->close(fp);
+    oc_mutex_unlock(g_mutexDb);
+
+#ifdef __SECURE_PSI__
+    if (psiIsKeySet() && ps->encrypt && ps->decrypt)
+    {
+        OICFree((uint8_t*)payload);
+    }
+#endif // __SECURE_PSI__
+    if (size == g_svrDbFileSize)
+    {
+        OIC_LOG_V(INFO, TAG, "Written %zu bytes into SVR database file", size);
+        ret = OC_STACK_OK;
+    }
+    else
+    {
+        OIC_LOG_V(ERROR, TAG, "Failed writing %zu in the database", g_svrDbFileSize);
+    }
+
+exit:
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+    return ret;
+}
+
+/**
+ * Gets the Secure Virtual Database from the Persistent Storage
+ *
+ * @param ps - Persistent Storage handler
+ * @param rsrcName - pointer of character string for the SVR name (e.g. "acl")
+ * @param data - pointer of the returned Secure Virtual Resource(s)
+ * @param size - pointer of the returned size of Secure Virtual Resource(s)
+ *
+ * @return OCStackResult - result of getting Secure Virtual Resource(s)
+ */
+OCStackResult GetSecureVirtualDatabaseFromPS2(OCPersistentStorage* ps, const char *rsrcName, uint8_t **data, size_t *size)
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+
+    if (!data || *data || !size || !ps)
+    {
+        OIC_LOG_V(ERROR, TAG, "%s: %s is NULL",
+                   __func__, !data || *data ? "data" : !size ? "size" : "ps");
+        OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+        return OC_STACK_INVALID_PARAM;
+    }
+
+    FILE *fp = NULL;
+    uint8_t *fsData = NULL;
+    size_t fileSize = 0;
+    OCStackResult ret = OC_STACK_ERROR;
+
+    fileSize = GetPSIDatabaseSizeWithoutCaching(ps);
+    OIC_LOG_V(INFO, TAG, "File Read Size: %zu", fileSize);
+    if (fileSize)
+    {
+        fsData = (uint8_t *) OICCalloc(1, fileSize + 1);
+        VERIFY_NON_NULL(TAG, fsData, ERROR);
+
+        fp = ps->open(SVR_DB_DAT_FILE_NAME, "rb");
+        VERIFY_NON_NULL(TAG, fp, ERROR);
+        if (ps->read(fsData, 1, fileSize, fp) == fileSize)
+        {
+#ifdef __SECURE_PSI__
+            if (psiIsKeySet() && ps->encrypt && ps->decrypt)
+            {
+                OIC_LOG(DEBUG, TAG, "ps->decrypt !");
+
+                unsigned char *plainData = NULL;
+                size_t plainSize = 0;
+
+                if (0 != ps->decrypt(fsData, fileSize, &plainData, &plainSize))
+                {
+                    OIC_LOG(ERROR, TAG, "ps->decrypt() Failed");
+                    ret = OC_STACK_ERROR;
+                    goto exit;
+                }
+                OICFree(fsData);
+                fsData = plainData;
+                fileSize = plainSize;
+            }
+#endif // __SECURE_PSI__
+            if (rsrcName)
+            {
+                CborParser parser;  // will be initialized in |cbor_parser_init|
+                CborValue cbor;     // will be initialized in |cbor_parser_init|
+                cbor_parser_init(fsData, fileSize, 0, &parser, &cbor);
+                CborValue cborValue = {0};
+                CborError cborFindResult = cbor_value_map_find_value(&cbor, rsrcName, &cborValue);
+                if (CborNoError == cborFindResult && cbor_value_is_byte_string(&cborValue))
+                {
+                    cborFindResult = cbor_value_dup_byte_string(&cborValue, data, size, NULL);
+                    VERIFY_SUCCESS(TAG, CborNoError==cborFindResult, ERROR);
+                    ret = OC_STACK_OK;
+                }
+                // in case of |else (...)|, svr_data not found
+            }
+            // return everything in case rsrcName is NULL
+            else
+            {
+                *size = fileSize;
+                *data = (uint8_t *) OICCalloc(1, fileSize);
+                VERIFY_NON_NULL(TAG, *data, ERROR);
+                memcpy(*data, fsData, fileSize);
+                ret = OC_STACK_OK;
+            }
+        }
+    }
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+
+exit:
+    if (fp)
+    {
+        ps->close(fp);
+    }
+    OICFree(fsData);
+    return ret;
+}
+
 /**
  * Gets the Secure Virtual Database from the Persistent Storage
  *
@@ -89,9 +560,16 @@ static size_t GetSVRDatabaseSize(const OCPersistentStorage *ps)
  */
 OCStackResult GetSecureVirtualDatabaseFromPS(const char *rsrcName, uint8_t **data, size_t *size)
 {
-    OIC_LOG(DEBUG, TAG, "GetSecureVirtualDatabaseFromPS IN");
-    if (!data || *data || !size)
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+
+    // Logs for Persistent Storage status
+    PrintPSStatus();
+
+    if (!data || *data || !size || !g_mutexDb)
     {
+        OIC_LOG_V(ERROR, TAG, "%s: %s is NULL",
+                   __func__, !data || *data ? "data" : !size ? "size" : "mutex");
+        OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
         return OC_STACK_INVALID_PARAM;
     }
 
@@ -103,8 +581,8 @@ OCStackResult GetSecureVirtualDatabaseFromPS(const char *rsrcName, uint8_t **dat
     OCPersistentStorage *ps = SRMGetPersistentStorageHandler();
     VERIFY_NON_NULL(TAG, ps, ERROR);
 
-    fileSize = GetSVRDatabaseSize(ps);
-    OIC_LOG_V(DEBUG, TAG, "File Read Size: %zu", fileSize);
+    fileSize = GetPSIDatabaseSize(ps);
+    OIC_LOG_V(INFO, TAG, "File Read Size: %zu", fileSize);
     if (fileSize)
     {
         fsData = (uint8_t *) OICCalloc(1, fileSize);
@@ -114,6 +592,25 @@ OCStackResult GetSecureVirtualDatabaseFromPS(const char *rsrcName, uint8_t **dat
         VERIFY_NON_NULL(TAG, fp, ERROR);
         if (ps->read(fsData, 1, fileSize, fp) == fileSize)
         {
+#ifdef __SECURE_PSI__
+            if (psiIsKeySet() && ps->encrypt && ps->decrypt)
+            {
+                OIC_LOG(DEBUG, TAG, "ps->decrypt !");
+
+                unsigned char *plainData = NULL;
+                size_t plainSize = 0;
+
+                if (0 != ps->decrypt(fsData, fileSize, &plainData, &plainSize))
+                {
+                    OIC_LOG(ERROR, TAG, "ps->decrypt() Failed");
+                    ret = OC_STACK_ERROR;
+                    goto exit;
+                }
+                OICFree(fsData);
+                fsData = plainData;
+                fileSize = plainSize;
+            }
+#endif // __SECURE_PSI__
             if (rsrcName)
             {
                 CborParser parser;  // will be initialized in |cbor_parser_init|
@@ -140,7 +637,7 @@ OCStackResult GetSecureVirtualDatabaseFromPS(const char *rsrcName, uint8_t **dat
             }
         }
     }
-    OIC_LOG(DEBUG, TAG, "GetSecureVirtualDatabaseFromPS OUT");
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
 
 exit:
     if (fp)
@@ -164,7 +661,8 @@ exit:
  */
 OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPayload, size_t psSize)
 {
-    OIC_LOG(DEBUG, TAG, "UpdateSecureResourceInPS IN");
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+
     if (!rsrcName)
     {
         return OC_STACK_INVALID_PARAM;
@@ -179,7 +677,6 @@ OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPa
     uint8_t *pstatCbor = NULL;
     uint8_t *doxmCbor = NULL;
     uint8_t *amaclCbor = NULL;
-    uint8_t *svcCbor = NULL;
     uint8_t *credCbor = NULL;
     uint8_t *pconfCbor = NULL;
     uint8_t *resetPfCbor = NULL;
@@ -187,18 +684,23 @@ OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPa
 
     int64_t cborEncoderResult = CborNoError;
     OCStackResult ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
+    if (OC_STACK_OK != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "GetSecureVirtualDatabaseFromPS() is failed(%d)", ret);
+    }
     if (dbData && dbSize)
     {
         size_t aclCborLen = 0;
         size_t pstatCborLen = 0;
         size_t doxmCborLen = 0;
         size_t amaclCborLen = 0;
-        size_t svcCborLen = 0;
         size_t credCborLen = 0;
         size_t pconfCborLen = 0;
         size_t resetPfCborLen = 0;
         size_t crlCborLen = 0;
 
+        ret = OC_STACK_ERROR;
+
         // Gets each secure virtual resource from persistent storage
         // this local scoping intended, for destroying large cbor instances after use
         {
@@ -232,12 +734,7 @@ OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPa
                 cborFindResult = cbor_value_dup_byte_string(&curVal, &amaclCbor, &amaclCborLen, NULL);
                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding AMACL Name Value.");
             }
-            cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_SVC_NAME, &curVal);
-            if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
-            {
-                cborFindResult = cbor_value_dup_byte_string(&curVal, &svcCbor, &svcCborLen, NULL);
-                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding SVC Name Value.");
-            }
+
             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRED_NAME, &curVal);
             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
             {
@@ -275,7 +772,7 @@ OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPa
         // this local scoping intended, for destroying large cbor instances after use
         {
             size_t size = aclCborLen + pstatCborLen + doxmCborLen + amaclCborLen
-                        + svcCborLen + credCborLen + pconfCborLen + resetPfCborLen + crlCborLen
+                        + credCborLen + pconfCborLen + resetPfCborLen + crlCborLen
                         + psSize + 255;
             // This added '255' is arbitrary value that is added to cover the name of the resource, map addition and ending
 
@@ -322,13 +819,6 @@ OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPa
                 cborEncoderResult |= cbor_encode_byte_string(&secRsrc, amaclCbor, amaclCborLen);
                 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Amacl Value.");
             }
-            if (strcmp(OIC_JSON_SVC_NAME, rsrcName) && svcCborLen)
-            {
-                cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_SVC_NAME, strlen(OIC_JSON_SVC_NAME));
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SVC Name.");
-                cborEncoderResult |= cbor_encode_byte_string(&secRsrc, svcCbor, svcCborLen);
-                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SVC Value.");
-            }
             if (strcmp(OIC_JSON_CRED_NAME, rsrcName) && credCborLen)
             {
                 cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRED_NAME, strlen(OIC_JSON_CRED_NAME));
@@ -386,35 +876,12 @@ OCStackResult UpdateSecureResourceInPS(const char *rsrcName, const uint8_t *psPa
         outSize = cbor_encoder_get_buffer_size(&encoder, outPayload);
     }
 
-    if (outPayload && outSize)
+    ret = WritePSIDatabase(outPayload, outSize);
+    if (OC_STACK_OK != ret)
     {
-        OIC_LOG_V(DEBUG, TAG, "Writing in the file: %zu", outSize);
-        OCPersistentStorage* ps = SRMGetPersistentStorageHandler();
-        if (ps)
-        {
-            FILE *fp = ps->open(SVR_DB_DAT_FILE_NAME, "wb");
-            if (fp)
-            {
-                size_t numberItems = ps->write(outPayload, 1, outSize, fp);
-                if (outSize == numberItems)
-                {
-                    OIC_LOG_V(DEBUG, TAG, "Written %zu bytes into SVR database file", outSize);
-                    ret = OC_STACK_OK;
-                }
-                else
-                {
-                    OIC_LOG_V(ERROR, TAG, "Failed writing %zu in the database", numberItems);
-                }
-                ps->close(fp);
-            }
-            else
-            {
-                OIC_LOG(ERROR, TAG, "File open failed.");
-            }
-        }
+        OIC_LOG_V(ERROR, TAG, "WritePSIDatabase() is failed(%d)", ret);
     }
-
-    OIC_LOG(DEBUG, TAG, "UpdateSecureResourceInPS OUT");
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
 
 exit:
     OICFree(dbData);
@@ -423,7 +890,6 @@ exit:
     OICFree(pstatCbor);
     OICFree(doxmCbor);
     OICFree(amaclCbor);
-    OICFree(svcCbor);
     OICFree(credCbor);
     OICFree(pconfCbor);
     OICFree(resetPfCbor);
@@ -440,7 +906,7 @@ exit:
  */
 OCStackResult ResetSecureResourceInPS(void)
 {
-    OIC_LOG(DEBUG, TAG, "ResetSecureResourceInPS IN");
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
 
     size_t dbSize = 0;
     size_t outSize = 0;
@@ -448,20 +914,27 @@ OCStackResult ResetSecureResourceInPS(void)
     uint8_t *outPayload = NULL;
 
     uint8_t *aclCbor = NULL;
+    uint8_t *credCbor = NULL;
     uint8_t *pstatCbor = NULL;
     uint8_t *doxmCbor = NULL;
     uint8_t *resetPfCbor = NULL;
 
     int64_t cborEncoderResult = CborNoError;
     OCStackResult ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
-
+    if (OC_STACK_OK != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "GetSecureVirtualDatabaseFromPS() is failed(%d)", ret);
+    }
     if(dbData && dbSize)
     {
         size_t aclCborLen = 0;
+        size_t credCborLen = 0;
         size_t pstatCborLen = 0;
         size_t doxmCborLen = 0;
         size_t resetPfCborLen = 0;
 
+        ret = OC_STACK_ERROR;
+
         // Gets the reset profile from persistent storage
         {
             CborParser parser;  // will be initialized in |cbor_parser_init|
@@ -475,6 +948,17 @@ OCStackResult ResetSecureResourceInPS(void)
                 cborFindResult = cbor_value_dup_byte_string(&curVal, &resetPfCbor, &resetPfCborLen, NULL);
                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Reset Profile Name Value.");
             }
+            else if (CborNoError == cborFindResult && CborInvalidType == curVal.type)
+            {
+                OIC_LOG(ERROR, TAG, "resetpf is not found");
+                goto exit;
+            }
+            else
+            {
+                OIC_LOG_V(ERROR, TAG, "cbor_value_map_find_value() Failed(%d)",
+                        cborFindResult);
+                goto exit;
+            }
         }
 
         // Gets each secure virtual resource from the reset profile
@@ -490,6 +974,12 @@ OCStackResult ResetSecureResourceInPS(void)
                 cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL);
                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
             }
+            cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRED_NAME, &curVal);
+            if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
+            {
+                cborFindResult = cbor_value_dup_byte_string(&curVal, &credCbor, &credCborLen, NULL);
+                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
+            }
             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal);
             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
             {
@@ -505,7 +995,7 @@ OCStackResult ResetSecureResourceInPS(void)
         }
 
         {
-            size_t size = aclCborLen + pstatCborLen + doxmCborLen + resetPfCborLen + 255;
+            size_t size = aclCborLen + credCborLen + pstatCborLen + doxmCborLen + resetPfCborLen + 255;
             // This added '255' is arbitrary value added to cover the name of the resource, map addition, and ending
 
             outPayload = (uint8_t *) OICCalloc(1, size);
@@ -520,6 +1010,14 @@ OCStackResult ResetSecureResourceInPS(void)
             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen);
             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value.");
 
+            if (credCborLen)
+            {
+                cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRED_NAME, strlen(OIC_JSON_CRED_NAME));
+                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CRED Name.");
+                cborEncoderResult |= cbor_encode_byte_string(&secRsrc, credCbor, credCborLen);
+                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CRED Value.");
+            }
+
             cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME));
             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name.");
             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen);
@@ -540,44 +1038,22 @@ OCStackResult ResetSecureResourceInPS(void)
             outSize = cbor_encoder_get_buffer_size(&encoder, outPayload);
         }
 
-        if (outPayload && outSize)
+        ret = WritePSIDatabase(outPayload, outSize);
+        if (OC_STACK_OK != ret)
         {
-            OIC_LOG_V(DEBUG, TAG, "Writing in the file: %zu", outSize);
-            OCPersistentStorage *ps = SRMGetPersistentStorageHandler();
-            if (ps)
-            {
-                FILE *fp = ps->open(SVR_DB_DAT_FILE_NAME, "wb");
-                if (fp)
-                {
-                    size_t numberItems = ps->write(outPayload, 1, outSize, fp);
-                    if (outSize == numberItems)
-                    {
-                        OIC_LOG_V(DEBUG, TAG, "Written %zu bytes into SVR database file", outSize);
-                        ret= OC_STACK_OK;
-                    }
-                    else
-                    {
-                        OIC_LOG_V(ERROR, TAG, "Failed writing %zu in the database", numberItems);
-                    }
-                    ps->close(fp);
-                }
-                else
-                {
-                    OIC_LOG(ERROR, TAG, "File open failed.");
-                }
-
-            }
+            OIC_LOG_V(ERROR, TAG, "WritePSIDatabase() is failed(%d)", ret);
         }
     }
 
     SRMDeInitSecureResources();
     InitSecureResources();
-    OIC_LOG(DEBUG, TAG, "ResetSecureResourceINPS OUT");
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
 
 exit:
     OICFree(dbData);
     OICFree(outPayload);
     OICFree(aclCbor);
+    OICFree(credCbor);
     OICFree(pstatCbor);
     OICFree(doxmCbor);
     OICFree(resetPfCbor);
@@ -588,18 +1064,19 @@ exit:
  * Creates Reset Profile from the initial secure virtual resources.
  * This function copies the secure resources
  * and creates the Reset Profile in the Persistent Storage.
- * Device ID in doxm and pstat are left empty as it will be renewed after reset.
+ * Device ID in doxm and pstat remains as same after reset.
  *
  * @return OCStackResult - result of updating Secure Virtual Resource(s)
  */
 OCStackResult CreateResetProfile(void)
 {
-    OIC_LOG(DEBUG, TAG, "CreateResetProfile IN");
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
 
     size_t dbSize = 0;
     uint8_t *dbData = NULL;
 
     uint8_t *aclCbor = NULL;
+    uint8_t *credCbor = NULL;
     uint8_t *pstatCbor = NULL;
     uint8_t *doxmCbor = NULL;
     uint8_t *resetPfCbor = NULL;
@@ -607,25 +1084,47 @@ OCStackResult CreateResetProfile(void)
     OCStackResult ret = OC_STACK_ERROR;
     int64_t cborEncoderResult = CborNoError;
     ret = GetSecureVirtualDatabaseFromPS(NULL, &dbData, &dbSize);
+    if (OC_STACK_OK != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "GetSecureVirtualDatabaseFromPS() is failed(%d)", ret);
+    }
     if (dbData && dbSize)
     {
         size_t aclCborLen = 0;
+        size_t credCborLen = 0;
         size_t pstatCborLen = 0;
         size_t doxmCborLen = 0;
         size_t resetPfCborLen = 0;
 
+        ret = OC_STACK_ERROR;
         {
             CborParser parser;
             CborValue cbor;
             cbor_parser_init(dbData, dbSize, 0, &parser, &cbor);
             CborValue curVal = {0};
             CborError cborFindResult = CborNoError;
+
+            // abort if reset profile exists
+            cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_RESET_PF_NAME, &curVal);
+            if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
+            {
+                OIC_LOG(DEBUG, TAG, "Reset Profile already exists!!");
+                OICFree(dbData);
+                return OC_STACK_OK;
+            }
+
             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_ACL_NAME, &curVal);
             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
             {
                 cborFindResult = cbor_value_dup_byte_string(&curVal, &aclCbor, &aclCborLen, NULL);
                 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ACL Name Value.");
             }
+            cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_CRED_NAME, &curVal);
+            if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
+            {
+                cborFindResult = cbor_value_dup_byte_string(&curVal, &credCbor, &credCborLen, NULL);
+                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CRED Name Value.");
+            }
             cborFindResult = cbor_value_map_find_value(&cbor, OIC_JSON_PSTAT_NAME, &curVal);
             if (CborNoError == cborFindResult && cbor_value_is_byte_string(&curVal))
             {
@@ -640,40 +1139,8 @@ OCStackResult CreateResetProfile(void)
             }
         }
 
-        // Set the Device ID in doxm and pstat to empty
-        if (pstatCbor)
-        {
-            OicSecPstat_t *pstat = NULL;
-            ret = CBORPayloadToPstat(pstatCbor, pstatCborLen, &pstat);
-            OICFree(pstatCbor);
-            pstatCbor = NULL;
-            pstatCborLen = 0;
-
-            OicUuid_t emptyUuid = {.id = {0} };
-            memcpy(&pstat->deviceID, &emptyUuid, sizeof(OicUuid_t));
-            memcpy(&pstat->rownerID, &emptyUuid, sizeof(OicUuid_t));
-
-            ret = PstatToCBORPayload(pstat, &pstatCbor, &pstatCborLen, false);
-            DeletePstatBinData(pstat);
-        }
-        if (doxmCbor)
-        {
-            OicSecDoxm_t *doxm = NULL;
-            ret = CBORPayloadToDoxm(doxmCbor, doxmCborLen, &doxm);
-            OICFree(doxmCbor);
-            doxmCbor = NULL;
-            doxmCborLen = 0;
-
-            OicUuid_t emptyUuid = {.id = {0} };
-            memcpy(&doxm->deviceID, &emptyUuid, sizeof(OicUuid_t));
-            memcpy(&doxm->rownerID, &emptyUuid, sizeof(OicUuid_t));
-
-            ret = DoxmToCBORPayload(doxm, &doxmCbor, &doxmCborLen, false);
-            DeleteDoxmBinData(doxm);
-        }
-
         {
-            size_t size = aclCborLen + pstatCborLen + doxmCborLen + 255;
+            size_t size = aclCborLen + credCborLen + pstatCborLen + doxmCborLen + 255;
             resetPfCbor = (uint8_t *) OICCalloc(1, size);
             VERIFY_NON_NULL(TAG, resetPfCbor, ERROR);
             CborEncoder encoder;  // will be initialized in |cbor_parser_init|
@@ -686,6 +1153,14 @@ OCStackResult CreateResetProfile(void)
             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, aclCbor, aclCborLen);
             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value.");
 
+            if (credCborLen)
+            {
+                cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_CRED_NAME, strlen(OIC_JSON_CRED_NAME));
+                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CRED Name.");
+                cborEncoderResult |= cbor_encode_byte_string(&secRsrc, credCbor, credCborLen);
+                VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CRED Value.");
+            }
+
             cborEncoderResult |= cbor_encode_text_string(&secRsrc, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME));
             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name.");
             cborEncoderResult |= cbor_encode_byte_string(&secRsrc, pstatCbor, pstatCborLen);
@@ -701,16 +1176,45 @@ OCStackResult CreateResetProfile(void)
             resetPfCborLen = cbor_encoder_get_buffer_size(&encoder, resetPfCbor);
         }
 
-        UpdateSecureResourceInPS(OIC_JSON_RESET_PF_NAME, resetPfCbor, resetPfCborLen);
+        ret = UpdateSecureResourceInPS(OIC_JSON_RESET_PF_NAME, resetPfCbor, resetPfCborLen);
+        if (OC_STACK_OK != ret)
+        {
+            OIC_LOG(ERROR, TAG, "Error in UpdateSecureResourceInPS");
+        }
 
     }
-    OIC_LOG(DEBUG, TAG, "CreateResetProfile OUT");
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
 
 exit:
     OICFree(dbData);
     OICFree(aclCbor);
+    OICFree(credCbor);
     OICFree(pstatCbor);
     OICFree(doxmCbor);
     OICFree(resetPfCbor);
     return ret;
 }
+
+void SetPSStatus(PSStatus_t status)
+{
+    g_psStatus = status;
+}
+
+void PrintPSStatus(void)
+{
+    switch(g_psStatus)
+    {
+        case PS_NORMAL:
+            OIC_LOG(INFO, TAG, "PS Status: Normal - using external DB");
+            break;
+        case PS_OPEN_FAIL:
+            OIC_LOG(INFO, TAG, "PS Status: Failed to open external DB! - using default DB");
+            break;
+        case PS_PARSE_FAIL:
+            OIC_LOG(INFO, TAG, "PS Status: Failed to CBOR parse external DB! - using default DB");
+            break;
+        default:
+            OIC_LOG(INFO, TAG, "PS Status: No external DB set - using internal memory");
+
+    }
+}
diff --git a/resource/csdk/security/src/psiutils.c b/resource/csdk/security/src/psiutils.c
new file mode 100755 (executable)
index 0000000..af41c5e
--- /dev/null
@@ -0,0 +1,309 @@
+/******************************************************************
+*
+* Copyright 2017 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 <stdlib.h>
+#include <string.h>
+
+#include "logger.h"
+#include "ocstack.h"
+#include "octypes.h"
+#include "psiutils.h"
+#include "psinterface.h"
+#include "oic_malloc.h"
+#include "mbedtls/entropy.h"
+#include "mbedtls/ctr_drbg.h"
+#include "mbedtls/aes.h"
+#include "mbedtls/md.h"
+
+#define TAG "OIC_SEC_PSIUTIL"
+
+/*Internal to this File only*/
+#define BLOCK_LEN 16
+#define KEY_LEN 256
+#define IV_LEN 16
+#define DIGEST_LEN 32
+
+#define VERIFY_NON_NULL(tag, arg, logLevel) do{ if (NULL == (arg)) \
+    { OIC_LOG((logLevel), tag, #arg " is NULL"); goto exit; } }while(0)
+
+static unsigned char aesKey[AES_KEY_SIZE];
+bool isKeySet = false;
+
+OCStackResult psiSetKey(const unsigned char* key)
+{
+    if (NULL == key)
+    {
+        return OC_STACK_INVALID_PARAM;
+    }
+    memcpy(aesKey,key,AES_KEY_SIZE);
+    isKeySet = true;
+    return OC_STACK_OK;
+}
+
+OCStackResult psiGetKey(unsigned char* key)
+{
+    if(false == isKeySet)
+    {
+        return OC_STACK_ERROR;
+    }
+    memcpy(key, aesKey, AES_KEY_SIZE);
+    return OC_STACK_OK;
+}
+
+bool psiIsKeySet()
+{
+    return isKeySet;
+}
+
+static int GenerateIV(unsigned char *IV)
+{
+    mbedtls_ctr_drbg_context ctr_drbg;
+    mbedtls_entropy_context entropy;
+    char *pers = "generate psi iv vector";
+    int ret;
+
+    mbedtls_entropy_init( &entropy );
+    mbedtls_ctr_drbg_init(&ctr_drbg);
+
+    if((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
+                    (unsigned char *) pers, strlen(pers))) != 0 )
+    {
+        OIC_LOG(ERROR, TAG, "mbedtls_ctr_drbg_init() Failed!!");
+        return 1;
+    }
+
+    if((ret = mbedtls_ctr_drbg_random(&ctr_drbg, IV, 16)) != 0 )
+    {
+        OIC_LOG(ERROR, TAG, "mbedtls_ctr_drbg_random Failed!!");
+        return 1;
+    }
+    return 0;
+}
+
+/*
+ * User need to OICFree() *ciphertext after using it.
+ */
+int psiEncrypt(const unsigned char *plaintext, size_t pt_len,
+        unsigned char **ciphertext, size_t *ct_len)
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+
+    unsigned char IV[IV_LEN];
+    unsigned char digest[DIGEST_LEN] , key[AES_KEY_SIZE];
+    unsigned char *tempBuf = NULL;
+    size_t padLen = BLOCK_LEN - (pt_len % BLOCK_LEN);
+    int ret = 0;
+    int tempBufSize, mod;
+
+    if (!plaintext || !pt_len || !ciphertext || *ciphertext || !ct_len)
+    {
+        OIC_LOG_V(ERROR, TAG, "%s: %s is NULL",
+                __func__, !plaintext ? "plaintext" : !pt_len ? "pt_len"
+                : !ciphertext || *ciphertext ? "ciphertext" : "ct_len");
+        ret = 1;
+        goto exit;
+    }
+
+    /*
+       -----------------------------------------
+       |  16 Bytes |  Plain/cipher    |32 Bytes|
+       |   IV      |  text + PadLen   | (H)MAC |
+       -----------------------------------------
+    */
+    tempBufSize = (IV_LEN + pt_len + padLen + DIGEST_LEN);
+    tempBuf = (unsigned char*)OICCalloc(1, sizeof(unsigned char) * tempBufSize);
+    VERIFY_NON_NULL(TAG, tempBuf, ERROR);
+
+    if (OC_STACK_OK != psiGetKey(key))
+    {
+        OIC_LOG(ERROR, TAG, "Failed to get Key");
+        ret = 1;
+        goto exit;
+    }
+
+    /* first IV_LEN bytes for Init. vector*/
+    memcpy(tempBuf + IV_LEN , plaintext, pt_len);
+    unsigned int i;
+    for (i = 0; i < padLen; ++i)
+    {
+        tempBuf[IV_LEN + pt_len + i] = padLen;
+    }
+
+    if (GenerateIV(IV))
+    {
+        OIC_LOG(ERROR, TAG, "IV Generation Failed!!");
+        ret = 1;
+        goto exit;
+    }
+
+    //last 4 bits of IV will store pt_len%BLOCK_LEN
+    //we will use these to recover padLen in decryption.
+    mod = (int)(pt_len & 0x0F);
+    IV[IV_LEN-1] = (unsigned char)((IV[IV_LEN -1] & 0xF0) | mod);
+
+    //store IV
+    memcpy(tempBuf, IV, IV_LEN);
+
+    mbedtls_aes_context aes_ctx;
+    mbedtls_aes_init(&aes_ctx);
+
+    mbedtls_aes_setkey_enc(&aes_ctx, key, KEY_LEN);
+
+    /*plain data start at an offset of IV_LEN*/
+    mbedtls_aes_crypt_cbc(&aes_ctx, MBEDTLS_AES_ENCRYPT, (pt_len + padLen),
+            IV, (tempBuf+IV_LEN), (tempBuf+IV_LEN));
+
+    mbedtls_md_context_t sha_ctx;
+    mbedtls_md_init(&sha_ctx);
+
+    if(0 != mbedtls_md_setup(&sha_ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 1))
+    {
+        OIC_LOG(ERROR, TAG, "mbedtls_md_setup() Failed!!");
+        ret = 1;
+        goto exit;
+    }
+
+    /* setup the AES and HMAC context*/
+    memset(digest, 0, DIGEST_LEN);
+
+    mbedtls_md_hmac_starts(&sha_ctx, key, DIGEST_LEN);
+    ret = mbedtls_md_hmac_update(&sha_ctx, tempBuf + IV_LEN, (pt_len+padLen));
+    if (0 != ret)
+    {
+        OIC_LOG(ERROR, TAG, "mbedtls_md_hmac_update() Failed");
+        mbedtls_md_free(&sha_ctx);
+        goto exit;
+    }
+    mbedtls_md_hmac_finish(&sha_ctx, digest);
+    mbedtls_md_free(&sha_ctx);
+
+    //copy last 32 bytes for MAC
+    memcpy((tempBuf + IV_LEN + pt_len + padLen), digest, DIGEST_LEN);
+
+    memset(key, 0, AES_KEY_SIZE); //destroy key
+
+    *ciphertext = tempBuf;
+    tempBuf = NULL;
+    *ct_len = tempBufSize;
+exit:
+    if (tempBuf)
+    {
+        OICFree(tempBuf);
+    }
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+    return ret;
+}
+
+/*
+ * plaintext will be free by App
+ */
+int psiDecrypt(const unsigned char *ciphertext, size_t ct_len,
+        unsigned char **plaintext, size_t *pt_len)
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+
+    int mod, len;
+    unsigned char IV[IV_LEN], digest[DIGEST_LEN];
+    unsigned char key[AES_KEY_SIZE];
+    unsigned char *pt = NULL;
+    int ret = 0;
+
+    if (!ciphertext || !ct_len || !plaintext || *plaintext || !pt_len)
+    {
+        OIC_LOG_V(ERROR, TAG, "%s: %s is NULL",
+                __func__, !ciphertext ? "ciphertext" : !ct_len ? "ct_len"
+                : !plaintext || *plaintext ? "plaintext" : "pt_len");
+        ret = 1;
+        goto exit;
+    }
+
+
+    if (OC_STACK_OK != psiGetKey(key))
+    {
+        OIC_LOG(ERROR, TAG, "Failed to get Key");
+        ret = 1;
+        goto exit;
+    }
+
+    memcpy(IV, ciphertext, IV_LEN);
+    //restore mod
+    mod = IV[IV_LEN-1] & 0x0F;
+
+    //Length of original data was..
+    //Avoid writing Padding, IV & HMAC into the SVR DB File
+    len = ct_len - (BLOCK_LEN - mod) - (IV_LEN + DIGEST_LEN);
+    pt = (unsigned char*)OICCalloc(1, ct_len *sizeof(unsigned char));
+    VERIFY_NON_NULL(TAG, pt, ERROR);
+
+    //decrypt
+    mbedtls_aes_context aes_ctx;
+    mbedtls_aes_init(&aes_ctx);
+
+    mbedtls_aes_setkey_dec(&aes_ctx, key, KEY_LEN);
+    mbedtls_aes_crypt_cbc(&aes_ctx, MBEDTLS_AES_DECRYPT, ct_len - IV_LEN,
+            IV, (ciphertext+IV_LEN), pt);
+
+    //hash check
+    mbedtls_md_context_t sha_ctx;
+    mbedtls_md_init(&sha_ctx);
+
+    if (0 != mbedtls_md_setup(&sha_ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 1))
+    {
+        OIC_LOG(ERROR, TAG, "mbedtls_md_setup() Failed!!");
+        ret = 1;
+        goto exit;
+    }
+
+    memset(digest, 0, DIGEST_LEN);
+    mbedtls_md_hmac_starts(&sha_ctx, key, DIGEST_LEN);
+    ret = mbedtls_md_hmac_update(&sha_ctx, ciphertext + IV_LEN, (ct_len - DIGEST_LEN - IV_LEN));
+    if (0 != ret)
+    {
+        OIC_LOG(ERROR, TAG, "mbedtls_md_hmac_update() Failed");
+        mbedtls_md_free(&sha_ctx);
+        goto exit;
+    }
+    mbedtls_md_hmac_finish(&sha_ctx, digest);
+    mbedtls_md_free(&sha_ctx);
+    memset(key, 0, AES_KEY_SIZE); //destroy key
+
+    int diff = 0;
+    for (int i = 0; i < DIGEST_LEN; i++)
+    {
+        diff |= digest[i] ^ ciphertext[ct_len - DIGEST_LEN + i];
+    }
+    if (diff != 0)
+    {
+        OIC_LOG(ERROR, TAG, "HMAC check failed: wrong key, "
+                "or file corrupted.");
+        ret = 1;
+        goto exit;
+    }
+    *plaintext = pt;
+    pt = NULL;
+    *pt_len = len;
+exit:
+    if (pt)
+    {
+        OICFree(pt);
+    }
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+    return ret;
+}
index 3a9e291..e32c86c 100644 (file)
@@ -224,6 +224,7 @@ exit:
     {
         // reallocate and try again!
         OICFree(outPayload);
+        outPayload = NULL;
         // Since the allocated initial memory failed, double the memory.
         cborLen += cbor_encoder_get_buffer_size(&encoder, encoder.end);
         cborEncoderResult = CborNoError;
@@ -360,6 +361,7 @@ static OCStackResult CBORPayloadToPstatBin(const uint8_t *cborPayload, const siz
 
         pstat->smLen = 1;
         pstat->sm = (OicSecDpom_t*)OICCalloc(pstat->smLen, sizeof(OicSecDpom_t));
+        VERIFY_NON_NULL(TAG, pstat->sm, ERROR);
         cborFindResult = cbor_value_get_int(&pstatMap, &sm);
         VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding SM.");
         pstat->sm[0] = (OicSecDpom_t)sm;
@@ -374,6 +376,7 @@ static OCStackResult CBORPayloadToPstatBin(const uint8_t *cborPayload, const siz
         VERIFY_NON_NULL(TAG, gPstat, ERROR);
         pstat->smLen = gPstat->smLen;
         pstat->sm = (OicSecDpom_t*)OICCalloc(pstat->smLen, sizeof(OicSecDpom_t));
+        VERIFY_NON_NULL(TAG, pstat->sm, ERROR);
         *pstat->sm = *gPstat->sm;
         cborFindResult = CborNoError;
     }
@@ -462,6 +465,30 @@ static bool ValidateQuery(const char * query)
     return (bInterfaceQry ? bInterfaceMatch: true);
 }
 
+#ifdef MULTIPLE_OWNER
+bool IsValidPstatAccessForSubOwner(const uint8_t *cborPayload, size_t size)
+{
+    OicSecPstat_t* pstat = NULL;
+    bool isValidPstat = true;
+
+    OIC_LOG_BUFFER(DEBUG, TAG, cborPayload, size);
+    VERIFY_NON_NULL(TAG, cborPayload, ERROR);
+    VERIFY_SUCCESS(TAG, 0 != size, ERROR);
+    VERIFY_SUCCESS(TAG, OC_STACK_OK == CBORPayloadToPstat(cborPayload, size, &pstat), ERROR);
+    VERIFY_NON_NULL(TAG, pstat, ERROR);
+
+    if (RESET & pstat->cm)
+    {
+        OIC_LOG(ERROR, TAG, "SubOwner can't reset the server.");
+        isValidPstat = false;
+    }
+
+exit:
+    DeletePstatBinData(pstat);
+    return isValidPstat;
+}
+#endif //MULTIPLE_OWNER
+
 /**
  * The entity handler determines how to process a GET request.
  */
@@ -517,6 +544,7 @@ static OCEntityHandlerResult HandlePstatPostRequest(OCEntityHandlerRequest *ehRe
     OIC_LOG(INFO, TAG, "HandlePstatPostRequest  processing POST request");
     OicSecPstat_t *pstat = NULL;
     static uint16_t previousMsgId = 0;
+    bool isDuplicatedMsg = false;
 
     if (ehRequest->payload && NULL != gPstat)
     {
@@ -531,6 +559,17 @@ static OCEntityHandlerResult HandlePstatPostRequest(OCEntityHandlerRequest *ehRe
         {
             bool validReq = false;
 
+            /*
+             * message ID is supported for CoAP over UDP only according to RFC 7252
+             * So we should check message ID to prevent duplicate request handling in case of OC_ADAPTER_IP.
+             * In case of other transport adapter, duplicate message check is not required.
+             */
+            if (OC_ADAPTER_IP == ehRequest->devAddr.adapter &&
+                 previousMsgId == ehRequest->messageID)
+            {
+                isDuplicatedMsg = true;
+            }
+
             if (true == roParsed)
             {
                     OIC_LOG(ERROR, TAG, "Not acceptable request because of read-only properties");
@@ -641,9 +680,12 @@ static OCEntityHandlerResult HandlePstatPostRequest(OCEntityHandlerRequest *ehRe
              {
                 OIC_LOG(WARNING, TAG, "The operation failed during handle DOXM request");
 
-                if((OC_ADAPTER_IP == ehRequest->devAddr.adapter && previousMsgId != ehRequest->messageID)
-                   || OC_ADAPTER_TCP == ehRequest->devAddr.adapter)
+                if (!isDuplicatedMsg)
                 {
+#if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
+                    InvokeOtmEventHandler(ehRequest->devAddr.addr, ehRequest->devAddr.port,
+                                          NULL, OIC_OTM_ERROR);
+#endif
                     RestoreDoxmToInitState();
                     RestorePstatToInitState();
                     OIC_LOG(WARNING, TAG, "DOXM will be reverted.");
@@ -659,7 +701,7 @@ static OCEntityHandlerResult HandlePstatPostRequest(OCEntityHandlerRequest *ehRe
      {
         if(ehRequest->devAddr.adapter == OC_ADAPTER_IP)
         {
-            previousMsgId = ehRequest->messageID++;
+            previousMsgId = ehRequest->messageID;
         }
      }
 
@@ -878,3 +920,44 @@ OCStackResult GetPstatRownerId(OicUuid_t *rowneruuid)
     }
     return retVal;
 }
+
+OCStackResult SetPstatSelfOwnership(const OicUuid_t* newROwner)
+{
+    OCStackResult ret = OC_STACK_ERROR;
+    uint8_t *cborPayload = NULL;
+    size_t size = 0;
+
+    if(NULL == gPstat)
+    {
+        ret = OC_STACK_NO_RESOURCE;
+        return ret;
+    }
+
+    if( newROwner && (false == gPstat->isOp) && (true == (TAKE_OWNER && gPstat->cm)) )
+    {
+        gPstat->cm = (OicSecDpm_t)(gPstat->cm & (~TAKE_OWNER));
+        gPstat->isOp = true;
+
+        memcpy(gPstat->deviceID.id, newROwner->id, sizeof(newROwner->id));
+        memcpy(gPstat->rownerID.id, newROwner->id, sizeof(newROwner->id));
+
+        ret = PstatToCBORPayload(gPstat, &cborPayload, &size, false);
+        VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+        ret = UpdateSecureResourceInPS(OIC_JSON_PSTAT_NAME, cborPayload, size);
+        VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+        OICFree(cborPayload);
+    }
+    else
+    {
+        OIC_LOG(ERROR, TAG, "The state of PSTAT is not Ready For OTM");
+    }
+
+    return ret;
+
+exit:
+    OICFree(cborPayload);
+    return ret;
+}
+
index c4545f3..6d7c8e1 100644 (file)
@@ -25,7 +25,6 @@
 #include "pstatresource.h"
 #include "doxmresource.h"
 #include "credresource.h"
-#include "svcresource.h"
 #include "amaclresource.h"
 #include "oic_malloc.h"
 #include "oic_string.h"
@@ -37,6 +36,7 @@
 #include "dpairingresource.h"
 //#endif // DIRECT_PAIRING
 #include "verresource.h"
+#include "psinterface.h"
 
 #define TAG "OIC_SRM_RM"
 
@@ -73,13 +73,17 @@ OCStackResult InitSecureResources( )
 {
     OCStackResult ret;
 
+    ret = InitPersistentStorageInterface();
+
     /*
      * doxm resource should be initialized first as it contains the DeviceID
      * which MAY be used during initialization of other resources.
      */
 
-    ret = InitDoxmResource();
-
+    if(OC_STACK_OK == ret)
+    {
+        ret = InitDoxmResource();
+    }
     if(OC_STACK_OK == ret)
     {
         ret = InitPstatResource();
@@ -100,10 +104,6 @@ OCStackResult InitSecureResources( )
 #endif // __WITH_DTLS__ || __WITH_TLS__
     if(OC_STACK_OK == ret)
     {
-        ret = InitSVCResource();
-    }
-    if(OC_STACK_OK == ret)
-    {
         ret = InitAmaclResource();
     }
 //#ifdef DIRECT_PAIRING
@@ -137,13 +137,13 @@ OCStackResult DestroySecureResources( )
 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
     DeInitCRLResource();
 #endif // __WITH_DTLS__ || __WITH_TLS__
-    DeInitSVCResource();
     DeInitAmaclResource();
 //#ifdef DIRECT_PAIRING
     DeInitPconfResource();
     DeInitDpairingResource();
 //#endif // DIRECT_PAIRING
     DeInitVerResource();
+    DeinitPersistentStorageInterface();
 
     return OC_STACK_OK;
 }
index 4c41799..a054e73 100644 (file)
 #include "cainterface.h"
 #include "resourcemanager.h"
 #include "credresource.h"
+#include "doxmresource.h"
+#include "pstatresource.h"
 #include "policyengine.h"
 #include "srmutility.h"
+#include "psinterface.h"
 #include "amsmgr.h"
 #include "oic_string.h"
 #include "oic_malloc.h"
@@ -133,7 +136,7 @@ exit:
  */
 void SRMRequestHandler(const CAEndpoint_t *endPoint, const CARequestInfo_t *requestInfo)
 {
-    OIC_LOG(DEBUG, TAG, "Received request from remote device");
+    OIC_LOG_V(DEBUG, TAG, "%s:Received request from remote device", __func__);
 
     bool isRequestOverSecureChannel = false;
     if (!endPoint || !requestInfo)
@@ -152,6 +155,12 @@ void SRMRequestHandler(const CAEndpoint_t *endPoint, const CARequestInfo_t *requ
     }
 
     //Check the URI has the query and skip it before checking the permission
+    if (NULL == requestInfo->info.resourceUri)
+    {
+        OIC_LOG(ERROR, TAG, "Invalid resourceUri");
+        return;
+    }
+
     char *uri = strstr(requestInfo->info.resourceUri, "?");
     int position = 0;
     if (uri)
@@ -204,14 +213,14 @@ void SRMRequestHandler(const CAEndpoint_t *endPoint, const CARequestInfo_t *requ
             }
         }
     }
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
     /*
      * In case of ACL and CRED, The payload required to verify the payload.
      * Payload information will be used for subowner's permission verification.
      */
     g_policyEngineContext.payload = (uint8_t*)requestInfo->info.payload;
     g_policyEngineContext.payloadSize = requestInfo->info.payloadSize;
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
     //New request are only processed if the policy engine state is AWAITING_REQUEST.
     if (AWAITING_REQUEST == g_policyEngineContext.state)
@@ -275,7 +284,7 @@ exit:
  */
 void SRMResponseHandler(const CAEndpoint_t *endPoint, const CAResponseInfo_t *responseInfo)
 {
-    OIC_LOG(DEBUG, TAG, "Received response from remote device");
+    OIC_LOG_V(DEBUG, TAG, "%s:Received response from remote device", __func__);
 
     // isProvResponse flag is to check whether response is catered by provisioning APIs or not.
     // When token sent by CA response matches with token generated by provisioning request,
@@ -302,8 +311,8 @@ void SRMResponseHandler(const CAEndpoint_t *endPoint, const CAResponseInfo_t *re
  */
 void SRMErrorHandler(const CAEndpoint_t *endPoint, const CAErrorInfo_t *errorInfo)
 {
-    OIC_LOG_V(INFO, TAG, "Received error from remote device with result, %d for request uri, %s",
-            errorInfo->result, errorInfo->info.resourceUri);
+    OIC_LOG_V(INFO, TAG, "%s:Received error from remote device with result, %d for request uri, %s",
+            __func__, errorInfo->result, errorInfo->info.resourceUri);
     if (gErrorHandler)
     {
         gErrorHandler(endPoint, errorInfo);
@@ -341,8 +350,18 @@ OCStackResult SRMRegisterPersistentStorageHandler(OCPersistentStorage* persisten
         OIC_LOG(ERROR, TAG, "The persistent storage handler is invalid");
         return OC_STACK_INVALID_PARAM;
     }
+
     gPersistentStorageHandler = persistentStorageHandler;
-    return OC_STACK_OK;
+
+    // Check validity of Persistent Storage
+    OCStackResult res = OC_STACK_SVR_DB_NOT_EXIST;
+    res = CheckPersistentStorage(persistentStorageHandler);
+    if (OC_STACK_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "Persistent storage is not normal");
+        gPersistentStorageHandler = NULL;
+    }
+    return res;
 }
 
 OCPersistentStorage* SRMGetPersistentStorageHandler()
@@ -391,7 +410,6 @@ bool SRMIsSecurityResourceURI(const char* uri)
     }
 
     const char *rsrcs[] = {
-        OIC_RSRC_SVC_URI,
         OIC_RSRC_AMACL_URI,
         OIC_RSRC_CRL_URI,
         OIC_RSRC_CRED_URI,
@@ -427,6 +445,133 @@ bool SRMIsSecurityResourceURI(const char* uri)
 }
 
 /**
+ * Check whether persistent storage is valid
+ * @return OC_STACK_OK if valid, other errors otherwise;
+ */
+OCStackResult CheckPersistentStorage(OCPersistentStorage* ps)
+{
+    OIC_LOG_V(INFO, TAG, "In %s", __func__);
+
+    FILE *fp = NULL;
+    OCStackResult ret = OC_STACK_SVR_DB_NOT_EXIST;
+    OicSecDoxm_t* doxm = NULL;
+    OicSecPstat_t* pstat = NULL;
+    uint8_t *data = NULL;
+    size_t size = 0;
+
+    if (NULL == ps)
+    {
+        OIC_LOG(ERROR, TAG, "NULL PersistentStorage Parameter");
+        ret = OC_STACK_INVALID_PARAM;
+        goto exit;
+    }
+
+    // Check whether the DB file exists
+    fp = ps->open(SVR_DB_DAT_FILE_NAME, "r+b");
+    if (NULL == fp)
+    {
+        OIC_LOG(ERROR, TAG, "DB file cannot be opened");
+        ret = OC_STACK_SVR_DB_NOT_EXIST;
+        SetPSStatus(PS_OPEN_FAIL);
+        goto exit;
+    }
+    ps->close(fp);
+
+    OIC_LOG(INFO, TAG, "Checking doxm resource...");
+    //Check DOXM resource
+    ret = GetSecureVirtualDatabaseFromPS2(ps, OIC_JSON_DOXM_NAME, &data, &size);
+    // If database read failed
+    if (OC_STACK_OK != ret)
+    {
+        OIC_LOG (ERROR, TAG, "Can not find the DOXM Resource in SVR DB.");
+        ret = OC_STACK_INCONSISTENT_DB;
+        SetPSStatus(PS_PARSE_FAIL);
+        goto exit;
+    }
+    if (data && 0 < size)
+    {
+        // Read DOXM resource from PS
+        ret = CBORPayloadToDoxm(data, size, &doxm);
+        if (OC_STACK_OK != ret)
+        {
+            OIC_LOG_V(ERROR, TAG, "Failed to Convert CBOR to Doxm bin : %d", ret);
+            ret = OC_STACK_INCONSISTENT_DB;
+            SetPSStatus(PS_PARSE_FAIL);
+            goto exit;
+        }
+    }
+    else
+    {
+        ret = OC_STACK_INCONSISTENT_DB;
+        SetPSStatus(PS_PARSE_FAIL);
+        goto exit;
+    }
+    if (data)
+    {
+        OICFree(data);
+        data = NULL;
+    }
+
+    OIC_LOG(INFO, TAG, "Checking pstat resource...");
+    //Check PSTAT resource
+    ret = GetSecureVirtualDatabaseFromPS2(ps, OIC_JSON_PSTAT_NAME, &data, &size);
+    // If database read failed
+    if (OC_STACK_OK != ret)
+    {
+        OIC_LOG (ERROR, TAG, "Can not find the PSTAT Resource in SVR DB.");
+        ret = OC_STACK_INCONSISTENT_DB;
+        SetPSStatus(PS_PARSE_FAIL);
+        goto exit;
+    }
+    if (data && 0 < size)
+    {
+        // Read ACL resource from PS
+        ret = CBORPayloadToPstat(data, size, &pstat);
+        if (OC_STACK_OK != ret)
+        {
+            OIC_LOG_V(ERROR, TAG, "Failed to Convert CBOR to PSTAT bin : %d", ret);
+            ret = OC_STACK_INCONSISTENT_DB;
+            SetPSStatus(PS_PARSE_FAIL);
+            goto exit;
+        }
+    }
+    else
+    {
+        ret = OC_STACK_INCONSISTENT_DB;
+        SetPSStatus(PS_PARSE_FAIL);
+        goto exit;
+    }
+    if (data)
+    {
+        OICFree(data);
+        data = NULL;
+    }
+
+    SetPSStatus(PS_NORMAL);
+
+    ret = OC_STACK_OK;
+    OIC_LOG(INFO, TAG, "All Secure Virtual Resources are fine.");
+
+exit:
+    if (data)
+    {
+        OICFree(data);
+    }
+    if (doxm)
+    {
+        DeleteDoxmBinData(doxm);
+    }
+    if (pstat)
+    {
+        DeletePstatBinData(pstat);
+    }
+
+    OIC_LOG_V(INFO, TAG, "Out %s", __func__);
+
+    return ret;
+}
+
+/**
  * Get the Secure Virtual Resource (SVR) type from the URI.
  * @param   uri [IN] Pointer to URI in question.
  * @return  The OicSecSvrType_t of the URI passed (note: if not a Secure Virtual
@@ -522,15 +667,6 @@ OicSecSvrType_t GetSvrTypeFromUri(const char* uri)
         }
     }
 
-    svrLen = strlen(OIC_RSRC_SVC_URI);
-    if(uriLen == svrLen)
-    {
-        if(0 == strncmp(uri, OIC_RSRC_SVC_URI, svrLen))
-        {
-            return OIC_R_SVC_TYPE;
-        }
-    }
-
     svrLen = strlen(OIC_RSRC_SACL_URI);
     if(uriLen == svrLen)
     {
index 9dd8ffe..b847a30 100644 (file)
@@ -63,11 +63,6 @@ const char * OIC_RSRC_TYPE_SEC_SACL = "oic.r.sacl";
 const char * OIC_RSRC_SACL_URI =  "/oic/sec/sacl";
 const char * OIC_JSON_SACL_NAME = "sacl";
 
-//svc
-const char * OIC_RSRC_TYPE_SEC_SVC = "oic.r.svc";
-const char * OIC_RSRC_SVC_URI =  "/oic/sec/svc";
-const char * OIC_JSON_SVC_NAME = "svc";
-
 //pconf
 const char * OIC_RSRC_TYPE_SEC_PCONF = "oic.r.pconf";
 const char * OIC_RSRC_PCONF_URI =  "/oic/sec/pconf";
@@ -94,15 +89,15 @@ const char * OIC_JSON_PERMISSION_NAME = "permission";
 const char * OIC_JSON_OWNERS_NAME = "ownrs";
 const char * OIC_JSON_OWNER_NAME = "ownr";
 const char * OIC_JSON_DEVOWNERID_NAME = "devowneruuid";
-#ifdef _ENABLE_MULTIPLE_OWNER_
-const char * OIC_JSON_SUBOWNERID_NAME = "subowneruuid";
-#endif //_ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
+const char * OIC_JSON_SUBOWNERID_NAME = "x.org.iotivity.subowneruuid";
+#endif //MULTIPLE_OWNER
 const char * OIC_JSON_OWNED_NAME = "owned";
 const char * OIC_JSON_OXM_NAME = "oxm";
 const char * OIC_JSON_OXMS_NAME = "oxms";
-#ifdef _ENABLE_MULTIPLE_OWNER_
-const char * OIC_JSON_MOM_NAME = "mom";
-#endif //_ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
+const char * OIC_JSON_MOM_NAME = "x.org.iotivity.mom";
+#endif //MULTIPLE_OWNER
 const char * OIC_JSON_OXM_TYPE_NAME = "oxmtype";
 const char * OIC_JSON_OXM_SEL_NAME = "oxmsel";
 const char * OIC_JSON_DEVICE_ID_FORMAT_NAME = "didformat";
@@ -123,8 +118,7 @@ const char * OIC_JSON_PUBDATA_NAME = "pubdata";
 const char * OIC_JSON_PRIVDATA_NAME = "privdata";
 const char * OIC_JSON_OPTDATA_NAME = "optionaldata";
 const char * OIC_JSON_CREDUSAGE_NAME = "credusage";
-const char * OIC_JSON_SERVICE_DEVICE_ID = "svcdid";
-const char * OIC_JSON_SERVICE_TYPE = "svct";
+const char * OIC_JSON_REVOCATION_STATUS_NAME = "revstat";
 const char* OIC_JSON_VALIDITY_NAME = "validity";
 const char * OIC_JSON_PERIOD_NAME = "period";
 const char * OIC_JSON_PERIODS_NAME = "prds";
@@ -146,9 +140,9 @@ const char * OIC_JSON_REL_NAME = OC_RSRVD_REL;
 const char * OIC_JSON_RT_NAME = OC_RSRVD_RESOURCE_TYPE;
 const char * OIC_JSON_IF_NAME = OC_RSRVD_INTERFACE;
 const char * OIC_JSON_ROWNERID_NAME = "rowneruuid";
-#ifdef _ENABLE_MULTIPLE_OWNER_
-const char * OIC_JSON_EOWNERID_NAME = "eowneruuid";
-#endif //_ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
+const char * OIC_JSON_EOWNERID_NAME = "x.org.iotivity.eowneruuid";
+#endif //MULTIPLE_OWNER
 const char * OIC_JSON_ENCODING_NAME = "encoding";
 const char * OIC_JSON_DATA_NAME = "data";
 const char * OIC_JSON_SEC_V_NAME = "secv";
@@ -173,9 +167,14 @@ const char * WILDCARD_RESOURCE_URI = "*";
 const char * OXM_JUST_WORKS = "oic.sec.doxm.jw";
 const char * OXM_RANDOM_DEVICE_PIN = "oic.sec.doxm.rdp";
 const char * OXM_MANUFACTURER_CERTIFICATE = "oic.sec.doxm.mfgcert";
-#ifdef _ENABLE_MULTIPLE_OWNER_
-const char * OXM_PRECONF_PIN = "oic.sec.doxm.pcp";
-#endif //_ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
+const char * OXM_PRECONF_PIN = "x.org.iotivity.sec.doxm.pcp";
+#endif //MULTIPLE_OWNER
+const char * OXM_MV_JUST_WORKS = "x.org.iotivity.sec.doxm.mvjw";
+const char * OXM_CON_MFG_CERT = "x.org.iotivity.conmfgcert";
+
+//Mutual Verified Just-Works Message Prefix
+const char * MUTUAL_VERIF_NUM = "mutualVerifNum";
 
 //Credential data encoding methods
 const char * OIC_SEC_ENCODING_BASE64 = "oic.sec.encoding.base64";
index b3685e2..2bd9bcd 100644 (file)
 #include "srmresourcestrings.h"
 #include "logger.h"
 #include "oic_malloc.h"
+#include "oic_string.h"
 #include "base64.h"
+#include "doxmresource.h"
+#include "pstatresource.h"
+#include "cacommon.h"
+#include "casecurityinterface.h"
+#if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
+#include "pkix_interface.h"
+#endif
 
 #define TAG  "OIC_SRM_UTILITY"
 
@@ -133,10 +141,14 @@ const char* GetOxmString(OicSecOxm_t oxmType)
             return OXM_RANDOM_DEVICE_PIN;
         case OIC_MANUFACTURER_CERTIFICATE:
             return OXM_MANUFACTURER_CERTIFICATE;
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
         case OIC_PRECONFIG_PIN:
             return OXM_PRECONF_PIN;
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
+        case OIC_MV_JUST_WORKS:
+            return OXM_MV_JUST_WORKS;
+        case OIC_CON_MFG_CERT:
+            return OXM_CON_MFG_CERT;
         default:
             return NULL;
     }
@@ -218,3 +230,148 @@ OCStackResult ConvertStrToUuid(const char* strUuid, OicUuid_t* uuid)
 
     return OC_STACK_OK;
 }
+
+#if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
+OCStackResult SetDeviceIdSeed(const uint8_t* seed, size_t seedSize)
+{
+    return SetDoxmDeviceIDSeed(seed, seedSize);
+}
+
+static OicSecOtmEventHandler_t gOtmEventHandler = NULL;
+static char ptAddr[256] = {0};
+static uint16_t ptPort = 0;
+
+void SetOtmEventHandler(OicSecOtmEventHandler_t otmEventHandler)
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+
+    memset(ptAddr, 0x00, sizeof(ptAddr));
+    ptPort = 0;
+    gOtmEventHandler = otmEventHandler;
+    OIC_LOG_V(DEBUG, TAG, "Out%s", __func__);
+}
+
+/**
+ * Function to handle the handshake result in OTM.
+ * This function will be invoked after DTLS handshake
+ * @param   endPoint  [IN] The remote endpoint.
+ * @param   errorInfo [IN] Error information from the endpoint.
+ * @return  NONE
+ */
+static void DTLSHandshakeServerCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info)
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+    if(NULL != endpoint && NULL != info)
+    {
+        OIC_LOG_V(INFO, TAG, "Received status from remote device(%s:%d) : %d",
+                 endpoint->addr, endpoint->port, info->result);
+
+        //We can't know about PT's secure port, so compare only adress to identify the PT.
+        if (strncmp(endpoint->addr, ptAddr, strlen(ptAddr)) == 0)
+        {
+            OIC_LOG_V(INFO, TAG, "Normal port is [%s:%d]", ptAddr, ptPort);
+
+            //If DTLS handshake error occurred, revert secure resource and notify error event to application.
+            if (CA_STATUS_OK != info->result)
+            {
+                OIC_LOG(ERROR, TAG, "Failed to establish a secure session with owner device.");
+                OIC_LOG(ERROR, TAG, "Doxm/Pstat resource will be reverted to init state.");
+                RestoreDoxmToInitState();
+                RestorePstatToInitState();
+                InvokeOtmEventHandler(endpoint->addr, endpoint->port, NULL, OIC_OTM_ERROR);
+            }
+        }
+        else
+        {
+            OIC_LOG_V(WARNING, TAG, "[%s:%d] is not a owner device", endpoint->addr, endpoint->port);
+        }
+    }
+    else
+    {
+        OIC_LOG(WARNING, TAG, "Invalid param.");
+    }
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+}
+
+
+void InvokeOtmEventHandler(const char* addr, uint16_t port,
+                           const OicUuid_t* uuid, OicSecOtmEvent_t event)
+{
+    char* strUuid = NULL;
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+
+    //addr can be NULL for init state
+    //port can be '0' for BLE and init state
+    //uuid can be NULL for init state & coap
+
+    switch(event)
+    {
+        case OIC_OTM_READY:
+        case OIC_OTM_STARTED:
+            if (addr)
+            {
+                OICStrcpy(ptAddr, sizeof(ptAddr), addr);
+                ptPort = port;
+            }
+            else
+            {
+                memset(ptAddr, 0x00, sizeof(ptAddr));
+                ptPort = 0;
+            }
+            //Register TLS event handler to catch the tls event while handshake
+            if(CA_STATUS_OK != CAregisterSslHandshakeCallback(DTLSHandshakeServerCB))
+            {
+                OIC_LOG(WARNING, TAG, "Failed to register (D)TLS handshake callback.");
+            }
+            break;
+        case OIC_OTM_DONE:
+        case OIC_OTM_ERROR:
+            memset(ptAddr, 0x00, sizeof(ptAddr));
+            ptPort = 0;
+            //Register TLS event handler to catch the tls event while handshake
+            if(CA_STATUS_OK != CAregisterSslHandshakeCallback(NULL))
+            {
+                OIC_LOG(WARNING, TAG, "Failed to register (D)TLS handshake callback.");
+            }
+            //Restore Pkix handler to initial state
+            CAregisterPkixInfoHandler(GetPkixInfo);
+            CAregisterGetCredentialTypesHandler(InitCipherSuiteList);
+            break;
+        default:
+            OIC_LOG_V(ERROR, TAG, "Unknow OTM event : %d", event);
+            goto exit;
+    }
+
+    if (uuid)
+    {
+        if(OC_STACK_OK != ConvertUuidToStr(uuid, &strUuid))
+        {
+            OIC_LOG(ERROR, TAG, "Failed to convert UUID to String.");
+            goto exit;
+        }
+    }
+
+    OIC_LOG(DEBUG, TAG, "=================================");
+    OIC_LOG(DEBUG, TAG, "[OTM Event]");
+    OIC_LOG_V(DEBUG, TAG, "PT UUID : %s", (strUuid ? strUuid : "NULL"));
+    OIC_LOG_V(DEBUG, TAG, "PT Addr=%s:%d", (addr ? addr : "NULL"), port);
+    OIC_LOG_V(DEBUG, TAG, "Event Code=%d", event);
+    OIC_LOG(DEBUG, TAG, "=================================");
+
+    if (NULL == gOtmEventHandler)
+    {
+        OIC_LOG(WARNING, TAG, "OTM event handler is not registered.");
+        goto exit;
+    }
+
+    OIC_LOG(DEBUG, TAG, "Invoking callback to notify OTM state..");
+    gOtmEventHandler(addr, port, strUuid, (int)event);
+
+exit:
+    if (strUuid)
+    {
+        OICFree(strUuid);
+    }
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+}
+#endif
diff --git a/resource/csdk/security/src/svcresource.c b/resource/csdk/security/src/svcresource.c
deleted file mode 100644 (file)
index d77a75e..0000000
+++ /dev/null
@@ -1,477 +0,0 @@
-//******************************************************************
-//
-// 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.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-#include <stdlib.h>
-#include <string.h>
-
-#include "ocstack.h"
-#include "ocpayload.h"
-#include "ocpayloadcbor.h"
-#include "oic_malloc.h"
-#include "utlist.h"
-#include "payload_logging.h"
-#include "resourcemanager.h"
-#include "psinterface.h"
-#include "svcresource.h"
-#include "srmresourcestrings.h"
-#include "srmutility.h"
-
-#include "security_internals.h"
-
-#define TAG  "OIC_SRM_SVC"
-
-/** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
- * The value of payload size is increased until reaching belox max cbor size. */
-static const uint16_t CBOR_SIZE = 512;
-
-/** Max cbor size payload. */
-static const uint16_t CBOR_MAX_SIZE = 4400;
-
-/** SVC Map size - Number of mandatory items. */
-static const uint8_t SVC_MAP_SIZE = 3;
-
-static OicSecSvc_t        *gSvc = NULL;
-static OCResourceHandle    gSvcHandle = NULL;
-
-void DeleteSVCList(OicSecSvc_t* svc)
-{
-    if (svc)
-    {
-        OicSecSvc_t *svcTmp1 = NULL, *svcTmp2 = NULL;
-        LL_FOREACH_SAFE(svc, svcTmp1, svcTmp2)
-        {
-            LL_DELETE(svc, svcTmp1);
-
-            // Clean Owners
-            OICFree(svcTmp1->owners);
-
-            // Clean SVC node itself
-            OICFree(svcTmp1);
-        }
-    }
-}
-
-static size_t svcElementsCount(const OicSecSvc_t *secSvc)
-{
-    size_t size = 0;
-    for (const OicSecSvc_t *svc = secSvc; svc; svc = svc->next)
-    {
-        size++;
-    }
-    return size;
-}
-
-OCStackResult SVCToCBORPayload(const OicSecSvc_t *svc, uint8_t **cborPayload,
-                               size_t *cborSize)
-{
-    if (NULL == svc || NULL == cborPayload || NULL != *cborPayload || NULL == cborSize)
-    {
-       return OC_STACK_INVALID_PARAM;
-    }
-
-    size_t cborLen = *cborSize;
-    if (0 == cborLen)
-    {
-        cborLen = CBOR_SIZE;
-    }
-    *cborPayload = NULL;
-    *cborSize = 0;
-
-    int64_t cborEncoderResult = CborNoError;
-    OCStackResult ret = OC_STACK_ERROR;
-    CborEncoder encoder;
-    CborEncoder svcArray;
-
-    uint8_t *outPayload = (uint8_t *)OICCalloc(1, cborLen);
-    VERIFY_NON_NULL(TAG, outPayload, ERROR);
-
-    cbor_encoder_init(&encoder, outPayload, cborLen, 0);
-
-    // Create SVC Array
-    cborEncoderResult = cbor_encoder_create_array(&encoder, &svcArray, svcElementsCount(svc));
-    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Create SVC Array.");
-
-    while (svc)
-    {
-        CborEncoder svcMap;
-        CborEncoder owners;
-
-        cborEncoderResult = cbor_encoder_create_map(&svcArray, &svcMap, SVC_MAP_SIZE);
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Create SVC Map.");
-
-        // Service Device Identity
-        cborEncoderResult = cbor_encode_text_string(&svcMap, OIC_JSON_SERVICE_DEVICE_ID,
-            strlen(OIC_JSON_SERVICE_DEVICE_ID));
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Add SVC Device Id.");
-        cborEncoderResult = cbor_encode_byte_string(&svcMap, (uint8_t *)svc->svcdid.id,
-            sizeof(svc->svcdid.id));
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to ");
-
-        // Service Type
-        cborEncoderResult = cbor_encode_text_string(&svcMap, OIC_JSON_SERVICE_TYPE,
-            strlen(OIC_JSON_SERVICE_TYPE));
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Add SVC Serv Type Tag.");
-        cborEncoderResult = cbor_encode_int(&svcMap, svc->svct);
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Add SVC Serv Type Value.");
-
-        // Owners
-        // TODO: Need to modification to single ROwner, (Currently SINGLE_SERVICE_CLIENT_DRIVEN only)
-        cborEncoderResult = cbor_encode_text_string(&svcMap, OIC_JSON_OWNERS_NAME,
-            strlen(OIC_JSON_OWNERS_NAME));
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Add SVC Owners Tag.");
-        cborEncoderResult = cbor_encoder_create_array(&svcMap, &owners, svc->ownersLen);
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Add SVC Array.");
-        for (size_t i = 0; i < svc->ownersLen; i++)
-        {
-            cborEncoderResult = cbor_encode_byte_string(&owners, (uint8_t *)svc->owners[i].id,
-                sizeof(svc->owners[i].id));
-            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Add SVC Owners Value.");
-        }
-        cborEncoderResult = cbor_encoder_close_container(&svcMap, &owners);
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Close SVC Array.");
-
-        cborEncoderResult = cbor_encoder_close_container(&svcArray, &svcMap);
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Close SVC Map.");
-
-        svc = svc->next;
-    }
-
-    cborEncoderResult = cbor_encoder_close_container(&encoder, &svcArray);
-    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Close SVC Array.");
-
-    if (CborNoError == cborEncoderResult)
-    {
-        *cborPayload = outPayload;
-        *cborSize = cbor_encoder_get_buffer_size(&encoder, outPayload);
-        ret = OC_STACK_OK;
-    }
-
-exit:
-    if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE))
-    {
-        // reallocate and try again!
-        OICFree(outPayload);
-        outPayload = NULL;
-        // Since the allocated initial memory failed, double the memory.
-        cborLen += cbor_encoder_get_buffer_size(&encoder, encoder.end);
-        cborEncoderResult = CborNoError;
-        ret = SVCToCBORPayload(svc, cborPayload, &cborLen);
-        *cborSize = cborLen;
-    }
-
-    if (CborNoError != cborEncoderResult)
-    {
-        OICFree(outPayload);
-        outPayload = NULL;
-        *cborSize = 0;
-        *cborPayload = NULL;
-        ret = OC_STACK_ERROR;
-    }
-
-    return ret;
-}
-
-OCStackResult CBORPayloadToSVC(const uint8_t *cborPayload, size_t size,
-                               OicSecSvc_t **secSvc)
-{
-    if (NULL == cborPayload || NULL == secSvc || NULL != *secSvc || 0 == size)
-    {
-        return OC_STACK_INVALID_PARAM;
-    }
-
-    *secSvc = NULL;
-
-    OCStackResult ret = OC_STACK_ERROR;
-
-    CborValue svcCbor = { .parser = NULL };
-    CborParser parser = { .end = NULL };
-    CborError cborFindResult = CborNoError;
-
-    cbor_parser_init(cborPayload, size, 0, &parser, &svcCbor);
-    OicSecSvc_t *headSvc = NULL;
-
-    CborValue svcArray = { .parser = NULL };
-    cborFindResult = cbor_value_enter_container(&svcCbor, &svcArray);
-    VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Enter SVC Array.");
-
-    while (cbor_value_is_valid(&svcArray))
-    {
-        CborValue svcMap = { .parser = NULL };
-        OicSecSvc_t *svc = (OicSecSvc_t *) OICCalloc(1, sizeof(OicSecSvc_t));
-        VERIFY_NON_NULL(TAG, svc, ERROR);
-        cborFindResult = cbor_value_enter_container(&svcArray, &svcMap);
-        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Enter SVC Map.");
-
-        while (cbor_value_is_valid(&svcMap))
-        {
-            char* name = NULL;
-            size_t len = 0;
-            CborType type = CborInvalidType;
-
-            cborFindResult = cbor_value_dup_text_string(&svcMap, &name, &len, NULL);
-            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Find Name.");
-            cborFindResult = cbor_value_advance(&svcMap);
-            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Advance.");
-
-            type = cbor_value_get_type(&svcMap);
-            // Service Device Identity
-            if (0 == strcmp(OIC_JSON_SERVICE_DEVICE_ID, name) && cbor_value_is_byte_string(&svcMap))
-            {
-                uint8_t *subjectId = NULL;
-                cborFindResult = cbor_value_dup_byte_string(&svcMap, &subjectId, &len, NULL);
-                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Find SubjectId.");
-                memcpy(svc->svcdid.id, subjectId, len);
-                OICFree(subjectId);
-            }
-            // Service Type
-            if (0 == strcmp(OIC_JSON_SERVICE_TYPE, name) && cbor_value_is_integer(&svcMap))
-            {
-                int svct;
-
-                cborFindResult = cbor_value_get_int(&svcMap, &svct);
-                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Find SVCT.");
-                svc->svct = (OicSecSvcType_t)svct;
-            }
-
-            // Owners -- Mandatory
-            if (0 == strcmp(OIC_JSON_OWNERS_NAME, name) && cbor_value_is_array(&svcMap))
-            {
-                int i = 0;
-                CborValue owners = { .parser = NULL };
-
-                cborFindResult = cbor_value_get_array_length(&svcMap, &svc->ownersLen);
-                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Find Owner Len.");
-                cborFindResult = cbor_value_enter_container(&svcMap, &owners);
-                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Enter Owner Array.");
-                svc->owners = (OicUuid_t *)OICCalloc(svc->ownersLen, sizeof(*svc->owners));
-                VERIFY_NON_NULL(TAG, svc->owners, ERROR);
-
-                while (cbor_value_is_valid(&owners) && cbor_value_is_byte_string(&owners))
-                {
-                    uint8_t *owner = NULL;
-                    cborFindResult = cbor_value_dup_byte_string(&owners, &owner, &len, NULL);
-                    VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Find Owner Array Value.");
-                    cborFindResult = cbor_value_advance(&owners);
-                    VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Advance Owner Array.");
-                    memcpy(svc->owners[i++].id, owner, len);
-                    OICFree(owner);
-                }
-            }
-            if (CborMapType != type  && cbor_value_is_valid(&svcMap))
-            {
-                cborFindResult = cbor_value_advance(&svcMap);
-                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Advance SVC.");
-            }
-            OICFree(name);
-        }
-
-        svc->next = NULL;
-        if (NULL == headSvc)
-        {
-            headSvc = svc;
-        }
-        else
-        {
-            OicSecSvc_t *temp = headSvc;
-            while (temp->next)
-            {
-                temp = temp->next;
-            }
-            temp->next = svc;
-        }
-        if (cbor_value_is_valid(&svcArray))
-        {
-            cborFindResult = cbor_value_advance(&svcArray);
-            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Find Name.");
-        }
-    }
-    *secSvc = headSvc;
-    ret = OC_STACK_OK;
-
-exit:
-    if (CborNoError != cborFindResult)
-    {
-        DeleteSVCList(headSvc);
-        headSvc = NULL;
-        *secSvc = NULL;
-        ret = OC_STACK_ERROR;
-    }
-    return ret;
-}
-
-static OCEntityHandlerResult HandleSVCGetRequest(const OCEntityHandlerRequest * ehRequest)
-{
-    // Convert SVC data into JSON for transmission
-    size_t size = 0;
-    uint8_t *cborSvc = NULL;
-    OCStackResult res =  SVCToCBORPayload(gSvc, &cborSvc, &size);
-    OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR;
-
-    // Send response payload to request originator
-    ehRet = ((SendSRMResponse(ehRequest, ehRet, cborSvc, size)) == OC_STACK_OK) ?
-                   OC_EH_OK : OC_EH_ERROR;
-
-    OICFree(cborSvc);
-    OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
-    return ehRet;
-}
-
-static OCEntityHandlerResult HandleSVCPostRequest(const OCEntityHandlerRequest * ehRequest)
-{
-    OCEntityHandlerResult ehRet = OC_EH_ERROR;
-    uint8_t *payload = ((OCSecurityPayload *) ehRequest->payload)->securityData;
-    size_t size = ((OCSecurityPayload *) ehRequest->payload)->payloadSize;
-    if (payload)
-    {
-        // Convert CBOR SVC data into SVC. This will also validate the SVC data received.
-        OicSecSvc_t *newSvc = NULL;
-        OCStackResult res =  CBORPayloadToSVC(payload, size, &newSvc);
-        if (newSvc && res == OC_STACK_OK)
-        {
-            // Append the new SVC to existing SVC
-            LL_APPEND(gSvc, newSvc);
-
-            // Convert SVC data into JSON for update to persistent storage
-            size_t size = 0;
-            uint8_t *cborPayload = NULL;
-            res = SVCToCBORPayload(gSvc, &cborPayload, &size);
-            if (cborPayload && OC_STACK_OK == res &&
-                UpdateSecureResourceInPS(OIC_JSON_SVC_NAME, cborPayload, size) == OC_STACK_OK)
-            {
-                ehRet = OC_EH_CHANGED;
-            }
-            OICFree(cborPayload);
-        }
-    }
-
-    // Send payload to request originator
-    if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL, 0))
-    {
-        ehRet = OC_EH_ERROR;
-        OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandleSVCPostRequest");
-    }
-
-    OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet);
-    return ehRet;
-}
-
-/**
- * This internal method is the entity handler for SVC resources and
- * will handle REST request (GET/PUT/POST/DEL) for them.
- */
-static OCEntityHandlerResult SVCEntityHandler(OCEntityHandlerFlag flag,
-                                              OCEntityHandlerRequest * ehRequest,
-                                              void* callbackParameter)
-{
-    (void) callbackParameter;
-    OCEntityHandlerResult ehRet = OC_EH_ERROR;
-
-    if (!ehRequest)
-    {
-        return ehRet;
-    }
-
-    if (flag & OC_REQUEST_FLAG)
-    {
-        switch (ehRequest->method)
-        {
-            case OC_REST_GET:
-                ehRet = HandleSVCGetRequest(ehRequest);
-                break;
-
-            case OC_REST_POST:
-                ehRet = HandleSVCPostRequest(ehRequest);
-                break;
-
-            default:
-                ehRet = OC_EH_ERROR;
-                SendSRMResponse(ehRequest, ehRet, NULL, 0);
-        }
-    }
-
-    return ehRet;
-}
-
-/**
- * This internal method is used to create '/oic/sec/svc' resource.
- */
-static OCStackResult CreateSVCResource()
-{
-    OCStackResult ret = OCCreateResource(&gSvcHandle,
-                                         OIC_RSRC_TYPE_SEC_SVC,
-                                         OC_RSRVD_INTERFACE_DEFAULT,
-                                         OIC_RSRC_SVC_URI,
-                                         SVCEntityHandler,
-                                         NULL,
-                                         OC_OBSERVABLE);
-
-    if (OC_STACK_OK != ret)
-    {
-        OIC_LOG(FATAL, TAG, "Unable to instantiate SVC resource");
-        DeInitSVCResource();
-    }
-    return ret;
-}
-
-OCStackResult InitSVCResource()
-{
-    OCStackResult ret = OC_STACK_ERROR;
-
-    OIC_LOG_V(DEBUG, TAG, "Begin %s ", __func__ );
-
-    uint8_t *data = NULL;
-    size_t size = 0;
-    ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_SVC_NAME, &data, &size);
-    // If database read failed
-    if (ret != OC_STACK_OK)
-    {
-        OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
-    }
-
-    if (data)
-    {
-        // Convert CBOR SVC into binary format
-        ret = CBORPayloadToSVC(data, size, &gSvc);
-        if (ret != OC_STACK_OK)
-        {
-            OIC_LOG (DEBUG, TAG, " ConvertCBOR SVC into binary format failed");
-        }
-        OICFree(data);
-    }
-
-    // Instantiate 'oic.sec.svc'
-    ret = CreateSVCResource();
-
-    if (OC_STACK_OK != ret)
-    {
-        DeInitSVCResource();
-    }
-
-    OIC_LOG_V(DEBUG, TAG, "%s RetVal %d", __func__ , ret);
-    return ret;
-}
-
-void DeInitSVCResource()
-{
-    OCDeleteResource(gSvcHandle);
-    gSvcHandle = NULL;
-
-    DeleteSVCList(gSvc);
-    gSvc = NULL;
-}
index a4478e9..3f0ea0f 100644 (file)
@@ -29,7 +29,6 @@
 #include "ocstack.h"
 #include "oic_malloc.h"
 #include "oic_string.h"
-#include "logger.h"
 #include "payload_logging.h"
 #include "ocpayload.h"
 #include "ocpayloadcbor.h"
@@ -140,6 +139,7 @@ exit:
         OIC_LOG(DEBUG, TAG, "Memory getting reallocated.");
         // reallocate and try again!
         OICFree(outPayload);
+        outPayload = NULL;
         // Since the allocated initial memory failed, double the memory.
         cborLen += cbor_encoder_get_buffer_size(&encoder, encoder.end);
         OIC_LOG_V(DEBUG, TAG, "Ver reallocation size : %zd.", cborLen);
@@ -317,7 +317,7 @@ OCStackResult InitVerResource()
 {
     OCStackResult ret = OC_STACK_ERROR;
 
-    OICStrcpy(gVer.secv, MAX_VERSION_LEN, SECURITY_VERSION);
+    OICStrcpy(gVer.secv, OIC_SEC_MAX_VER_LEN, SECURITY_VERSION);
 
     //Read device id from doxm
     OicUuid_t deviceID = {.id={0}};
index 871e7a9..6aee4b5 100644 (file)
@@ -1,27 +1,29 @@
-# //******************************************************************
-# //
-# // 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.
-# //
-# //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+# ******************************************************************
+#
+# 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.
+#
+# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 #
 Import('env')
+import os
 
 tools_env = env.Clone()
 src_dir = tools_env.get('SRC_DIR')
+target_os = tools_env.get('TARGET_OS')
 
 ######################################################################
 # Build flags
@@ -29,29 +31,47 @@ src_dir = tools_env.get('SRC_DIR')
 with_upstream_libcoap = tools_env.get('WITH_UPSTREAM_LIBCOAP')
 if with_upstream_libcoap == '1':
     # For bring up purposes only, we manually copy the forked version to where the unforked version is downloaded.
-    tools_env.AppendUnique(CPPPATH = ['#extlibs/libcoap/libcoap/include'])
+    tools_env.AppendUnique(CPPPATH = ['#/extlibs/libcoap/libcoap/include'])
 else:
     # For bring up purposes only, the forked version will live here.
-    tools_env.AppendUnique(CPPPATH = ['../../connectivity/lib/libcoap-4.1.1/include'])
+    tools_env.AppendUnique(CPPPATH = ['#/resource/csdk/connectivity/lib/libcoap-4.1.1/include'])
 
-tools_env.PrependUnique(CPPPATH = ['../../../../extlibs/cjson',
-                                  '../../stack/include',
-                                  '../../stack/include/internal',
-                                  '../../logger/include',
-                                  '../../../oc_logger/include',
-                                  '../../connectivity/api',
-                                  '../../connectivity/inc/pkix',
-                                  '../include',
-                                  '../include/internal'
-                                  ])
+tools_env.PrependUnique(CPPPATH = [
+    '#/extlibs/cjson',
+    '#/resource/csdk/stack/include',
+    '#/resource/csdk/stack/include/internal',
+    '#/resource/csdk/logger/include',
+    '#/resource/oc_logger/include',
+    '#/resource/csdk/connectivity/api',
+    '#/resource/csdk/connectivity/inc/pkix',
+    '#/resource/csdk/security/include',
+    '#/resource/csdk/security/include/internal',
+    '#/resource/csdk/security/provisioning/include',
+    '#/resource/csdk/security/provisioning/include/internal'
+])
 tools_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-Wextra', '-std=c++0x'])
-tools_env.AppendUnique(LIBPATH = [tools_env.get('BUILD_DIR')])
 tools_env.AppendUnique(RPATH = [tools_env.get('BUILD_DIR')])
-tools_env.PrependUnique(LIBS = ['oc', 'octbstack'])
+tools_env.AppendUnique(LIBPATH = [tools_env.get('BUILD_DIR')])
+tools_env.PrependUnique(LIBS = ['oc', 'octbstack', 'mbedtls', 'mbedx509', 'mbedcrypto'])
+
+if tools_env.get('MULTIPLE_OWNER') == '1':
+       tools_env.AppendUnique(CPPDEFINES=['MULTIPLE_OWNER'])
 
 ######################################################################
 # Source files and Targets
 ######################################################################
 json2cbor = tools_env.Program('json2cbor', ['json2cbor.c'])
-Alias("json2cbor", [json2cbor])
-env.AppendTarget('json2cbor')
+
+SVRDBEDITOR_DIR = 'svrdbeditor_src/'
+svrdbeditor_src = [
+    SVRDBEDITOR_DIR + 'svrdbeditorcommon.c',
+    SVRDBEDITOR_DIR + 'svrdbeditoracl.c',
+    SVRDBEDITOR_DIR + 'svrdbeditorcred.c',
+    SVRDBEDITOR_DIR + 'svrdbeditordoxm.c',
+    SVRDBEDITOR_DIR + 'svrdbeditorpstat.c',
+    SVRDBEDITOR_DIR + 'svrdbeditor.c'
+]
+
+svrdbeditor = tools_env.Program("svrdbeditor", svrdbeditor_src)
+Alias("securitytool", [json2cbor, svrdbeditor])
+tools_env.AppendTarget('securitytool')
index 03b9718..b6fa1aa 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include "utlist.h"
+#if defined (__TIZENRT__)
+#include <apps/netutils/cJSON.h>
+#else
 #include "cJSON.h"
+#endif
 #include "base64.h"
 #include "cainterface.h"
 #include "ocstack.h"
@@ -38,7 +42,6 @@
 #include "doxmresource.h"
 #include "amaclresource.h"
 #include "credresource.h"
-#include "svcresource.h"
 #include "security_internals.h"
 
 #define TAG  "OIC_JSON2CBOR"
@@ -49,7 +52,6 @@ static const size_t DB_FILE_SIZE_BLOCK = 1023;
 static OicSecPstat_t* JSONToPstatBin(const char * jsonStr);
 static OicSecDoxm_t* JSONToDoxmBin(const char * jsonStr);
 static OicSecAcl_t *JSONToAclBin(const char * jsonStr);
-static OicSecSvc_t* JSONToSvcBin(const char * jsonStr);
 static OicSecAmacl_t* JSONToAmaclBin(const char * jsonStr);
 static OicSecCred_t* JSONToCredBin(const char * jsonStr);
 
@@ -85,7 +87,6 @@ static void ConvertJsonToCBOR(const char *jsonFileName, const char *cborFileName
     uint8_t *pstatCbor = NULL;
     uint8_t *doxmCbor = NULL;
     uint8_t *amaclCbor = NULL;
-    uint8_t *svcCbor = NULL;
     uint8_t *credCbor = NULL;
     cJSON *jsonRoot = NULL;
     OCStackResult ret = OC_STACK_ERROR;
@@ -183,22 +184,6 @@ static void ConvertJsonToCBOR(const char *jsonFileName, const char *cborFileName
         printf("AMACL Cbor Size: %zd\n", amaclCborSize);
         DeleteAmaclList(amacl);
     }
-    value = cJSON_GetObjectItem(jsonRoot, OIC_JSON_SVC_NAME);
-    size_t svcCborSize = 0;
-    if (NULL != value)
-    {
-        OicSecSvc_t *svc = JSONToSvcBin(jsonStr);
-        VERIFY_NON_NULL(TAG, svc, FATAL);
-        ret = SVCToCBORPayload(svc, &svcCbor, &svcCborSize);
-        if(OC_STACK_OK != ret)
-        {
-            OIC_LOG (ERROR, TAG, "Failed converting Svc to Cbor Payload");
-            DeleteSVCList(svc);
-            goto exit;
-        }
-        printf("SVC Cbor Size: %zd\n", svcCborSize);
-        DeleteSVCList(svc);
-    }
     value = cJSON_GetObjectItem(jsonRoot, OIC_JSON_CRED_NAME);
     //printf("CRED json : \n%s\n", cJSON_PrintUnformatted(value));
     size_t credCborSize = 0;
@@ -219,7 +204,7 @@ static void ConvertJsonToCBOR(const char *jsonFileName, const char *cborFileName
     }
 
     CborEncoder encoder;
-    size_t cborSize = aclCborSize + pstatCborSize + doxmCborSize + svcCborSize + credCborSize + amaclCborSize;
+    size_t cborSize = aclCborSize + pstatCborSize + doxmCborSize + credCborSize + amaclCborSize;
 
     printf("Total Cbor Size : %zd\n", cborSize);
     cborSize += 255; // buffer margin for adding map and byte string
@@ -258,13 +243,6 @@ static void ConvertJsonToCBOR(const char *jsonFileName, const char *cborFileName
         cborEncoderResult = cbor_encode_byte_string(&map, amaclCbor, amaclCborSize);
         VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding AMACL Value.");
     }
-    if (svcCborSize > 0)
-    {
-        cborEncoderResult = cbor_encode_text_string(&map, OIC_JSON_SVC_NAME, strlen(OIC_JSON_SVC_NAME));
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SVC Name.");
-        cborEncoderResult = cbor_encode_byte_string(&map, svcCbor, svcCborSize);
-        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SVC Value.");
-    }
     if (credCborSize > 0)
     {
         cborEncoderResult = cbor_encode_text_string(&map, OIC_JSON_CRED_NAME, strlen(OIC_JSON_CRED_NAME));
@@ -301,7 +279,6 @@ exit:
     OICFree(doxmCbor);
     OICFree(pstatCbor);
     OICFree(amaclCbor);
-    OICFree(svcCbor);
     OICFree(credCbor);
     OICFree(jsonStr);
     return ;
@@ -608,7 +585,7 @@ OicSecDoxm_t* JSONToDoxmBin(const char * jsonStr)
         doxm->owned = jsonObj->valueint;
     }
 
-#ifdef _ENABLE_MULTIPLE_OWNER_
+#ifdef MULTIPLE_OWNER
     //mom -- Not Mandatory
     jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_MOM_NAME);
     if (jsonObj)
@@ -618,7 +595,7 @@ OicSecDoxm_t* JSONToDoxmBin(const char * jsonStr)
         VERIFY_NON_NULL(TAG, doxm->mom, ERROR);
         doxm->mom->mode = (OicSecMomType_t)jsonObj->valueint;
     }
-#endif //_ENABLE_MULTIPLE_OWNER_
+#endif //MULTIPLE_OWNER
 
     //DeviceId -- Mandatory
     jsonObj = cJSON_GetObjectItem(jsonDoxm, OIC_JSON_DEVICE_ID_NAME);
@@ -856,7 +833,7 @@ OicSecCred_t * JSONToCredBin(const char * jsonStr)
             {
                 cJSON *jsonPriv = cJSON_GetObjectItem(jsonObj, OIC_JSON_DATA_NAME);
                 VERIFY_NON_NULL(TAG, jsonPriv, ERROR);
-                jsonObjLen = strlen(jsonPriv->valuestring);
+                jsonObjLen = strlen(jsonPriv->valuestring) + 1;
                 cred->privateData.data = (uint8_t *)OICCalloc(1, jsonObjLen);
                 VERIFY_NON_NULL(TAG, (cred->privateData.data), ERROR);
                 memcpy(cred->privateData.data, jsonPriv->valuestring, jsonObjLen);
@@ -874,7 +851,7 @@ OicSecCred_t * JSONToCredBin(const char * jsonStr)
             {
                 cJSON *jsonPub = cJSON_GetObjectItem(jsonObj, OIC_JSON_DATA_NAME);
                 VERIFY_NON_NULL(TAG, jsonPub, ERROR);
-                jsonObjLen = strlen(jsonPub->valuestring);
+                jsonObjLen = strlen(jsonPub->valuestring) + 1;
                 cred->publicData.data = (uint8_t *)OICCalloc(1, jsonObjLen);
                 VERIFY_NON_NULL(TAG, (cred->publicData.data), ERROR);
                 memcpy(cred->publicData.data, jsonPub->valuestring, jsonObjLen);
@@ -887,7 +864,7 @@ OicSecCred_t * JSONToCredBin(const char * jsonStr)
             {
                 cJSON *jsonOpt = cJSON_GetObjectItem(jsonObj, OIC_JSON_DATA_NAME);
                 VERIFY_NON_NULL(TAG, jsonOpt, ERROR);
-                jsonObjLen = strlen(jsonOpt->valuestring);
+                jsonObjLen = strlen(jsonOpt->valuestring) + 1;
                 cred->optionalData.data =  (uint8_t *)OICCalloc(1, jsonObjLen);
                 VERIFY_NON_NULL(TAG, (cred->optionalData.data), ERROR);
                 memcpy(cred->optionalData.data, jsonOpt->valuestring, jsonObjLen);
@@ -896,6 +873,10 @@ OicSecCred_t * JSONToCredBin(const char * jsonStr)
                 cJSON *jsonEncoding = cJSON_GetObjectItem(jsonObj, OIC_JSON_ENCODING_NAME);
                 VERIFY_NON_NULL(TAG, jsonEncoding, ERROR);
                 cred->optionalData.encoding = GetEncodingTypeFromStr(jsonEncoding->valuestring);
+
+                cJSON *jsonRevstat = cJSON_GetObjectItem(jsonObj, OIC_JSON_REVOCATION_STATUS_NAME);
+                VERIFY_NON_NULL(TAG, jsonRevstat, ERROR);
+                cred->optionalData.revstat = jsonObj->valueint;
             }
 
             //CredUsage
@@ -940,104 +921,6 @@ exit:
     return headCred;
 }
 
-static OicSecSvc_t* JSONToSvcBin(const char * jsonStr)
-{
-    OCStackResult ret = OC_STACK_ERROR;
-    OicSecSvc_t * headSvc = NULL;
-    OicSecSvc_t * prevSvc = NULL;
-    cJSON *jsonRoot = NULL;
-    cJSON *jsonSvcArray = NULL;
-
-    VERIFY_NON_NULL(TAG, jsonStr, ERROR);
-
-    jsonRoot = cJSON_Parse(jsonStr);
-    VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
-
-    jsonSvcArray = cJSON_GetObjectItem(jsonRoot, OIC_JSON_SVC_NAME);
-    VERIFY_NON_NULL(TAG, jsonSvcArray, INFO);
-
-    if (cJSON_Array == jsonSvcArray->type)
-    {
-        int numSvc = cJSON_GetArraySize(jsonSvcArray);
-        int idx = 0;
-
-        VERIFY_SUCCESS(TAG, numSvc > 0, INFO);
-        do
-        {
-            cJSON *jsonSvc = cJSON_GetArrayItem(jsonSvcArray, idx);
-            VERIFY_NON_NULL(TAG, jsonSvc, ERROR);
-
-            OicSecSvc_t *svc = (OicSecSvc_t*)OICCalloc(1, sizeof(OicSecSvc_t));
-            VERIFY_NON_NULL(TAG, svc, ERROR);
-
-            headSvc = (headSvc) ? headSvc : svc;
-            if (prevSvc)
-            {
-                prevSvc->next = svc;
-            }
-
-            cJSON *jsonObj = NULL;
-            unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {};
-            uint32_t outLen = 0;
-            B64Result b64Ret = B64_OK;
-
-            // Service Device Identity
-            jsonObj = cJSON_GetObjectItem(jsonSvc, OIC_JSON_SERVICE_DEVICE_ID);
-            VERIFY_NON_NULL(TAG, jsonObj, ERROR);
-            VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
-            outLen = 0;
-            b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff,
-                       sizeof(base64Buff), &outLen);
-            VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(svc->svcdid.id)), ERROR);
-            memcpy(svc->svcdid.id, base64Buff, outLen);
-
-            // Service Type
-            jsonObj = cJSON_GetObjectItem(jsonSvc, OIC_JSON_SERVICE_TYPE);
-            VERIFY_NON_NULL(TAG, jsonObj, ERROR);
-            VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
-            svc->svct = (OicSecSvcType_t)jsonObj->valueint;
-
-            // Resource Owners
-            jsonObj = cJSON_GetObjectItem(jsonSvc, OIC_JSON_OWNERS_NAME);
-            VERIFY_NON_NULL(TAG, jsonObj, ERROR);
-            VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR);
-
-            svc->ownersLen = (size_t)cJSON_GetArraySize(jsonObj);
-            VERIFY_SUCCESS(TAG, svc->ownersLen > 0, ERROR);
-            svc->owners = (OicUuid_t*)OICCalloc(svc->ownersLen, sizeof(OicUuid_t));
-            VERIFY_NON_NULL(TAG, (svc->owners), ERROR);
-
-            size_t idxx = 0;
-            do
-            {
-                cJSON *jsonOwnr = cJSON_GetArrayItem(jsonObj, idxx);
-                VERIFY_NON_NULL(TAG, jsonOwnr, ERROR);
-                VERIFY_SUCCESS(TAG, cJSON_String == jsonOwnr->type, ERROR);
-                outLen = 0;
-                b64Ret = b64Decode(jsonOwnr->valuestring, strlen(jsonOwnr->valuestring), base64Buff,
-                           sizeof(base64Buff), &outLen);
-
-                VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(svc->owners[idxx].id)),
-                                   ERROR);
-                memcpy(svc->owners[idxx].id, base64Buff, outLen);
-            } while ( ++idxx < svc->ownersLen);
-
-            prevSvc = svc;
-        } while( ++idx < numSvc);
-    }
-
-    ret = OC_STACK_OK;
-
-exit:
-    cJSON_Delete(jsonRoot);
-    if (OC_STACK_OK != ret)
-    {
-        DeleteSVCList(headSvc);
-        headSvc = NULL;
-    }
-    return headSvc;
-}
-
 static OicSecAmacl_t* JSONToAmaclBin(const char * jsonStr)
 {
     OCStackResult ret = OC_STACK_ERROR;
diff --git a/resource/csdk/security/tool/svrdbeditor_src/svrdbeditor.c b/resource/csdk/security/tool/svrdbeditor_src/svrdbeditor.c
new file mode 100644 (file)
index 0000000..944a8c1
--- /dev/null
@@ -0,0 +1,333 @@
+/* *****************************************************************
+ *
+ * Copyright 2017 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 <string.h>
+
+#include "octypes.h"
+#include "ocstack.h"
+#include "psinterface.h"
+
+#include "credresource.h"
+
+#include "svrdbeditorcommon.h"
+#include "svrdbeditoracl.h"
+#include "svrdbeditorcred.h"
+#include "svrdbeditordoxm.h"
+#include "svrdbeditorpstat.h"
+
+static bool g_allowedEditMenu[SVR_EDIT_IDX_SIZE] = {false/*unused*/, false, false, false, false};
+static char g_svrDbPath[SVR_DB_PATH_LENGTH];
+
+typedef enum OperationType
+{
+    SVR_PRINT_ALL = 1,
+    SVR_EDIT_CRED,
+    SVR_EDIT_ACL,
+    SVR_EDIT_DOXM,
+    SVR_EDIT_PSTAT = 5,
+    EXIT = 99
+} OperationType_t;
+
+static int MainOperation(const char *svrpath);
+static void PrintMainMenu(void);
+static void PrintEditMenu(const char *resourceName, bool print, bool add, bool remove,
+                          bool modify);
+static void PrintHelp(void);
+static FILE *SVRDBFopen(const char *path, const char *mode);
+
+int main(int argc, char *argv[])
+{
+    if (2 == argc)
+    {
+        PRINT_NORMAL("SVR DB File Path: %s\n", argv[1]);
+        return MainOperation(argv[1]);
+    }
+    else
+    {
+        PrintHelp();
+        return 0;
+    }
+}
+
+static int MainOperation(const char *svrpath)
+{
+    OperationType_t menu = EXIT;
+    SubOperationType_t editMenu = EXIT;
+    OCStackResult ocResult = OC_STACK_ERROR;
+    bool run = true;
+
+    // initialize persistent storage for SVR DB
+    static OCPersistentStorage psInst =
+    {
+        .open = SVRDBFopen,
+        .read = fread,
+        .write = fwrite,
+        .close = fclose,
+        .unlink = unlink
+    };
+
+    if (!svrpath)
+    {
+        PRINT_ERR("Incorrect file path");
+        return -1;
+    }
+
+    strncpy(g_svrDbPath, svrpath, sizeof(g_svrDbPath) - 1);
+    g_svrDbPath[sizeof(g_svrDbPath) - 1] = '\0';
+
+    ocResult = InitPersistentStorageInterface();
+    if (OC_STACK_OK != ocResult)
+    {
+        PRINT_ERR("InitPersistentStorageInterface error : %d", ocResult);
+        return -1;
+    }
+
+    ocResult = OCRegisterPersistentStorageHandler(&psInst);
+    if (OC_STACK_OK != ocResult)
+    {
+        PRINT_ERR("OCRegisterPersistentStorageHandler : %d", ocResult);
+        return -1;
+    }
+    RefreshACL();
+    RefreshCred();
+    RefreshDoxm();
+    RefreshPstat();
+    while (run)
+    {
+        PrintMainMenu();
+        menu = (OperationType_t)InputNumber("\tSelect the menu : ");
+        switch (menu)
+        {
+            case SVR_PRINT_ALL:
+                PrintDoxm();
+                PrintPstat();
+                PrintAcl();
+                PrintCredList(GetCredList());
+                break;
+            case SVR_EDIT_CRED:
+                for (;;)
+                {
+                    if (NULL == GetCredList())
+                    {
+                        PRINT_WARN("Credential resource is empty.");
+                        PrintEditMenu("Credential Resource", false, true, false, false);
+                    }
+                    else
+                    {
+                        PrintEditMenu("Credential Resource", true, true, true, true);
+                    }
+                    editMenu = (SubOperationType_t)InputNumber("Select the menu : ");
+                    if (0 < editMenu && editMenu < SVR_EDIT_IDX_SIZE)
+                    {
+                        if (!g_allowedEditMenu[editMenu])
+                        {
+                            PRINT_ERR("Disabled menu");
+                            continue;
+                        }
+                    }
+                    else if (BACK == editMenu)
+                    {
+                        PRINT_INFO("Back to the previous menu.");
+                        break;
+                    }
+                    else
+                    {
+                        PRINT_ERR("Invalid menu");
+                        continue;
+                    }
+                    HandleCredOperation(editMenu);
+                    RefreshCred();
+                }
+                break;
+            case SVR_EDIT_ACL:
+                for (;;)
+                {
+                    PrintEditMenu("ACL Resource", true, true, true, true);
+                    editMenu = (SubOperationType_t)InputNumber("Select the menu : ");
+                    if (0 < editMenu && editMenu < SVR_EDIT_IDX_SIZE)
+                    {
+                        if (!g_allowedEditMenu[editMenu])
+                        {
+                            PRINT_ERR("Disabled menu");
+                            continue;
+                        }
+                    }
+                    else if (BACK == editMenu)
+                    {
+                        PRINT_INFO("Back to the previous menu.");
+                        break;
+                    }
+                    else
+                    {
+                        PRINT_ERR("Invalid menu");
+                        continue;
+                    }
+                    HandleAclOperation(editMenu);
+                    RefreshACL();
+                }
+                break;
+            case SVR_EDIT_DOXM:
+                for (;;)
+                {
+                    PrintEditMenu("Doxm Resource", true, true, true, true);
+                    editMenu = (SubOperationType_t)InputNumber("Select the menu : ");
+                    if (0 < editMenu && editMenu < SVR_EDIT_IDX_SIZE)
+                    {
+                        if (!g_allowedEditMenu[editMenu])
+                        {
+                            PRINT_ERR("Disabled menu");
+                            continue;
+                        }
+                    }
+                    else if (BACK == editMenu)
+                    {
+                        PRINT_INFO("Back to the previous menu.");
+                        break;
+                    }
+                    else
+                    {
+                        PRINT_ERR("Invalid menu");
+                        continue;
+                    }
+                    HandleDoxmOperation(editMenu);
+                    RefreshDoxm();
+                }
+                break;
+            case SVR_EDIT_PSTAT:
+                for (;;)
+                {
+                    PrintEditMenu("Pstat Resource", true, true, true, true);
+                    editMenu = (SubOperationType_t)InputNumber("Select the menu : ");
+                    if (0 < editMenu && editMenu < SVR_EDIT_IDX_SIZE)
+                    {
+                        if (!g_allowedEditMenu[editMenu])
+                        {
+                            PRINT_ERR("Disabled menu");
+                            continue;
+                        }
+                    }
+                    else if (BACK == editMenu)
+                    {
+                        PRINT_INFO("Back to the previous menu.");
+                        break;
+                    }
+                    else
+                    {
+                        PRINT_ERR("Invalid menu");
+                        continue;
+                    }
+                    HandlePstatOperation(editMenu);
+                    RefreshPstat();
+                }
+                break;
+            case EXIT:
+                run = false;
+                break;
+            default:
+                PRINT_ERR("Unknown operation");
+                PRINT_ERR("Please make sure the menu.");
+                break;
+        }
+    }
+
+    DeInitCredResource();
+    DeInitACL();
+    DeInitDoxm();
+    DeInitPstat();
+    return 0;
+}
+
+static FILE *SVRDBFopen(const char *path, const char *mode)
+{
+    (void)path;  // unused |path| parameter
+    return fopen(g_svrDbPath, mode);
+}
+
+static void PrintHelp(void)
+{
+    PRINT_ERR("<This program requires one input>");
+    PRINT_INFO("./svrdbeditor <svr_db_file_path>");
+}
+
+static void PrintEditMenu(const char *resourceName, bool print, bool add, bool remove,
+                          bool modify)
+{
+    PRINT_PROG("\n\nYou can perform the "
+               CYAN_BEGIN "cyan color opertions " COLOR_END
+               BOLD_BEGIN "for" COLOR_END
+               YELLOW_BEGIN " %s" COLOR_END_NL, resourceName);
+
+    for (int i = 0; i < SVR_EDIT_IDX_SIZE; i++)
+    {
+        g_allowedEditMenu[i] = false;
+    }
+    if (print)
+    {
+        g_allowedEditMenu[SVR_PRINT] = true;
+        PRINT_DATA("\t%2d. Print all entities\n", SVR_PRINT);
+    }
+    else
+    {
+        PRINT_NORMAL("\t%2d. Print all entities\n", SVR_PRINT);
+    }
+
+    if (add)
+    {
+        g_allowedEditMenu[SVR_ADD] = true;
+        PRINT_DATA("\t%2d. Add entity\n", SVR_ADD);
+    }
+    else
+    {
+        PRINT_NORMAL("\t%2d. Add entity\n", SVR_ADD);
+    }
+    if (remove)
+    {
+        g_allowedEditMenu[SVR_REMOVE] = true;
+        PRINT_DATA("\t%2d. Remove entity\n", SVR_REMOVE);
+    }
+    else
+    {
+        PRINT_NORMAL("\t%2d. Remove entity\n", SVR_REMOVE);
+    }
+
+    if (modify)
+    {
+        g_allowedEditMenu[SVR_MODIFY] = true;
+        PRINT_DATA("\t%2d. Modify entity\n", SVR_MODIFY);
+    }
+    else
+    {
+        PRINT_NORMAL("\t%2d. Modify entity\n", SVR_MODIFY);
+    }
+    PRINT_DATA("\t%2d. Back to the main menu\n", BACK);
+}
+
+static void PrintMainMenu(void)
+{
+    PRINT_PROG("\n\nYou can perform the "
+               CYAN_BEGIN "cyan color opertions : " COLOR_END_NL);
+
+    PRINT_DATA("\t%2d. Print All Security Resource.\n", SVR_PRINT_ALL);
+    PRINT_DATA("\t%2d. Edit Credential Resource.\n", SVR_EDIT_CRED);
+    PRINT_DATA("\t%2d. Edit ACL Resource.\n", SVR_EDIT_ACL);
+    PRINT_DATA("\t%2d. Edit Doxm Resource.\n", SVR_EDIT_DOXM);
+    PRINT_DATA("\t%2d. Edit Pstat Resource.\n", SVR_EDIT_PSTAT);
+    PRINT_DATA("\t%2d. Exit.\n", EXIT);
+}
diff --git a/resource/csdk/security/tool/svrdbeditor_src/svrdbeditoracl.c b/resource/csdk/security/tool/svrdbeditor_src/svrdbeditoracl.c
new file mode 100644 (file)
index 0000000..9d26b38
--- /dev/null
@@ -0,0 +1,812 @@
+/* *****************************************************************
+ *
+ * Copyright 2017 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 <stdbool.h>
+
+#include "utlist.h"
+#include "octypes.h"
+#include "oic_malloc.h"
+
+#include "psinterface.h"
+
+#include "srmresourcestrings.h"
+#include "security_internals.h"
+#include "aclresource.h"
+
+#include "svrdbeditoracl.h"
+
+#define ACL_PEMISN_CNT (5)
+#define ACE_MAX_ENTITY (256)
+
+static OicSecAcl_t *g_acl = NULL;
+
+typedef enum AclModifyType
+{
+    ACL_MODIFY_ACE = 1,
+    ACL_EDIT_ROWNERID = 2
+} AclModifyType_t;
+typedef enum AceModifyType
+{
+    ACE_EDIT_SUBJECT = 1,
+    ACE_ADD_RESOURCE,
+    ACE_REMOVE_RESOURCE,
+    ACE_EDIT_RESOURCE,
+    ACE_EDIT_PERMISSION = 5
+} AceModifyType_t;
+
+void DeInitACL(void)
+{
+    if (g_acl)
+    {
+        DeleteACLList(g_acl);
+        g_acl = NULL;
+    }
+}
+
+void RefreshACL(void)
+{
+    OicSecAcl_t *tmpACL = NULL;
+    uint8_t *secPayload = NULL;
+    size_t payloadSize = 0;
+    OCStackResult ocResult = OC_STACK_ERROR;
+    ocResult = GetSecureVirtualDatabaseFromPS(OIC_JSON_ACL_NAME, &secPayload, &payloadSize);
+    if (OC_STACK_OK != ocResult)
+    {
+        PRINT_WARN("Failed GetSecureVirtualDatabaseFromPS");
+        return;
+    }
+
+    tmpACL = CBORPayloadToAcl(secPayload, payloadSize);
+    if (NULL == tmpACL)
+    {
+        PRINT_ERR("Failed CBORPayloadToAcl");
+        OICFree(secPayload);
+        return;
+    }
+    OICFree(secPayload);
+
+    if (g_acl)
+    {
+        DeInitACL();
+    }
+    g_acl = tmpACL;
+}
+
+static void UpdateACL(void)
+{
+    OCStackResult aclResult = OC_STACK_ERROR;
+    uint8_t *aclPayload = NULL;
+    size_t aclPayloadSize = 0;
+
+    aclResult = AclToCBORPayload(g_acl, &aclPayload, &aclPayloadSize);
+    if (OC_STACK_OK != aclResult)
+    {
+        PRINT_ERR("AclToCBORPayload error : %d" , aclResult);
+        return;
+    }
+    aclResult = UpdateSecureResourceInPS(OIC_JSON_ACL_NAME, aclPayload, aclPayloadSize);
+    if (OC_STACK_OK != aclResult)
+    {
+        PRINT_ERR("UpdateSecureResourceInPS error : %d" , aclResult);
+        OICFree(aclPayload);
+        return;
+    }
+    OICFree(aclPayload);
+}
+
+static void FreeACE(OicSecAce_t *ace)
+{
+    if (NULL == ace)
+    {
+        PRINT_ERR("Invalid parameter");
+        return;
+    }
+
+    //Clean Resources
+    OicSecRsrc_t *rsrc = NULL;
+    OicSecRsrc_t *tmpRsrc = NULL;
+    LL_FOREACH_SAFE(ace->resources, rsrc, tmpRsrc)
+    {
+        LL_DELETE(ace->resources, rsrc);
+        FreeRsrc(rsrc);
+    }
+
+    OicSecValidity_t *validity = NULL;
+    OicSecValidity_t *tmpValidity = NULL;
+    LL_FOREACH_SAFE(ace->validities, validity, tmpValidity)
+    {
+        LL_DELETE(ace->validities, validity);
+
+        //Clean period
+        OICFree(validity->period);
+
+        //Clean recurrence
+        for (size_t i = 0; i < validity->recurrenceLen; i++)
+        {
+            OICFree(validity->recurrences[i]);
+        }
+        OICFree(validity->recurrences);
+        OICFree(validity);
+        validity = NULL;
+    }
+
+#ifdef MULTIPLE_OWNER
+    OICFree(ace->eownerID);
+#endif
+    OICFree(ace);
+}
+
+static void PrintValidity(const OicSecValidity_t *validities)
+{
+    const OicSecValidity_t *validity = NULL;
+    const OicSecValidity_t *tempValidity = NULL;
+    size_t validityCnt = 0;
+
+    LL_FOREACH_SAFE(validities, validity, tempValidity)
+    {
+        PRINT_DATA("Validity #%zu:\n", validityCnt + 1);
+        PRINT_DATA("%10s : %s\n", OIC_JSON_PERIOD_NAME, validity->period);
+        PRINT_DATA("%10s : ", OIC_JSON_RESOURCES_NAME);
+        PrintStringArray((const char **)validity->recurrences, validity->recurrenceLen);
+        validityCnt++;
+    }
+}
+
+static void PrintPermission(uint16_t permission)
+{
+    PRINT_DATA("%d (", permission);
+
+    if (0 == permission)
+    {
+        PRINT_DATA(" NO PERMISSION");
+    }
+    else
+    {
+        if (permission & PERMISSION_CREATE)
+        {
+            PRINT_DATA(" CREATE ");
+        }
+        if (permission & PERMISSION_READ)
+        {
+            PRINT_DATA(" READ ");
+        }
+        if (permission & PERMISSION_WRITE)
+        {
+            PRINT_DATA(" WRITE ");
+        }
+        if (permission & PERMISSION_DELETE)
+        {
+            PRINT_DATA(" DELETE ");
+        }
+        if (permission & PERMISSION_NOTIFY)
+        {
+            PRINT_DATA(" NOTIFY ");
+        }
+    }
+
+    PRINT_DATA(") \n");
+}
+
+static size_t PrintResourceList(const OicSecRsrc_t *rsrcList)
+{
+    const OicSecRsrc_t *rsrc = NULL;
+    const OicSecRsrc_t *tempRsrc = NULL;
+    size_t rsrcCnt = 0;
+
+    LL_FOREACH_SAFE(rsrcList, rsrc, tempRsrc)
+    {
+        PRINT_DATA("Resource #%zu:\n", rsrcCnt + 1);
+        PRINT_DATA("%10s : %s\n", OIC_JSON_HREF_NAME, rsrc->href);
+        PRINT_DATA("%10s : %s\n", OIC_JSON_REL_NAME, rsrc->rel);
+        PRINT_DATA("%10s : ", OIC_JSON_RT_NAME);
+        PrintStringArray((const char **)rsrc->types, rsrc->typeLen);
+        PRINT_DATA("%10s : ", OIC_JSON_IF_NAME);
+        PrintStringArray((const char **)rsrc->interfaces, rsrc->interfaceLen);
+        rsrcCnt++;
+    }
+    return rsrcCnt;
+}
+
+
+static int PrintAce(const OicSecAce_t *ace)
+{
+    PRINT_PROG("%15s : ", OIC_JSON_SUBJECT_NAME);
+    if (memcmp(&(ace->subjectuuid), &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t)) == 0)
+    {
+        PrintString((char *)WILDCARD_SUBJECT_ID.id);
+    }
+    else
+    {
+        PrintUuid(&(ace->subjectuuid));
+    }
+
+#ifdef MULTIPLE_OWNER
+    if (ace->eownerID)
+    {
+        PRINT_PROG("%15s : ", OIC_JSON_EOWNERID_NAME);
+        PrintUuid(&(ace->subjectuuid));
+    }
+#endif
+
+    //permission
+    PRINT_PROG("%15s : ", OIC_JSON_PERMISSION_NAME);
+    PrintPermission(ace->permission);
+
+    //resource list
+    PRINT_PROG("%15s : \n", OIC_JSON_RESOURCES_NAME);
+    PrintResourceList(ace->resources);
+
+    //Validity
+    PrintValidity(ace->validities);
+
+    return 0;
+}
+
+size_t PrintAcl(void)
+{
+    OicSecAce_t *ace = NULL;
+    OicSecAce_t *tempAce = NULL;
+    bool isEmptyList = true;
+    size_t aceCnt = 0;
+
+    PRINT_INFO("\n\n********************* [%-20s] *********************",
+               "ACL Resource");
+    if (g_acl)
+    {
+        LL_FOREACH_SAFE(g_acl->aces, ace, tempAce)
+        {
+            PRINT_INFO("[ACE #%zu]", ++aceCnt);
+            if (0 != PrintAce(ace))
+            {
+                return aceCnt;
+            }
+            PRINT_PROG("------------------------------------------------------------------\n");
+            isEmptyList = false;
+        }
+
+        if (isEmptyList)
+        {
+            PRINT_PROG("ACE is empty.\n");
+            PRINT_PROG("------------------------------------------------------------------\n");
+        }
+        PRINT_PROG("%15s : ", OIC_JSON_ROWNERID_NAME);
+        PrintUuid(&(g_acl->rownerID));
+    }
+    else
+    {
+        PRINT_PROG("ACL is empty.\n");
+    }
+
+    PRINT_INFO("********************* [%-20s] *********************",
+               "ACL Resource");
+
+    return aceCnt;
+}
+
+static int InputSubjectUuid(OicSecAce_t *ace)
+{
+    int ret = 0;
+
+    PRINT_DATA("\tInput the Subject UUID for this access (e.g. 61646D69-6E44-6576-6963-655575696430) : ");
+    ret = InputUuid(&ace->subjectuuid);
+    if (0 != ret)
+    {
+        PRINT_ERR("Failed InputUuid");
+        return ret;
+    }
+    return ret;
+}
+
+static int InputResources(OicSecRsrc_t *resources)
+{
+    size_t i = 0;
+    char *href = NULL;
+    char **types = NULL;
+    size_t typeLen = 0;
+    char **interfaces = NULL;
+    size_t interfaceLen = 0;
+
+    if (NULL == resources)
+    {
+        PRINT_ERR("Invalid parameter");
+        return -1;
+    }
+    // input href
+    href = InputString("\tInput the resource URI : ");
+    if (NULL == href)
+    {
+        PRINT_ERR("Failed InputString");
+        return -1;
+    }
+
+    // input types
+    PRINT_PROG("\tInput the number of resource type for %s (MAX : %d): ", href,
+               SVR_MAX_ENTITY);
+    typeLen = InputNumber("");
+    if (0 == typeLen || SVR_MAX_ENTITY < typeLen)
+    {
+        PRINT_ERR("Invalid number");
+        OICFree(href);
+        return -1;
+    }
+    types = (char **)OICCalloc(typeLen, sizeof(char *));
+    if (NULL == types)
+    {
+        PRINT_ERR("Failed to allocate memory");
+        OICFree(href);
+        return -1;
+    }
+
+    for (i = 0; i < typeLen; i++)
+    {
+        PRINT_PROG("\tInput the resource type name #%zu : ", i + 1);
+        types[i] = InputString("");
+        if (NULL == types[i] )
+        {
+            PRINT_ERR("Failed InputString");
+            OICFree(href);
+            for (size_t j = 0; j < i; j++)
+            {
+                OICFree(types[j]);
+            }
+            OICFree(types);
+            return -1;
+        }
+    }
+    // input interfaces
+    PRINT_PROG("\tInput the number of interface for %s (MAX : %d): ", href, SVR_MAX_ENTITY);
+    interfaceLen = InputNumber("");
+    if (0 == interfaceLen || SVR_MAX_ENTITY < interfaceLen)
+    {
+        PRINT_ERR("Invalid number");
+        OICFree(href);
+        for (size_t j = 0; j < typeLen; j++)
+        {
+            OICFree(types[j]);
+        }
+        OICFree(types);
+        return -1;
+    }
+    interfaces = (char **)OICCalloc(interfaceLen, sizeof(char *));
+    if (NULL == interfaces)
+    {
+        PRINT_ERR("Failed to allocate memory");
+        OICFree(href);
+        for (size_t j = 0; j < typeLen; j++)
+        {
+            OICFree(types[j]);
+        }
+        OICFree(types);
+        return -1;
+
+    }
+
+    for (i = 0; i < interfaceLen; i++)
+    {
+        PRINT_PROG("\tInput the interface name #%zu : ", i + 1);
+        interfaces[i] = InputString("");
+        if (NULL == interfaces[i] )
+        {
+            PRINT_ERR("Failed InputString");
+            OICFree(href);
+            for (size_t j = 0; j < typeLen; j++)
+            {
+                OICFree(types[j]);
+            }
+            OICFree(types);
+
+            for (size_t j = 0; j < i; j++)
+            {
+                OICFree(interfaces[j]);
+            }
+            OICFree(interfaces);
+            return -1;
+        }
+    }
+
+    // free before assign
+    OICFree(resources->href);
+    if (0 < resources->typeLen && resources->types)
+    {
+        for (i = 0; i < resources->typeLen; i++)
+        {
+            OICFree(resources->types[i]);
+        }
+        OICFree(resources->types);
+    }
+    if (0 < resources->interfaceLen && resources->interfaces)
+    {
+        for (i = 0; i < resources->interfaceLen; i++)
+        {
+            OICFree(resources->interfaces[i]);
+        }
+        OICFree(resources->interfaces);
+    }
+
+    // assign to real
+    resources->href = href;
+    resources->typeLen = typeLen;
+    resources->types = types;
+    resources->interfaceLen = interfaceLen;
+    resources->interfaces = interfaces;
+    return 0;
+}
+
+static uint16_t InputAccessPermission(void)
+{
+    uint16_t pmsn = PERMISSION_FULL_CONTROL;  // default full permission
+    uint16_t pmsn_msk = PERMISSION_CREATE;  // default permission mask
+    const char *ACL_PEMISN[ACL_PEMISN_CNT] = {"CREATE", "READ", "WRITE", "DELETE", "NOTIFY"};
+
+    for (int i = 0; i < ACL_PEMISN_CNT; i++)
+    {
+        char ans = 0;
+        for ( ; ; )
+        {
+            PRINT_NORMAL("\tEnter %s Permission (y/n): ", ACL_PEMISN[i]);
+            for (int ret = 0; 1 != ret; )
+            {
+                ret = scanf("%c", &ans);
+                for ( ; 0x20 <= getchar(); ); // for removing overflow garbages
+                // '0x20<=code' is character region
+            }
+            if ('y' == ans || 'Y' == ans || 'n' == ans || 'N' == ans)
+            {
+                ans &= ~0x20;  // for masking lower case, 'y/n'
+                break;
+            }
+            PRINT_NORMAL("\tEntered Wrong Answer. Please Enter 'y/n' Again\n");
+        }
+        if ('N' == ans)  // masked lower case, 'n'
+        {
+            pmsn -= pmsn_msk;
+        }
+        pmsn_msk <<= 1;
+    }
+    return pmsn;
+}
+
+int InputAceData(OicSecAce_t *ace)
+{
+    int ret = 0;
+    size_t numOfRsrc = 0;
+
+    PRINT_PROG("\n\nPlease input the each entity of new ACE.\n");
+
+    ret = InputSubjectUuid(ace);
+    if (0 != ret)
+    {
+        PRINT_ERR("Failed InputSubjectUuid");
+        return ret;
+    }
+    PRINT_PROG("\tInput the number of resource for this access : ");
+    numOfRsrc = InputNumber("");
+    if (SVR_MAX_ENTITY < numOfRsrc)
+    {
+        PRINT_ERR("Invalid number");
+        return -1;
+    }
+
+    for (size_t i = 0; i < numOfRsrc; i++)
+    {
+        PRINT_PROG("Please input the resource information for resource #%zu\n", i + 1);
+        OicSecRsrc_t *rsrc = (OicSecRsrc_t *)OICCalloc(1, sizeof(OicSecRsrc_t));
+        if (NULL == rsrc)
+        {
+            PRINT_ERR("Failed to allocate memory");
+            return -1;
+        }
+
+        ret = InputResources(rsrc);
+        if (0 != ret)
+        {
+            PRINT_ERR("Failed InputResources");
+            OICFree(rsrc);
+            return ret;
+        }
+        LL_APPEND(ace->resources, rsrc);
+    }
+
+    PRINT_PROG("\tSelect permission for this access.\n");
+    ace->permission = InputAccessPermission();
+
+#ifdef MULTIPLE_OWNER
+    // TODO: Input eowner
+#endif
+
+    // TODO: Input the validity (T.B.D)
+
+    return 0;
+}
+
+static int ModifyAce(OicSecAce_t *ace)
+{
+    int ret = 0;
+    int modifyMenu = 0;
+
+    size_t sizeOfRsrc = 0;
+    size_t curIdx = 0;
+    size_t rsrcIdx = 0;
+    OicSecRsrc_t *rsrc = NULL;
+    OicSecRsrc_t *tmpRsrc = NULL;
+
+    PRINT_PROG("\n\nPlease input the attribute you want to modify\n");
+    PRINT_DATA("\t%2d. Edit subject\n", ACE_EDIT_SUBJECT);
+    PRINT_DATA("\t%2d. Add resources \n", ACE_ADD_RESOURCE);
+    PRINT_DATA("\t%2d. Remove resources \n", ACE_REMOVE_RESOURCE);
+    PRINT_DATA("\t%2d. Edit resources \n", ACE_EDIT_RESOURCE);
+    PRINT_DATA("\t%2d. Edit permission\n", ACE_EDIT_PERMISSION);
+    PRINT_DATA("\t%2d. Back to the previous\n", BACK);
+    modifyMenu = InputNumber("Select the menu : ");
+    switch (modifyMenu)
+    {
+        case ACE_EDIT_SUBJECT:
+            ret = InputSubjectUuid(ace);
+            if (0 != ret)
+            {
+                PRINT_ERR("InputSubjectType error");
+                return ret;
+            }
+            break;
+        case ACE_ADD_RESOURCE :
+            PRINT_PROG("Please input the resource information for resource to add\n");
+            rsrc = (OicSecRsrc_t *)OICCalloc(1, sizeof(OicSecRsrc_t));
+            if (NULL == rsrc)
+            {
+                PRINT_ERR("Failed to allocate memory");
+                return -1;
+            }
+
+            ret = InputResources(rsrc);
+            if (0 != ret)
+            {
+                PRINT_ERR("InputResources error");
+                OICFree(rsrc);
+                return ret;
+            }
+            LL_APPEND(ace->resources, rsrc);
+            break;
+        case ACE_REMOVE_RESOURCE:
+            sizeOfRsrc = PrintResourceList(ace->resources);
+            rsrcIdx = InputNumber("\tInput the number of resource to remove : ");
+            if (0 == rsrcIdx || sizeOfRsrc < rsrcIdx)
+            {
+                PRINT_ERR("Invalid number");
+                return -1;
+            }
+            LL_FOREACH_SAFE(ace->resources, rsrc, tmpRsrc)
+            {
+                if (rsrcIdx == ++curIdx)
+                {
+                    LL_DELETE(ace->resources, rsrc);
+                    FreeRsrc(rsrc);
+                    break;
+                }
+            }
+            break;
+        case ACE_EDIT_RESOURCE:
+            sizeOfRsrc = PrintResourceList(ace->resources);
+            PRINT_PROG("\tInput the number of resource to edit : ");
+            rsrcIdx = InputNumber("");
+            if (0 == rsrcIdx || sizeOfRsrc < rsrcIdx)
+            {
+                PRINT_ERR("Invalid number");
+                return -1;
+            }
+            LL_FOREACH_SAFE(ace->resources, rsrc, tmpRsrc)
+            {
+                if (rsrcIdx == ++curIdx)
+                {
+                    PRINT_PROG("Please input the resource information for resource #%zu\n", rsrcIdx );
+                    ret = InputResources(rsrc);
+                    if (0 != ret)
+                    {
+                        PRINT_ERR("InputResources error");
+                        return ret;
+                    }
+                    break;
+                }
+            }
+            break;
+        case ACE_EDIT_PERMISSION:
+            PRINT_PROG("\tSelect permission for this access.\n");
+            ace->permission = InputAccessPermission();
+            break;
+        case BACK:
+            PRINT_INFO("Back to the previous menu.");
+            ret = -1;
+            break;
+        default:
+            PRINT_ERR("Wrong type Number");
+            ret = -1;
+            break;
+    }
+    return ret;
+}
+
+static int ModifyAcl(void)
+{
+    int ret = 0;
+    int modifyMenu = 0;
+    OicSecAce_t *ace = NULL;
+    OicSecAce_t *tempAce = NULL;
+    size_t aclIdx = 0;
+    size_t curIdx = 0;
+    size_t numOfAce = 0;
+
+    PRINT_PROG("\n\nPlease select the menu you want to modify\n");
+    PRINT_DATA("\t%2d. Modify ACE\n", ACL_MODIFY_ACE);
+    PRINT_DATA("\t%2d. Edit rownerid\n", ACL_EDIT_ROWNERID);
+    modifyMenu = InputNumber("Select the menu : ");
+    switch (modifyMenu)
+    {
+        case ACL_MODIFY_ACE:
+            numOfAce = PrintAcl();
+            if (0 == numOfAce)
+            {
+                PRINT_ERR("empty ace");
+                return -1;
+            }
+            aclIdx = InputNumber("\tPlease input the number of ACE : ");
+            if (0 == aclIdx || numOfAce < aclIdx)
+            {
+                PRINT_ERR("Wrong number of ACE.");
+                return -1;
+            }
+
+            //Modify the ACE
+            LL_FOREACH_SAFE(g_acl->aces, ace, tempAce)
+            {
+                if (ace)
+                {
+                    //If found target ACE, modify it.
+                    if (aclIdx == ++curIdx)
+                    {
+                        if (0 != ModifyAce(ace))
+                        {
+                            PRINT_ERR("Failed to Moidfy ACE");
+                            return -1;
+                        }
+                        PRINT_INFO("\n\n[ACE #%zu] Modified", aclIdx);
+                        PrintAce(ace);
+                        break;
+                    }
+                }
+            }
+            break;
+        case ACL_EDIT_ROWNERID:
+            PRINT_PROG(
+                "\tInput the ROWNER UUID for this access (e.g. 61646D69-6E44-6576-6963-655575696430) : ");
+            ret = InputUuid(&(g_acl->rownerID));
+            if (0 != ret)
+            {
+                PRINT_ERR("InputUuid error");
+                return -1;
+            }
+            break;
+        default:
+            PRINT_ERR("Wrong type Number");
+            ret = -1;
+            break;
+    }
+    return ret;
+}
+
+void HandleAclOperation(const SubOperationType_t cmd)
+{
+    size_t aclIdx = 0;
+
+    if (NULL == g_acl)
+    {
+        g_acl = (OicSecAcl_t *) OICCalloc(1, sizeof(OicSecAcl_t));
+        if (NULL == g_acl)
+        {
+            PRINT_ERR("Failed to allocate memory");
+            return;
+        }
+    }
+    if (SVR_EDIT_IDX_SIZE <= cmd)
+    {
+        PRINT_ERR("Invalid menu for ACL");
+        return;
+    }
+    switch (cmd)
+    {
+        case SVR_PRINT:
+            PrintAcl();
+            break;
+        case SVR_ADD:
+            {
+                OicSecAce_t *ace = (OicSecAce_t *)OICCalloc(1, sizeof(OicSecAce_t));
+
+                if (NULL == ace)
+                {
+                    PRINT_ERR("Failed to allocate memory");
+                    return;
+                }
+
+                if (0 != InputAceData(ace))
+                {
+                    PRINT_ERR("Failed to input ACE");
+                    FreeACE(ace);
+                    return;
+                }
+
+                //Add ACE
+                LL_APPEND(g_acl->aces, ace);
+                UpdateACL();
+                break;
+            }
+        case SVR_REMOVE:
+            {
+                OicSecAce_t *ace = NULL;
+                OicSecAce_t *tempAce = NULL;
+                size_t curIdx = 0;
+                size_t numOfAce = 0;
+
+                numOfAce = PrintAcl();
+                if (0 == numOfAce)
+                {
+                    PRINT_ERR("empty ace");
+                    return;
+                }
+
+                aclIdx = InputNumber("\tPlease input the number of ACE : ");
+
+                if (0 == aclIdx || aclIdx > numOfAce)
+                {
+                    PRINT_ERR("Wrong number of ACE.");
+                    return;
+                }
+
+                //Revmoe the ACE
+                LL_FOREACH_SAFE(g_acl->aces, ace, tempAce)
+                {
+                    if (ace)
+                    {
+                        //If found target ACE, delete it.
+                        if (aclIdx == ++curIdx)
+                        {
+                            LL_DELETE(g_acl->aces, ace);
+                            FreeACE(ace);
+                            UpdateACL();
+                            break;
+                        }
+                    }
+                }
+                break;
+            }
+        case SVR_MODIFY:
+            if (NULL == g_acl)
+            {
+                PRINT_ERR("empty acl");
+                return;
+            }
+            if (0 != ModifyAcl())
+            {
+                PRINT_ERR("Fail ModifyAcl");
+                return;
+            }
+            UpdateACL();
+            break;
+        default:
+            break;
+    }
+}
diff --git a/resource/csdk/security/tool/svrdbeditor_src/svrdbeditoracl.h b/resource/csdk/security/tool/svrdbeditor_src/svrdbeditoracl.h
new file mode 100644 (file)
index 0000000..b7f6e96
--- /dev/null
@@ -0,0 +1,31 @@
+/* *****************************************************************
+ *
+ * Copyright 2017 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 SVRDBEDITOR_ACL_H_
+#define SVRDBEDITOR_ACL_H_
+
+#include "svrdbeditorcommon.h"
+
+void DeInitACL(void);
+void RefreshACL(void);
+size_t PrintAcl(void);
+void HandleAclOperation(const SubOperationType_t cmd);
+
+#endif /* SVRDBEDITOR_ACL_H_ */
\ No newline at end of file
diff --git a/resource/csdk/security/tool/svrdbeditor_src/svrdbeditorcommon.c b/resource/csdk/security/tool/svrdbeditor_src/svrdbeditorcommon.c
new file mode 100644 (file)
index 0000000..3c3e54c
--- /dev/null
@@ -0,0 +1,174 @@
+/* *****************************************************************
+ *
+ * Copyright 2017 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 <stdio.h>
+#include <string.h>
+
+#include "utlist.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+
+#include "srmresourcestrings.h"
+#include "securevirtualresourcetypes.h"
+#include "srmutility.h"
+
+#include "svrdbeditorcommon.h"
+
+#define STR_UUID_LENGTH (UUID_LENGTH * 2 + 4 + 1) // length + dash length  + '\0'
+#define STR_UUID_ZERO "0"
+
+void PrintUuid(const OicUuid_t *uuid)
+{
+    char *strUuid = NULL;
+    if (OC_STACK_OK == ConvertUuidToStr(uuid, &strUuid))
+    {
+        PRINT_DATA("%s\n", strUuid);
+        OICFree(strUuid);
+    }
+    else
+    {
+        PRINT_ERR("Can not convert UUID to String");
+    }
+}
+
+void PrintIntArray(const int *array, size_t length)
+{
+    for (size_t i = 0; i < length; i++)
+    {
+        PRINT_DATA("%d ", array[i]);
+    }
+    PRINT_NL();
+}
+
+void PrintStringArray(const char **array, size_t length)
+{
+    for (size_t i = 0; i < length; i++)
+    {
+        PRINT_DATA("%s ", array[i]);
+    }
+    PRINT_NL();
+}
+
+void PrintInt(int value)
+{
+    PRINT_DATA("%d\n", value);
+}
+
+void PrintString(const char *text)
+{
+    PRINT_DATA("%s\n", text);
+}
+
+void PrintBuffer(const uint8_t *buf, size_t bufLen)
+{
+    size_t i = 0;
+
+    for (i = 0; i < bufLen; i++)
+    {
+        if (0 == (i + 1) % 20 || bufLen - 1 == i)
+        {
+            PRINT_DATA("%02X \n", buf[i]);
+        }
+        else
+        {
+            PRINT_DATA("%02X ", buf[i]);
+        }
+    }
+}
+
+int InputNumber(const char *infoText)
+{
+    int inputValue = 0;
+
+    PRINT_PROG("%s", infoText);
+    for (int ret = 0; 1 != ret; )
+    {
+        ret = scanf("%d", &inputValue);
+        for ( ; 0x20 <= getchar(); ); // for removing overflow garbages
+        // '0x20<=code' is character region
+    }
+
+    return inputValue;
+}
+
+char *InputString(const char *infoText)
+{
+    char tmpStr[SVR_DB_PATH_LENGTH] = {0};
+
+    PRINT_PROG("%s", infoText);
+    for (int ret = 0; 1 != ret; )
+    {
+        ret = scanf("%1024s", tmpStr);
+        for ( ; 0x20 <= getchar(); ); // for removing overflow garbages
+        // '0x20<=code' is character region
+    }
+
+    return OICStrdup(tmpStr);
+}
+
+int InputUuid(OicUuid_t *uuid)
+{
+    OCStackResult ocResult = OC_STACK_ERROR;
+    char strUuid[STR_UUID_LENGTH] = {0};
+    size_t strLen = 0;
+
+    if (NULL == uuid)
+    {
+        PRINT_ERR("Invalid parameter");
+        return -1;
+    }
+
+    if (NULL == fgets(strUuid, STR_UUID_LENGTH, stdin))
+    {
+        PRINT_ERR("Failed fgets");
+        return -1;
+    }
+    strLen = strlen(strUuid);
+    if ('\n' == strUuid[strLen - 1])
+    {
+        strUuid[strLen - 1] = '\0';
+    }
+    else
+    {
+        for ( ; 0x20 <= getchar(); ); // for removing overflow garbages
+    }
+
+    if (0 == strncmp(strUuid, STR_UUID_ZERO, sizeof(STR_UUID_ZERO)))
+    {
+        memset(uuid->id, 0x00, sizeof(uuid->id));
+    }
+    else if (0 == strncmp(strUuid, (char *)WILDCARD_SUBJECT_ID.id, sizeof(WILDCARD_SUBJECT_ID.id)))
+    {
+        memset(uuid->id, 0x00, sizeof(uuid->id));
+        memcpy(uuid->id, WILDCARD_SUBJECT_ID.id, WILDCARD_SUBJECT_ID_LEN);
+    }
+    else
+    {
+        ocResult = ConvertStrToUuid(strUuid, uuid);
+        if (OC_STACK_OK != ocResult)
+        {
+            PRINT_ERR("Failed ConvertStrToUuid");
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
diff --git a/resource/csdk/security/tool/svrdbeditor_src/svrdbeditorcommon.h b/resource/csdk/security/tool/svrdbeditor_src/svrdbeditorcommon.h
new file mode 100644 (file)
index 0000000..7a5340a
--- /dev/null
@@ -0,0 +1,75 @@
+/* *****************************************************************
+ *
+ * Copyright 2017 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 SVRDBEDITOR_COMMON_H_
+#define SVRDBEDITOR_COMMON_H_
+
+#include "iotivity_config.h"
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <stdio.h>
+
+#include "securevirtualresourcetypes.h"
+
+#define TAG  "OIC_SVR_DB_EDITOR"
+
+#define BOLD_BEGIN    "\033[1m"
+#define RED_BEGIN      "\033[1;31m"
+#define YELLOW_BEGIN  "\033[1;33m"
+#define CYAN_BEGIN  "\033[1;36m"
+#define GREEN_BEGIN  "\033[1;92m"
+#define COLOR_END      "\033[0m"
+#define COLOR_END_NL      "\033[0m\n"
+
+#define SVR_MAX_ENTITY (16)
+
+#define SVR_DB_PATH_LENGTH (1024)
+#define PRINT_ERR(fmt,...) printf(RED_BEGIN "error: " fmt COLOR_END_NL, ##__VA_ARGS__)
+#define PRINT_WARN(fmt,...) printf(YELLOW_BEGIN "warning : " fmt COLOR_END_NL, ##__VA_ARGS__)
+#define PRINT_INFO(fmt,...) printf(YELLOW_BEGIN fmt COLOR_END_NL, ##__VA_ARGS__)
+#define PRINT_PROG(fmt,...) printf(BOLD_BEGIN fmt COLOR_END, ##__VA_ARGS__)
+#define PRINT_DATA(fmt,...) printf(CYAN_BEGIN fmt COLOR_END, ##__VA_ARGS__)
+#define PRINT_NORMAL(fmt,...) printf(fmt, ##__VA_ARGS__)
+#define PRINT_NL() printf("\n");
+
+typedef enum SubOperationType
+{
+    SVR_PRINT = 1,
+    SVR_ADD = 2,
+    SVR_REMOVE = 3,
+    SVR_MODIFY = 4,
+    SVR_EDIT_IDX_SIZE = 5,
+    BACK = 99
+} SubOperationType_t;
+
+void PrintUuid(const OicUuid_t *uuid);
+void PrintIntArray(const int *array, size_t length);
+void PrintStringArray(const char **array, size_t length);
+void PrintInt(int value);
+void PrintString(const char *text);
+void PrintBuffer(const uint8_t *buf, size_t bufLen);
+
+int InputNumber(const char *infoText);
+char *InputString(const char *infoText);
+int InputUuid(OicUuid_t *uuid);
+
+#endif /* SVRDBEDITOR_COMMON_H_ */
diff --git a/resource/csdk/security/tool/svrdbeditor_src/svrdbeditorcred.c b/resource/csdk/security/tool/svrdbeditor_src/svrdbeditorcred.c
new file mode 100644 (file)
index 0000000..b10a86c
--- /dev/null
@@ -0,0 +1,1364 @@
+/* *****************************************************************
+ *
+ * Copyright 2017 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 _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <mbedtls/ssl.h>
+#include <mbedtls/ctr_drbg.h>
+#include <mbedtls/x509_crt.h>
+#include <mbedtls/pkcs12.h>
+#include <mbedtls/ssl_internal.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include "utlist.h"
+#include "base64.h"
+#include "octypes.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "logger.h"
+
+#include "srmresourcestrings.h"
+#include "pinoxmcommon.h"
+#include "credresource.h"
+
+#include "security_internals.h"
+#include "psinterface.h"
+
+#include "svrdbeditordoxm.h"
+#include "svrdbeditorcred.h"
+
+typedef enum CredModifyType
+{
+    CRED_EDIT_SUBJECTUUID = 1,
+    CRED_EDIT_PSK,
+    CRED_EDIT_ROWNERUUID = 3,
+} CredModifyType_t;
+
+void RefreshCred()
+{
+    OCStackResult ocResult = OC_STACK_ERROR;
+    uint8_t *secPayload = NULL;
+    size_t payloadSize = 0;
+
+    OicSecCred_t *credList = NULL;
+    OicSecCred_t *cred = NULL;
+    OicSecCred_t *tmpCred = NULL;
+    //Load security resouce data from SVR DB.
+    ocResult = GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &secPayload, &payloadSize);
+    if (OC_STACK_OK != ocResult)
+    {
+        PRINT_WARN("GetSecureVirtualDatabaseFromPS : %d", ocResult);
+        return;
+    }
+    if (secPayload && 0 != payloadSize)
+    {
+        ocResult = CBORPayloadToCred(secPayload, payloadSize, &credList);
+        if (OC_STACK_OK != ocResult)
+        {
+            PRINT_ERR("CBORPayloadToCred : %d", ocResult);
+            OICFree(secPayload);
+            return;
+        }
+    }
+    OICFree(secPayload);
+    DeInitCredResource();
+
+    //Add the loaded credentials into gCred of CredResource module in order to use the credential management mechanism.
+    LL_FOREACH_SAFE(credList, cred, tmpCred)
+    {
+        ocResult = AddCredential(cred);
+        if (OC_STACK_OK != ocResult)
+        {
+            PRINT_ERR("AddCredential : %d", ocResult);
+            OICFree(credList);
+            return;
+        }
+    }
+}
+
+static void UpdateCred(void)
+{
+    OCStackResult credResult = OC_STACK_ERROR;
+    uint8_t *credPayload = NULL;
+    size_t credPayloadSize = 0;
+    int secureFlag = 0;
+
+    credResult = CredToCBORPayload(GetCredList(), &credPayload, &credPayloadSize, secureFlag);
+    if (OC_STACK_OK != credResult)
+    {
+        PRINT_ERR("CredToCBORPayload error : %d", credResult);
+        return;
+    }
+    credResult = UpdateSecureResourceInPS(OIC_JSON_CRED_NAME, credPayload, credPayloadSize);
+    if (OC_STACK_OK != credResult)
+    {
+        PRINT_ERR("UpdateSecureResourceInPS error : %d", credResult);
+        OICFree(credPayload);
+        return;
+    }
+    OICFree(credPayload);
+}
+
+/**
+ * Parse chain of X.509 certificates.
+ *
+ * @param[out] crt     container for X.509 certificates
+ * @param[in]  buf     buffer with X.509 certificates. Certificates may be in either in PEM
+ or DER format in a jumble. Each PEM certificate must be NULL-terminated.
+ * @param[in]  bufLen  buffer length
+ *
+ * @return  0 on success, -1 on error
+ */
+// TODO: Update to use credresource.c
+static int ParseCertChain(mbedtls_x509_crt *crt, unsigned char *buf, size_t bufLen)
+{
+    if (NULL == crt || NULL == buf || 0 == bufLen)
+    {
+        PRINT_ERR("ParseCertChain : Invalid param");
+        return -1;
+    }
+
+    /* byte encoded ASCII string '-----BEGIN CERTIFICATE-----' */
+    char pemCertHeader[] =
+    {
+        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43, 0x45, 0x52,
+        0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d
+    };
+    // byte encoded ASCII string '-----END CERTIFICATE-----' */
+    char pemCertFooter[] =
+    {
+        0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43, 0x45, 0x52, 0x54, 0x49,
+        0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d
+    };
+    size_t pemCertHeaderLen = sizeof(pemCertHeader);
+    size_t pemCertFooterLen = sizeof(pemCertFooter);
+
+    size_t len = 0;
+    unsigned char *tmp = NULL;
+    int count = 0;
+    int ret = 0;
+    size_t pos = 0;
+
+    while (pos < bufLen)
+    {
+        if (0x30 == buf[pos] && 0x82 == buf[pos + 1])
+        {
+            tmp = (unsigned char *)buf + pos + 1;
+            ret = mbedtls_asn1_get_len(&tmp, buf + bufLen, &len);
+            if (0 != ret)
+            {
+                PRINT_ERR("mbedtls_asn1_get_len failed: 0x%04x", ret);
+                return -1;
+            }
+
+            if (pos + len < bufLen)
+            {
+                ret = mbedtls_x509_crt_parse_der(crt, buf + pos, len + 4);
+                if (0 == ret)
+                {
+                    count++;
+                }
+                else
+                {
+                    PRINT_ERR("mbedtls_x509_crt_parse_der failed: 0x%04x", ret);
+                }
+            }
+            pos += len + 4;
+        }
+        else if ((buf + pos + pemCertHeaderLen < buf + bufLen) &&
+                 0 == memcmp(buf + pos, pemCertHeader, pemCertHeaderLen))
+        {
+            void *endPos = NULL;
+            endPos = memmem(&(buf[pos]), bufLen - pos, pemCertFooter, pemCertFooterLen);
+            if (NULL == endPos)
+            {
+                PRINT_ERR("end of PEM certificate not found.");
+                return -1;
+            }
+
+            len = (char *)endPos - ((char *)buf + pos) + pemCertFooterLen;
+            if (pos + len + 1 <= bufLen)
+            {
+                char con = buf[pos + len];
+                buf[pos + len] = 0x00;
+                ret = mbedtls_x509_crt_parse(crt, buf + pos, len + 1);
+                if (0 == ret)
+                {
+                    count++;
+                }
+                else
+                {
+                    PRINT_ERR("mbedtls_x509_crt_parse failed: 0x%04x", ret);
+                }
+                buf[pos + len] = con;
+            }
+            else
+            {
+                unsigned char *lastCert = (unsigned char *)OICMalloc((len + 1) * sizeof(unsigned char));
+                if (NULL == lastCert)
+                {
+                    PRINT_ERR("Failed to allocate memory for certificate");
+                    return -1;
+                }
+                memcpy(lastCert, buf + pos, len);
+                lastCert[len] = 0x00;
+                ret = mbedtls_x509_crt_parse(crt, lastCert, len + 1);
+                if (0 == ret)
+                {
+                    count++;
+                }
+                else
+                {
+                    PRINT_ERR("mbedtls_x509_crt_parse failed: 0x%04x", ret);
+                }
+                OICFree(lastCert);
+            }
+            pos += len;
+        }
+        else
+        {
+            pos++;
+        }
+    }
+
+    return 0;
+}
+
+// TODO: Update to use credresource.c
+static void ParseDerCaCert(ByteArray_t *crt, const char *usage, uint16_t credId)
+{
+    if (NULL == crt || NULL == usage)
+    {
+        PRINT_ERR("ParseDerCaCert : Invalid param");
+        return;
+    }
+    crt->len = 0;
+    OicSecCred_t *temp = NULL;
+
+    LL_FOREACH(((OicSecCred_t *)GetCredList()), temp)
+    {
+        if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
+            0 == strcmp(temp->credUsage, usage) &&
+            temp->credId == credId)
+        {
+            if (OIC_ENCODING_BASE64 == temp->optionalData.encoding)
+            {
+                size_t bufSize = B64DECODE_OUT_SAFESIZE((temp->optionalData.len + 1));
+                uint8_t *buf = OICCalloc(1, bufSize);
+                if (NULL == buf)
+                {
+                    PRINT_ERR("ParseDerCaCert : Failed to allocate memory");
+                    return;
+                }
+                uint32_t outSize;
+                if (B64_OK != b64Decode((char *)(temp->optionalData.data), temp->optionalData.len, buf, bufSize,
+                                        &outSize))
+                {
+                    OICFree(buf);
+                    PRINT_ERR("ParseDerCaCert : Failed to decode base64 data");
+                    return;
+                }
+                crt->data = OICRealloc(crt->data, crt->len + outSize);
+                memcpy(crt->data + crt->len, buf, outSize);
+                crt->len += outSize;
+                OICFree(buf);
+            }
+            else
+            {
+                crt->data = OICRealloc(crt->data, crt->len + temp->optionalData.len);
+                memcpy(crt->data + crt->len, temp->optionalData.data, temp->optionalData.len);
+                crt->len += temp->optionalData.len;
+            }
+        }
+    }
+    if (0 == crt->len)
+    {
+        PRINT_INFO("ParseDerCaCert : %s not found", usage);
+    }
+    return;
+}
+
+// TODO: Update to use credresource.c
+static void ParseDerOwnCert(ByteArray_t *crt, const char *usage, uint16_t credId)
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+    if (NULL == crt || NULL == usage)
+    {
+        OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+        return;
+    }
+    crt->len = 0;
+    OicSecCred_t *temp = NULL;
+    LL_FOREACH(((OicSecCred_t *)GetCredList()), temp)
+    {
+        if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
+            0 == strcmp(temp->credUsage, usage) &&
+            temp->credId == credId)
+        {
+            crt->data = OICRealloc(crt->data, crt->len + temp->publicData.len);
+            memcpy(crt->data + crt->len, temp->publicData.data, temp->publicData.len);
+            crt->len += temp->publicData.len;
+            OIC_LOG_V(DEBUG, TAG, "%s found", usage);
+        }
+    }
+    if (0 == crt->len)
+    {
+        OIC_LOG_V(WARNING, TAG, "%s not found", usage);
+    }
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+    return;
+}
+
+inline void ParseDerKey(ByteArray_t *key, const char *usage, uint16_t credId)
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+    if (NULL == key || NULL == usage)
+    {
+        OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+        return;
+    }
+
+    OicSecCred_t *temp = NULL;
+    key->len = 0;
+    LL_FOREACH(((OicSecCred_t *)GetCredList()), temp)
+    {
+        if (SIGNED_ASYMMETRIC_KEY == temp->credType &&
+            0 == strcmp(temp->credUsage, usage) &&
+            temp->credId == credId)
+        {
+            key->data = OICRealloc(key->data, key->len + temp->privateData.len);
+            memcpy(key->data + key->len, temp->privateData.data, temp->privateData.len);
+            key->len += temp->privateData.len;
+            OIC_LOG_V(DEBUG, TAG, "Key for %s found", usage);
+        }
+    }
+    if (0 == key->len)
+    {
+        OIC_LOG_V(WARNING, TAG, "Key for %s not found", usage);
+    }
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+}
+
+static void PrintCredType(OicSecCredType_t credType)
+{
+    PRINT_DATA("%d", credType);
+    switch (credType)
+    {
+        case NO_SECURITY_MODE:
+            PRINT_DATA(" (NO_SECURITY_MODE)\n");
+            break;
+        case SYMMETRIC_PAIR_WISE_KEY:
+            PRINT_DATA(" (SYMMETRIC_PAIR_WISE_KEY)\n");
+            break;
+        case SYMMETRIC_GROUP_KEY:
+            PRINT_DATA(" (SYMMETRIC_GROUP_KEY)\n");
+            break;
+        case ASYMMETRIC_KEY:
+            PRINT_DATA(" (ASYMMETRIC_KEY)\n");
+            break;
+        case SIGNED_ASYMMETRIC_KEY:
+            PRINT_DATA(" (SIGNED_ASYMMETRIC_KEY)\n");
+            break;
+        case PIN_PASSWORD:
+            PRINT_DATA(" (PIN_PASSWORD)\n");
+            break;
+        case ASYMMETRIC_ENCRYPTION_KEY:
+            PRINT_DATA(" (ASYMMETRIC_ENCRYPTION_KEY)\n");
+            break;
+        default:
+            PRINT_ERR(" (Unknown Cred type)");
+            break;
+    }
+}
+
+static void PrintCredEncodingType(OicEncodingType_t encoding)
+{
+    PRINT_DATA("%d", encoding);
+    switch (encoding)
+    {
+        case OIC_ENCODING_RAW:
+            PRINT_DATA(" (OIC_ENCODING_RAW)\n");
+            break;
+        case OIC_ENCODING_BASE64:
+            PRINT_DATA(" (OIC_ENCODING_BASE64)\n");
+            break;
+        case OIC_ENCODING_PEM:
+            PRINT_DATA(" (OIC_ENCODING_PEM)\n");
+            break;
+        case OIC_ENCODING_DER:
+            PRINT_DATA(" (OIC_ENCODING_DER)\n");
+            break;
+        default:
+            PRINT_ERR(" (Unknown Encoding type)");
+            break;
+    }
+
+}
+
+/**
+ * This API to print credential list.
+ * Also return the number of credential in credential list.
+ */
+void PrintCredList(const OicSecCred_t *creds)
+{
+    const OicSecCred_t *cred = NULL;
+    const OicSecCred_t *tempCred = NULL;
+    bool isEmptyList = true;
+    PRINT_INFO("\n\n********************* [%-20s] *********************",
+               "Credential Resource");
+    LL_FOREACH_SAFE(creds, cred, tempCred)
+    {
+        PRINT_PROG("%15s : ", OIC_JSON_CREDID_NAME);
+        PrintInt(cred->credId);
+
+        PRINT_PROG("%15s : ", OIC_JSON_SUBJECTID_NAME);
+        if (0 == memcmp(&(cred->subject), &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t)))
+        {
+            PrintString((char *)WILDCARD_SUBJECT_ID.id);
+        }
+        else
+        {
+            PrintUuid(&(cred->subject));
+        }
+
+#ifdef MULTIPLE_OWNER
+        if (creds->eownerID)
+        {
+            PRINT_PROG("%15s : ", OIC_JSON_EOWNERID_NAME);
+            PrintUuid(cred->eownerID);
+        }
+#endif
+
+        PRINT_PROG("%15s : ", OIC_JSON_CREDTYPE_NAME);
+        PrintCredType(cred->credType);
+
+        switch (cred->credType)
+        {
+            case SYMMETRIC_PAIR_WISE_KEY:
+            case SYMMETRIC_GROUP_KEY:
+                PRINT_PROG("%15s : \n", OIC_JSON_PRIVATEDATA_NAME);
+                if (cred->privateData.data)
+                {
+                    PRINT_DATA("%s : ", OIC_JSON_ENCODING_NAME);
+                    PrintCredEncodingType(cred->privateData.encoding);
+
+                    PRINT_DATA("%s : ", OIC_JSON_DATA_NAME);
+                    if (OIC_ENCODING_BASE64 == cred->privateData.encoding)
+                    {
+                        PrintString((char *)cred->privateData.data);
+                    }
+                    else
+                    {
+                        PrintBuffer(cred->privateData.data, cred->privateData.len);
+                    }
+                }
+                else
+                {
+                    PRINT_ERR("Private data is null");
+                }
+                break;
+            case ASYMMETRIC_KEY:
+            case SIGNED_ASYMMETRIC_KEY:
+                // TODO: Print certificate and asymmetric key in readable formats
+
+                //cred usage
+                if (cred->credUsage)
+                {
+                    PRINT_PROG("%15s : ", OIC_JSON_CREDUSAGE_NAME);
+                    PRINT_DATA("%s\n", cred->credUsage);
+                }
+
+                //private data
+                if (cred->privateData.data)
+                {
+                    PRINT_PROG("%15s : \n", OIC_JSON_PRIVATEDATA_NAME);
+                    PrintBuffer(cred->privateData.data, cred->privateData.len);
+
+                    if (cred->credUsage &&
+                        (0 == strcmp(cred->credUsage, PRIMARY_CERT) ||
+                         0 == strcmp(cred->credUsage, MF_PRIMARY_CERT)))
+                    {
+                        // TODO: T.B.D
+                    }
+                    else
+                    {
+                        // TODO: T.B.D
+                    }
+                }
+
+                //public data
+                if (cred->publicData.data)
+                {
+                    PRINT_PROG("%15s : ", OIC_JSON_PUBLICDATA_NAME);
+                    PRINT_DATA("%-17s : ", OIC_JSON_ENCODING_NAME);
+                    PrintCredEncodingType(cred->publicData.encoding);
+
+                    if (cred->credUsage &&
+                        (0 == strcmp(cred->credUsage, PRIMARY_CERT) ||
+                         0 == strcmp(cred->credUsage, MF_PRIMARY_CERT)))
+                    {
+                        char buf[2048];
+                        mbedtls_x509_crt crt;
+                        mbedtls_x509_crt *tmpCrt = NULL;
+                        PkiInfo_t inf;
+                        int i = 0;
+
+                        memset(&inf, 0x00, sizeof(PkiInfo_t));
+                        mbedtls_x509_crt_init(&crt);
+
+                        ParseDerOwnCert(&inf.crt, cred->credUsage, cred->credId);
+                        ParseCertChain(&crt, inf.crt.data, inf.crt.len);
+
+                        for (i = 0, tmpCrt = &crt; NULL != tmpCrt; i++, tmpCrt = tmpCrt->next)
+                        {
+                            PRINT_INFO("[Cert #%d]", (i + 1));
+                            mbedtls_x509_crt_info( buf, sizeof(buf) - 1, "", tmpCrt );
+                            PRINT_DATA("%s", buf);
+                        }
+                        mbedtls_x509_crt_free(&crt);
+                    }
+                    else
+                    {
+                        PRINT_INFO("will be updated to print public data");
+                    }
+                }
+
+                //optional data
+                if (cred->optionalData.data)
+                {
+                    PRINT_PROG("%15s : \n", OIC_JSON_OPTDATA_NAME);
+
+                    //revocation status
+                    PRINT_DATA("%-17s : %s\n", OIC_JSON_REVOCATION_STATUS_NAME,
+                               (cred->optionalData.revstat ? "True" : "False"));
+
+                    PRINT_DATA("%-17s : ", OIC_JSON_ENCODING_NAME);
+                    PrintCredEncodingType(cred->optionalData.encoding);
+
+                    //CA chain
+                    if (cred->credUsage &&
+                        (0 == strcmp(cred->credUsage, TRUST_CA) ||
+                         0 == strcmp(cred->credUsage, MF_TRUST_CA)))
+                    {
+                        char buf[2048];
+                        mbedtls_x509_crt ca;
+                        mbedtls_x509_crt *tmpCa = NULL;
+                        PkiInfo_t inf;
+                        int i = 0;
+
+                        memset(&inf, 0x00, sizeof(PkiInfo_t));
+                        mbedtls_x509_crt_init(&ca);
+
+                        ParseDerCaCert(&inf.ca, cred->credUsage, cred->credId);
+                        ParseCertChain(&ca, inf.ca.data, inf.ca.len);
+
+                        for (i = 0, tmpCa = &ca; NULL != tmpCa; i++, tmpCa = tmpCa->next)
+                        {
+                            PRINT_INFO("[Cert #%d]", (i + 1));
+                            mbedtls_x509_crt_info( buf, sizeof(buf) - 1, "", tmpCa );
+                            PRINT_DATA("%s", buf);
+                        }
+                        mbedtls_x509_crt_free(&ca);
+                    }
+                    else
+                    {
+                        // TODO: T.B.D
+                        PRINT_INFO("will be updated to print optional data");
+                    }
+                }
+                break;
+            case PIN_PASSWORD:
+                PRINT_PROG("%15s : ", OIC_JSON_PRIVATEDATA_NAME);
+                if (cred->privateData.data)
+                {
+                    PRINT_DATA("%s : ", OIC_JSON_ENCODING_NAME);
+                    PrintCredEncodingType(cred->privateData.encoding);
+
+                    PRINT_DATA("%s : ", OIC_JSON_DATA_NAME);
+                    PRINT_DATA("%s\n", cred->privateData.data);
+                }
+                else
+                {
+                    PRINT_ERR("Private data is null");
+                }
+                break;
+            case ASYMMETRIC_ENCRYPTION_KEY:
+                break;
+            default:
+                PRINT_ERR(" (Unknown Cred type)");
+                break;
+        }
+        PRINT_PROG("------------------------------------------------------------------\n");
+        isEmptyList = false;
+    }
+
+    if (!isEmptyList)
+    {
+        OicUuid_t uuid = {.id = {0}};
+        if (OC_STACK_OK != GetCredRownerId(&uuid))
+        {
+            PRINT_WARN("GetCredRownerId failed");
+        }
+        else
+        {
+            PRINT_PROG("%15s : ", OIC_JSON_ROWNERID_NAME);
+            PrintUuid(&uuid);
+        }
+    }
+    else
+    {
+        PRINT_PROG("Cred List is empty.\n");
+    }
+
+    PRINT_INFO("********************* [%-20s] *********************",
+               "Credential Resource");
+
+    return;
+}
+
+static int ReadDataFromFile(const char *infoTxt, uint8_t **buffer, size_t *bufferSize)
+{
+    char filePath[512] = {0};
+    char tmpBuffer[SVR_DB_PATH_LENGTH] = {0};
+    FILE *fp = NULL;
+    size_t filePathLen = 0 ;
+    size_t fileSize = 0;
+
+    if (NULL == buffer || NULL != *buffer || NULL == bufferSize)
+    {
+        PRINT_ERR("ReadDataFromFile : Invaild param");
+        return -1;
+    }
+
+    PRINT_NORMAL("%s", infoTxt);
+    if (NULL == fgets(filePath, sizeof(filePath), stdin))
+    {
+        PRINT_ERR("Failed fgets");
+        return -1;
+    }
+    filePathLen = strlen(filePath);
+    if ('\n' == filePath[filePathLen - 1])
+    {
+        filePath[filePathLen - 1] = '\0';
+    }
+
+    //Get a file size
+    fp = fopen(filePath, "rb");
+    if (fp)
+    {
+        size_t bytesRead = 0;
+        do
+        {
+            bytesRead = fread(tmpBuffer, 1, 1023, fp);
+            fileSize += bytesRead;
+            if (ferror (fp))
+            {
+                PRINT_ERR("Error fread\n");
+                fclose (fp);
+                return -1;
+            }
+        }
+        while (bytesRead);
+        fclose(fp);
+        fp = NULL;
+    }
+    else
+    {
+        PRINT_ERR("Failed to open %s" , filePath);
+        PRINT_ERR("Please make sure the file path and access permission.");
+        goto error;
+    }
+
+    if (0 == fileSize)
+    {
+        PRINT_ERR("%s is empty." , filePath);
+        goto error;
+    }
+
+    fp = fopen(filePath, "rb");
+    if (fp)
+    {
+        *buffer = (uint8_t *) OICCalloc(1, fileSize);
+        if ( NULL == *buffer)
+        {
+            PRINT_ERR("Failed to allocate memory.");
+            goto error;
+        }
+
+        if ( fread(*buffer, 1, fileSize, fp) == fileSize)
+        {
+            *bufferSize = fileSize;
+        }
+        fclose(fp);
+    }
+    else
+    {
+        PRINT_ERR("Failed to open %s" , filePath);
+        PRINT_ERR("Please make sure the file path and access permission.");
+        goto error;
+    }
+
+    return 0;
+
+error:
+    if (fp)
+    {
+        fclose(fp);
+    }
+    if (*buffer)
+    {
+        OICFree(*buffer);
+    }
+    return -1;
+}
+
+static int InputCredUsage(char **credUsage)
+{
+    char inputUsage[128] = {0};
+    int credUsageNum = 0;
+
+    if (NULL == credUsage || NULL != *credUsage)
+    {
+        PRINT_ERR("InputCredUsage error : invaild param");
+        return -1;
+    }
+
+    do
+    {
+        PRINT_NORMAL("\n\n");
+        PRINT_NORMAL("\t1. %s\n", TRUST_CA);
+        PRINT_NORMAL("\t2. %s\n", PRIMARY_CERT);
+        PRINT_NORMAL("\t3. %s\n", MF_TRUST_CA);
+        PRINT_NORMAL("\t4. %s\n", MF_PRIMARY_CERT);
+        PRINT_NORMAL("\t5. Input manually\n");
+        credUsageNum = InputNumber("\tSelect the credential usage : ");
+        switch (credUsageNum)
+        {
+            case 1:
+                *credUsage = OICStrdup(TRUST_CA);
+                break;
+            case 2:
+                *credUsage = OICStrdup(PRIMARY_CERT);
+                break;
+            case 3:
+                *credUsage = OICStrdup(MF_TRUST_CA);
+                break;
+            case 4:
+                *credUsage = OICStrdup(MF_PRIMARY_CERT);
+                break;
+            case 5:
+                PRINT_NORMAL("\tInput the credential usage : ");
+                for (int ret = 0; 1 != ret; )
+                {
+                    ret = scanf("%128s", inputUsage);
+                    for ( ; 0x20 <= getchar(); ); // for removing overflow garbages
+                    // '0x20<=code' is character region
+                }
+                *credUsage = OICStrdup(inputUsage);
+                break;
+            default:
+                PRINT_ERR("Invaild credential usage");
+                credUsageNum = 0;
+                break;
+        }
+    }
+    while (0 == credUsageNum);
+
+    if (NULL == *credUsage)
+    {
+        PRINT_ERR("Failed OICStrdup");
+        return -1;
+    }
+
+    return 0;
+}
+
+static int InputCredEncodingType(const char *dataType, OicEncodingType_t *encoding)
+{
+    int credEncType = 0;
+    char infoText[512] = {0};
+
+    if (NULL == dataType || NULL == encoding)
+    {
+        PRINT_ERR("InputCredEncodingType : Invaild param");
+        return -1;
+    }
+
+    snprintf(infoText, sizeof(infoText), "\tSelect the encoding type of %s : ", dataType);
+
+    do
+    {
+        PRINT_NORMAL("\n\n");
+        PRINT_NORMAL("\t%d. %s\n", OIC_ENCODING_RAW, "OIC_ENCODING_RAW");
+        PRINT_NORMAL("\t%d. %s\n", OIC_ENCODING_BASE64, "OIC_ENCODING_BASE64");
+        PRINT_NORMAL("\t%d. %s\n", OIC_ENCODING_PEM, "OIC_ENCODING_PEM");
+        PRINT_NORMAL("\t%d. %s\n", OIC_ENCODING_DER, "OIC_ENCODING_DER");
+        credEncType = InputNumber(infoText);
+        switch ( (OicEncodingType_t)credEncType )
+        {
+            case OIC_ENCODING_RAW:
+                break;
+            case OIC_ENCODING_BASE64:
+                break;
+            case OIC_ENCODING_PEM:
+                break;
+            case OIC_ENCODING_DER:
+                break;
+            default:
+                PRINT_ERR("Invaild encoding type");
+                credEncType = 0;
+                break;
+        }
+    }
+    while (0 == credEncType);
+
+    *encoding = (OicEncodingType_t)credEncType;
+
+    return 0;
+}
+
+static int InputCredSubject(OicUuid_t *uuid)
+{
+    int ret = 0;
+    OicUuid_t emptyUuid = {.id = {0}};
+    PRINT_PROG(
+        "\tInput the Subject UUID for this access (e.g. 61646D69-6E44-6576-6963-655575696430) : ");
+    ret = InputUuid(uuid);
+    if (0 != ret)
+    {
+        PRINT_ERR("InputUuid failed");
+        return ret;
+    }
+
+    if (0 == memcmp(emptyUuid.id, (*uuid).id, sizeof((*uuid).id) ) )
+    {
+        PRINT_ERR("Cred Subject UUID can't be empty uuid");
+        return -1;
+    }
+    return ret;
+}
+
+static int InputPSK(OicSecKey_t *secKey)
+{
+    char *data = NULL;
+    size_t psklen = 0;
+    size_t bufSize = 0;
+    uint8_t *buf = NULL;
+    uint32_t outSize = 0;
+
+    data = InputString("\tInput encoded base64 psk (decoded psk 128 or 256 bits,\n"
+                       "\te.g. BxjJidB+u21QlEwMCYBoKA== ) : ");
+    if (NULL == data)
+    {
+        PRINT_ERR("Failed InputString");
+        return -1;
+    }
+
+    psklen = strlen(data);
+    bufSize = B64DECODE_OUT_SAFESIZE(psklen + 1);
+    buf = OICCalloc(1, bufSize);
+    if (NULL == buf)
+    {
+        PRINT_ERR("Failed to allocate memory");
+        OICFree(data);
+        return -1;
+    }
+    //validate base64 psk
+    if (B64_OK != b64Decode(data, psklen, buf, bufSize, &outSize))
+    {
+        PRINT_ERR("Failed to decode base64 data. Invalid base64 input");
+        OICFree(data);
+        OICFree(buf);
+        return -1;
+    }
+    if (!(OWNER_PSK_LENGTH_128 == outSize || OWNER_PSK_LENGTH_256 == outSize))
+    {
+        PRINT_ERR("Invalid key size");
+        OICFree(data);
+        OICFree(buf);
+        return -1;
+    }
+    secKey->data = (uint8_t *)data;
+    secKey->encoding = OIC_ENCODING_BASE64;
+    secKey->len = psklen;
+    OICFree(buf);
+    return 0;
+}
+
+static int InputCredentialData(OicSecCred_t *cred)
+{
+    uint8_t *certChain = NULL;
+    uint8_t *privateKey = NULL;
+    uint8_t *publicKey = NULL;
+    size_t certChainSize = 0;
+    size_t privateKeySize = 0;
+    size_t publicKeySize = 0;
+
+    PRINT_PROG("\n\nPlease input the each entity of new credential.\n");
+
+    PRINT_NORMAL("\t%3d. Symmetric pair wise key\n", SYMMETRIC_PAIR_WISE_KEY);
+    PRINT_NORMAL("\t%3d. Symmetric group key\n", SYMMETRIC_GROUP_KEY);
+    PRINT_NORMAL("\t%3d. Asymmetric key\n", ASYMMETRIC_KEY);
+    PRINT_NORMAL("\t%3d. Signed asymmetric key\n", SIGNED_ASYMMETRIC_KEY);
+    PRINT_NORMAL("\t%3d. PIN/Password\n", PIN_PASSWORD);
+    PRINT_NORMAL("\t%3d. Asymmetric encryption key\n", ASYMMETRIC_ENCRYPTION_KEY);
+    cred->credType = (OicSecCredType_t)InputNumber("\tSelect the credential type : ");
+    if (SYMMETRIC_PAIR_WISE_KEY != cred->credType &&
+        SYMMETRIC_GROUP_KEY != cred->credType &&
+        SIGNED_ASYMMETRIC_KEY != cred->credType &&
+        PIN_PASSWORD != cred->credType &&
+        ASYMMETRIC_ENCRYPTION_KEY != cred->credType)
+    {
+        PRINT_ERR("Invaild credential type");
+        goto error;
+    }
+
+    //Input the key data according to credential type
+    switch (cred->credType)
+    {
+        case SYMMETRIC_PAIR_WISE_KEY:
+            {
+                PRINT_PROG("\tSubject UUID (e.g. 61646D69-6E44-6576-6963-655575696430) : ");
+                if (0 != InputCredSubject(&cred->subject))
+                {
+                    PRINT_ERR("InputCredSubject failed");
+                    return -1;
+                }
+                if (0 != InputPSK(&cred->privateData))
+                {
+                    PRINT_ERR("Failed InputPSK");
+                    return -1;
+                }
+                break;
+            }
+        case SYMMETRIC_GROUP_KEY:
+            // TODO: T.B.D
+            PRINT_INFO("Not supported yet.");
+            goto error;
+            break;
+        case ASYMMETRIC_KEY:
+            // TODO: T.B.D
+            PRINT_INFO("Not supported yet.");
+            goto error;
+            break;
+        case SIGNED_ASYMMETRIC_KEY:
+            //Credential usage
+            if ( 0 != InputCredUsage(&cred->credUsage))
+            {
+                PRINT_ERR("Failed InputCredUsage");
+                goto error;
+            }
+
+            //Input the other data according to credential usage.
+            if (0 == strcmp(cred->credUsage, TRUST_CA) ||
+                0 == strcmp(cred->credUsage, MF_TRUST_CA))
+            {
+                OicUuid_t doxmUuid;
+                if (0 != GetDoxmDevID(&doxmUuid))
+                {
+                    PRINT_ERR("Failed get doxm device id");
+                }
+                else
+                {
+                    memcpy(cred->subject.id, doxmUuid.id, sizeof(doxmUuid.id));
+                }
+
+                //encoding type
+                if ( 0 != InputCredEncodingType("certificate chain", &cred->optionalData.encoding))
+                {
+                    PRINT_ERR("Failed InputCredEncodingType");
+                    goto error;
+                }
+
+                //Read chain data from file (readed data will be saved to optional data)
+                if (0 != ReadDataFromFile("\tInput the certificate chain path : ", &certChain, &certChainSize))
+                {
+                    PRINT_ERR("Failed ReadDataFromFile");
+                    goto error;
+                }
+
+                //optional data
+                if (OIC_ENCODING_PEM == cred->optionalData.encoding)
+                {
+                    cred->optionalData.data = (uint8_t *)OICCalloc(1, certChainSize + 1);
+                    if (NULL == cred->optionalData.data)
+                    {
+                        PRINT_ERR("InputCredentialData : Failed to allocate memory.");
+                        goto error;
+                    }
+                    cred->optionalData.len = certChainSize + 1;
+                }
+                else
+                {
+                    cred->optionalData.data = (uint8_t *)OICCalloc(1, certChainSize);
+                    if (NULL == cred->optionalData.data)
+                    {
+                        PRINT_ERR("InputCredentialData : Failed to allocate memory.");
+                        goto error;
+                    }
+                    cred->optionalData.len = certChainSize;
+                }
+                memcpy(cred->optionalData.data, certChain, certChainSize);
+                cred->optionalData.revstat = false;
+            }
+            else if (0 == strcmp(cred->credUsage, PRIMARY_CERT) ||
+                     0 == strcmp(cred->credUsage, MF_PRIMARY_CERT))
+            {
+                OicUuid_t doxmUuid;
+                if (0 != GetDoxmDevID(&doxmUuid))
+                {
+                    PRINT_ERR("Failed get doxm device id");
+                }
+                else
+                {
+                    memcpy(cred->subject.id, doxmUuid.id, sizeof(doxmUuid.id));
+                }
+
+                //private key
+                //encoding type
+                if ( 0 != InputCredEncodingType(YELLOW_BEGIN"Private key"COLOR_END, &cred->privateData.encoding))
+                {
+                    PRINT_ERR("Failed InputCredEncodingType");
+                    goto error;
+                }
+
+                if (OIC_ENCODING_RAW != cred->privateData.encoding)
+                {
+                    PRINT_ERR("Not supported encoding type for private key");
+                    goto error;
+                }
+
+                //Read private key data from file
+                if (0 != ReadDataFromFile("\tInput the private key's path : ", &privateKey, &privateKeySize))
+                {
+                    PRINT_ERR("Failed ReadDataFromFile");
+                    goto error;
+                }
+
+                cred->privateData.data = OICCalloc(1, privateKeySize);
+                if (NULL == cred->privateData.data)
+                {
+                    PRINT_ERR("InputCredentialData : Failed to allocate memory.");
+                    goto error;
+                }
+                memcpy(cred->privateData.data, privateKey, privateKeySize);
+                cred->privateData.len = privateKeySize;
+
+                //public key
+                //encoding type
+                if ( 0 != InputCredEncodingType(YELLOW_BEGIN"Certificate"COLOR_END, &cred->publicData.encoding))
+                {
+                    PRINT_ERR("Failed InputCredEncodingType");
+                    goto error;
+                }
+
+                if (OIC_ENCODING_DER != cred->publicData.encoding &&
+                    OIC_ENCODING_PEM != cred->publicData.encoding)
+                {
+                    PRINT_ERR("Not supported encoding type for private key");
+                    goto error;
+                }
+
+                //Read certificate data from file
+                if (0 != ReadDataFromFile("\tInput the certificate's path : ", &publicKey, &publicKeySize))
+                {
+                    PRINT_ERR("Failed ReadDataFromFile");
+                    goto error;
+                }
+
+                if (OIC_ENCODING_PEM == cred->publicData.encoding)
+                {
+                    cred->publicData.data = OICCalloc(1, publicKeySize + 1);
+                    if (NULL == cred->publicData.data)
+                    {
+                        PRINT_ERR("InputCredentialData : Failed to allocate memory.");
+                        goto error;
+                    }
+                    cred->publicData.len = publicKeySize + 1;
+                }
+                else
+                {
+                    cred->publicData.data = OICCalloc(1, publicKeySize);
+                    if (NULL == cred->publicData.data)
+                    {
+                        PRINT_ERR("InputCredentialData : Failed to allocate memory.");
+                        goto error;
+                    }
+                    cred->publicData.len = publicKeySize;
+                }
+                memcpy(cred->publicData.data, publicKey, publicKeySize);
+            }
+            else
+            {
+                // TODO: T.B.D : Data type should be selected by user.
+                PRINT_ERR("Not supported yet.");
+                goto error;
+            }
+            break;
+        case PIN_PASSWORD:
+            {
+                char pinPass[OXM_RANDOM_PIN_MAX_SIZE + 1] = {0};
+
+                PRINT_NORMAL("\tSubject UUID (e.g. 61646D69-6E44-6576-6963-655575696430) : ");
+                if (0 != InputCredSubject(&cred->subject))
+                {
+                    PRINT_ERR("InputCredSubject failed");
+                    goto error;
+                }
+
+                PRINT_NORMAL("\tInput the PIN or Password : ");
+                for (int ret = 0; 1 != ret; )
+                {
+                    ret = scanf("%32s", pinPass);
+                    for ( ; 0x20 <= getchar(); ); // for removing overflow garbages
+                    // '0x20<=code' is character region
+                }
+                cred->privateData.data = (uint8_t *)OICStrdup(pinPass);
+                if (NULL == cred->privateData.data)
+                {
+                    PRINT_ERR("Failed OICStrdup");
+                    goto error;
+                }
+                cred->privateData.len = strlen((char *)cred->privateData.data);
+                cred->privateData.encoding = OIC_ENCODING_RAW;
+                break;
+            }
+        case ASYMMETRIC_ENCRYPTION_KEY:
+            // TODO: T.B.D
+            PRINT_INFO("Not supported yet.");
+            goto error;
+            break;
+        default:
+            PRINT_ERR("Invalid credential type");
+            goto error;
+    }
+
+    OICFree(certChain);
+    OICFree(privateKey);
+    OICFree(publicKey);
+    return 0;
+
+error:
+    OICFree(certChain);
+    OICFree(privateKey);
+    OICFree(publicKey);
+    memset(cred, 0x00, sizeof(OicSecCred_t));
+    return -1;
+}
+
+static int ModifyCred(void)
+{
+    OCStackResult credResult = OC_STACK_ERROR;
+    int ret = 0;
+    int modifyMenu = 0;
+    OicSecCred_t *cred = NULL;
+    uint16_t credId = 0;
+    OicUuid_t uuid = {.id = {0}};
+    OicSecKey_t key = {0};
+
+    PRINT_PROG("\n\nPlease select the menu you want to modify\n");
+    PRINT_DATA("\t%2d. Edit subjectuuid\n", CRED_EDIT_SUBJECTUUID);
+    PRINT_DATA("\t%2d. Edit psk of symmetric cred\n", CRED_EDIT_PSK);
+    PRINT_DATA("\t%2d. Edit rowner uuid\n", CRED_EDIT_ROWNERUUID);
+    PRINT_DATA("\t%2d. Back to the previous\n", BACK);
+    modifyMenu = InputNumber("Select the menu : ");
+    switch (modifyMenu)
+    {
+        case CRED_EDIT_SUBJECTUUID:
+            PrintCredList(GetCredList());
+            credId = (uint16_t)InputNumber("\tPlease input the credential ID : ");
+            cred = GetCredEntryByCredId(credId);
+            if (NULL == cred)
+            {
+                PRINT_ERR("Invalid credId");
+                return -1;
+            }
+
+            if (0 != InputCredSubject(&uuid))
+            {
+                PRINT_ERR("InputCredSubject failed");
+                DeleteCredList(cred);
+                return ret;
+            }
+
+            if (0 == memcmp(cred->subject.id, uuid.id, sizeof(cred->subject.id)))
+            {
+                PRINT_ERR("Please input different uuid from the selected cred's uuid");
+                DeleteCredList(cred);
+                return -1;
+            }
+            memcpy(cred->subject.id, uuid.id , sizeof(cred->subject.id));
+
+            credResult = AddCredential(cred);
+            if (OC_STACK_OK != credResult)
+            {
+                PRINT_ERR("AddCredential : %d", credResult);
+                DeleteCredList(cred);
+                return -1;
+            }
+            credResult = RemoveCredentialByCredId(credId);
+            if ( OC_STACK_RESOURCE_DELETED != credResult)
+            {
+                PRINT_ERR("RemoveCredentialByCredId error : %d" , credResult);
+                return -1;
+            }
+
+            break;
+        case CRED_EDIT_PSK:
+            PrintCredList(GetCredList());
+            credId = (uint16_t)InputNumber("\tPlease input the credential ID : ");
+            cred = GetCredEntryByCredId(credId);
+            if (NULL == cred)
+            {
+                PRINT_ERR("Invalid credId");
+                return -1;
+            }
+            if (SYMMETRIC_PAIR_WISE_KEY != cred->credType)
+            {
+                PRINT_ERR("Selected cred is not SYMMETRIC_PAIR_WISE_KEY type\n");
+                DeleteCredList(cred);
+                return -1;
+            }
+            if (0 != InputPSK(&key))
+            {
+                PRINT_ERR("Failed InputPSK");
+                DeleteCredList(cred);
+                return -1;
+            }
+            if (key.len == cred->privateData.len &&
+                key.encoding == cred->privateData.encoding &&
+                0 == memcmp(key.data, cred->privateData.data, key.len))
+            {
+                PRINT_ERR("Please input different psk from the selected cred's psk");
+                OICFree(key.data);
+                DeleteCredList(cred);
+                return -1;
+            }
+            cred->privateData = key;
+
+            credResult = AddCredential(cred);
+            if (OC_STACK_OK != credResult)
+            {
+                PRINT_ERR("AddCredential : %d", credResult);
+                DeleteCredList(cred);
+                return -1;
+            }
+            credResult = RemoveCredentialByCredId(credId);
+            if ( OC_STACK_RESOURCE_DELETED != credResult)
+            {
+                PRINT_ERR("RemoveCredentialByCredId error : %d" , credResult);
+                return -1;
+            }
+
+            break;
+        case CRED_EDIT_ROWNERUUID:
+            PRINT_PROG(
+                "\tInput the ROWNER UUID (e.g. 61646D69-6E44-6576-6963-655575696430) : ");
+            ret = InputUuid(&uuid);
+            if (0 != ret)
+            {
+                PRINT_ERR("InputUuid failed");
+                return -1;
+            }
+            credResult = SetCredRownerId(&uuid);
+            if (OC_STACK_OK != credResult)
+            {
+                PRINT_ERR("SetCredRownerId failed");
+                return -1;
+            }
+            break;
+        case BACK:
+            PRINT_INFO("Back to the previous menu.");
+            break;
+        default:
+            PRINT_ERR("Wrong type Number");
+            ret = -1;
+            break;
+    }
+    return ret;
+}
+
+void HandleCredOperation(SubOperationType_t cmd)
+{
+    uint16_t credId = 0;
+    OCStackResult credResult = OC_STACK_ERROR;
+
+    if (SVR_EDIT_IDX_SIZE <= cmd)
+    {
+        PRINT_ERR("Invalid menu for credential");
+        return;
+    }
+    switch (cmd)
+    {
+        case SVR_PRINT:
+            PrintCredList(GetCredList());
+            break;
+        case SVR_ADD:
+            {
+                OicSecCred_t *cred = (OicSecCred_t *)OICCalloc(1, sizeof(OicSecCred_t));
+                if (NULL == cred)
+                {
+                    PRINT_ERR("Failed to allocate memory");
+                    return;
+                }
+
+                if (0 != InputCredentialData(cred))
+                {
+                    PRINT_ERR("Failed to InputCredentialData");
+                    DeleteCredList(cred);
+                    return;
+                }
+
+                credResult = AddCredential(cred);
+                if ( OC_STACK_OK != credResult)
+                {
+                    PRINT_ERR("AddCredential error : %d" , credResult);
+                    DeleteCredList(cred);
+                    return;
+                }
+                break;
+            }
+        case SVR_REMOVE:
+            PrintCredList(GetCredList());
+            credId = (uint16_t)InputNumber("\tPlease input the credential ID : ");
+
+            credResult = RemoveCredentialByCredId(credId);
+            if ( OC_STACK_RESOURCE_DELETED != credResult)
+            {
+                PRINT_ERR("RemoveCredentialByCredId error : %d" , credResult);
+                return;
+            }
+            break;
+        case SVR_MODIFY:
+            if (0 != ModifyCred())
+            {
+                PRINT_ERR("Failed Modification");
+                return;
+            }
+            PRINT_INFO("\n\nCred Modified");
+            UpdateCred();
+            break;
+        default:
+            break;
+    }
+}
diff --git a/resource/csdk/security/tool/svrdbeditor_src/svrdbeditorcred.h b/resource/csdk/security/tool/svrdbeditor_src/svrdbeditorcred.h
new file mode 100644 (file)
index 0000000..aa65cd0
--- /dev/null
@@ -0,0 +1,31 @@
+/* *****************************************************************
+ *
+ * Copyright 2017 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 SVRDBEDITOR_CRED_H_
+#define SVRDBEDITOR_CRED_H_
+
+#include "svrdbeditorcommon.h"
+#include "securevirtualresourcetypes.h"
+
+void RefreshCred();
+void PrintCredList(const OicSecCred_t *creds);
+void HandleCredOperation(SubOperationType_t cmd);
+
+#endif /* SVRDBEDITOR_CRED_H_ */
\ No newline at end of file
diff --git a/resource/csdk/security/tool/svrdbeditor_src/svrdbeditordoxm.c b/resource/csdk/security/tool/svrdbeditor_src/svrdbeditordoxm.c
new file mode 100644 (file)
index 0000000..6caa748
--- /dev/null
@@ -0,0 +1,636 @@
+/* *****************************************************************
+ *
+ * Copyright 2017 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 "octypes.h"
+#include "srmresourcestrings.h"
+#include "oic_malloc.h"
+
+#include "psinterface.h"
+
+#include "doxmresource.h"
+#include "svrdbeditordoxm.h"
+
+#ifdef MULTIPLE_OWNER
+#define DOXM_TYPE_CNT (6)
+#else
+#define DOXM_TYPE_CNT (5)
+#endif //MULTIPLE_OWNER
+
+static const char *DOXM_TYPE_STRING[DOXM_TYPE_CNT] =
+{
+    "OCFJustWorks", "OCFSharedPin", "OCFMfgCert",
+#ifdef MULTIPLE_OWNER
+    "PRECONFIG_PIN",
+#endif //MULTIPLE_OWNER
+    "MV_JUST_WORKS", "CON_MFG_CERT"
+};
+
+static const unsigned int DOXM_TYPE_NUMBER[DOXM_TYPE_CNT] =
+{
+    OIC_JUST_WORKS, OIC_RANDOM_DEVICE_PIN, OIC_MANUFACTURER_CERTIFICATE,
+#ifdef MULTIPLE_OWNER
+    OIC_PRECONFIG_PIN,
+#endif //MULTIPLE_OWNER
+    OIC_MV_JUST_WORKS, OIC_CON_MFG_CERT
+};
+
+#define DOXM_SCT_CNT (6)
+static const char *DOXM_SCT_STRING[DOXM_SCT_CNT] =
+{
+    "SYMMETRIC_PAIR_WISE_KEY", "SYMMETRIC_GROUP_KEY", "ASYMMETRIC_KEY",
+    "SIGNED_ASYMMETRIC_KEY", "PIN_PASSWORD", "ASYMMETRIC_ENCRYPTION_KEY"
+};
+static const unsigned int DOXM_SCT_NUMBER[DOXM_SCT_CNT] =
+{
+    SYMMETRIC_PAIR_WISE_KEY, SYMMETRIC_GROUP_KEY, ASYMMETRIC_KEY, SIGNED_ASYMMETRIC_KEY,
+    PIN_PASSWORD, ASYMMETRIC_ENCRYPTION_KEY
+};
+
+typedef enum DoxmModifyType
+{
+    DOXM_EDIT_OXM = 1,
+    DOXM_EDIT_OXMSEL,
+    DOXM_EDIT_SCT,
+    DOXM_EDIT_OWNED,
+    DOXM_EDIT_DEVICEID,
+    DOXM_EDIT_OWNER,
+    DOXM_EDIT_ROWNERID = 7,
+    DOXM_SAVE = 98,
+    DOXM_CANCEL = 99
+} DoxmModifyType;
+
+static OicSecDoxm_t *g_doxm = NULL;
+
+void DeInitDoxm(void)
+{
+    DeleteDoxmBinData(g_doxm);
+    g_doxm = NULL;
+}
+
+int GetDoxmDevID(OicUuid_t *deviceuuid)
+{
+    if (deviceuuid && g_doxm)
+    {
+        *deviceuuid = g_doxm->deviceID;
+        return 0;
+    }
+    return -1;
+}
+
+#ifdef MULTIPLE_OWNER
+static void PrintMom(const OicSecMom_t *mom)
+{
+    if (mom)
+    {
+        PRINT_DATA("%d (", mom->mode);
+
+        switch (mom->mode)
+        {
+            case OIC_MULTIPLE_OWNER_DISABLE:
+                PRINT_DATA(" OIC_MULTIPLE_OWNER_DISABLE ");
+                break;
+            case OIC_MULTIPLE_OWNER_ENABLE:
+                PRINT_DATA(" OIC_MULTIPLE_OWNER_ENABLE ");
+                break;
+            case OIC_MULTIPLE_OWNER_TIMELY_ENABLE:
+                PRINT_DATA(" OIC_MULTIPLE_OWNER_TIMELY_ENABLE ");
+                break;
+            default:
+                break;
+        }
+
+        PRINT_DATA(") \n");
+    }
+    else
+    {
+        PRINT_DATA("NULL\n");
+    }
+}
+#endif
+
+void RefreshDoxm(void)
+{
+    OCStackResult ocResult = OC_STACK_ERROR;
+    OicSecDoxm_t *tmpDoxm = NULL;
+    uint8_t *secPayload = NULL;
+    size_t payloadSize = 0;
+
+    ocResult = GetSecureVirtualDatabaseFromPS(OIC_JSON_DOXM_NAME, &secPayload, &payloadSize);
+    if (OC_STACK_OK != ocResult)
+    {
+        PRINT_WARN("GetSecureVirtualDatabaseFromPS : %d", ocResult);
+        return;
+    }
+    ocResult = CBORPayloadToDoxm(secPayload, payloadSize, &tmpDoxm);
+    if (OC_STACK_OK != ocResult)
+    {
+        PRINT_ERR("Failed CBORPayloadToDoxm");
+        OICFree(secPayload);
+        return;
+    }
+    OICFree(secPayload);
+
+    if (g_doxm)
+    {
+        DeInitDoxm();
+    }
+    g_doxm = tmpDoxm;
+}
+
+static void UpdateDoxm(void)
+{
+    OCStackResult doxmResult = OC_STACK_ERROR;
+    uint8_t *doxmPayload = NULL;
+    size_t doxmPayloadSize = 0;
+
+    doxmResult = DoxmToCBORPayload(g_doxm, &doxmPayload, &doxmPayloadSize, false);
+    if (OC_STACK_OK != doxmResult)
+    {
+        PRINT_ERR("doxmToCBORPayload error : %d", doxmResult);
+        return;
+    }
+    doxmResult = UpdateSecureResourceInPS(OIC_JSON_DOXM_NAME, doxmPayload, doxmPayloadSize);
+    if (OC_STACK_OK != doxmResult)
+    {
+        PRINT_ERR("UpdateSecureResourceInPS error : %d", doxmResult);
+        OICFree(doxmPayload);
+        return;
+    }
+    OICFree(doxmPayload);
+}
+
+void PrintDoxm(void)
+{
+    PRINT_INFO("\n\n********************* [%-20s] *********************",
+               "DOXM Resource");
+    if (g_doxm)
+    {
+        PRINT_PROG("%15s : ", OIC_JSON_OWNED_NAME);
+        (g_doxm->owned ? PrintString("True (Owned)") : PrintString("False (Unowned)"));
+
+        PRINT_PROG("%15s : ", OIC_JSON_OXMS_NAME);
+        PrintIntArray((int *)g_doxm->oxm, g_doxm->oxmLen);
+
+        PRINT_PROG("%15s : ", OIC_JSON_OXM_SEL_NAME);
+        PrintInt((int)g_doxm->oxmSel);
+
+        PRINT_PROG("%15s : ", OIC_JSON_SUPPORTED_CRED_TYPE_NAME);
+        PrintInt((int)g_doxm->sct);
+
+#ifdef MULTIPLE_OWNER
+        PRINT_PROG("%15s : ", OIC_JSON_MOM_NAME);
+        PrintMom(g_doxm->mom);
+
+        // TODO: Print Subowner List
+#endif //MULTIPLE_OWNER
+
+        PRINT_PROG("%15s : ", OIC_JSON_DEVICE_ID_NAME);
+        PrintUuid(&g_doxm->deviceID);
+
+        PRINT_PROG("%15s : ", OIC_JSON_DEVOWNERID_NAME);
+        PrintUuid(&g_doxm->owner);
+
+        PRINT_PROG("%15s : ", OIC_JSON_ROWNERID_NAME);
+        PrintUuid(&g_doxm->rownerID);
+    }
+    else
+    {
+        PRINT_PROG("doxm is empty.\n");
+        return;
+    }
+    PRINT_INFO("********************* [%-20s] *********************",
+               "DOXM Resource");
+}
+
+static int InputOxm(OicSecOxm_t **oxm, size_t *oxmLen)
+{
+    bool oxmSelected[DOXM_TYPE_CNT] = {false};
+    unsigned int sel = 0;
+    unsigned int *tmpOxm = NULL;
+    size_t tmpLen = 0;
+    size_t oxmIdx = 0;
+
+    PRINT_PROG("\nInput value identifying the owner transfer method\n");
+
+    for (;;)
+    {
+        for (size_t i = 0; i < DOXM_TYPE_CNT; i++)
+        {
+            if (oxmSelected[i])
+            {
+                PRINT_DATA("\t%zu. %s\n", i, DOXM_TYPE_STRING[i]);
+            }
+            else
+            {
+                PRINT_NORMAL("\t%zu. %s\n", i, DOXM_TYPE_STRING[i]);
+            }
+        }
+        PRINT_NORMAL("\t%d. Save\n", DOXM_SAVE);
+        PRINT_NORMAL("\t%d. Cancel\n", DOXM_CANCEL);
+        sel = InputNumber("Select number : ");
+        if (sel < DOXM_TYPE_CNT)
+        {
+            if (oxmSelected[sel])
+            {
+                tmpLen--;
+                oxmSelected[sel] = false;
+            }
+            else
+            {
+                tmpLen++;
+                oxmSelected[sel] = true;
+            }
+        }
+        else if (DOXM_SAVE == sel)
+        {
+            break;
+        }
+        else if (DOXM_CANCEL == sel)
+        {
+            return -1;
+        }
+        else
+        {
+            PRINT_WARN("Wrong number.");
+        }
+    }
+    tmpOxm = (unsigned int *)OICCalloc(tmpLen, sizeof(unsigned int));
+    if (NULL == tmpOxm)
+    {
+        PRINT_ERR("Failed to allocate memory");
+        return -1;
+    }
+    for (size_t i = 0; i < DOXM_TYPE_CNT; i++)
+    {
+        if (oxmSelected[i])
+        {
+            tmpOxm[oxmIdx++] = DOXM_TYPE_NUMBER[i];
+        }
+    }
+    if (*oxm)
+    {
+        OICFree(*oxm);
+    }
+    *oxm = tmpOxm;
+    *oxmLen = tmpLen;
+    return 0;
+}
+
+static int InputOxmSel(OicSecOxm_t *oxms, size_t oxmLen, OicSecOxm_t *oxmSel)
+{
+    bool oxmSelected[DOXM_TYPE_CNT] = {false};
+    unsigned int sel = 0;
+
+    for (size_t i = 0; i < oxmLen; i++)
+    {
+        for (size_t j = 0; j < DOXM_TYPE_CNT; j++)
+        {
+            if (DOXM_TYPE_NUMBER[j] == oxms[i])
+            {
+                oxmSelected[j] = true;
+                break;
+            }
+        }
+    }
+
+    PRINT_PROG("\nInput selected owner transfer method\n");
+    PRINT_INFO("You can select CYAN COLOR methods in oxms\n");
+    for (;;)
+    {
+
+        for (size_t i = 0; i < DOXM_TYPE_CNT; i++)
+        {
+            if (oxmSelected[i])
+            {
+                PRINT_DATA("\t%zu. %s\n", i, DOXM_TYPE_STRING[i]);
+            }
+            else
+            {
+                PRINT_NORMAL("\t%zu. %s\n", i, DOXM_TYPE_STRING[i]);
+            }
+        }
+        PRINT_NORMAL("\t%d. Cancel\n", DOXM_CANCEL);
+        sel = InputNumber("Select number : ");
+        if (sel < DOXM_TYPE_CNT)
+        {
+            if (oxmSelected[sel])
+            {
+                *oxmSel = DOXM_TYPE_NUMBER[sel];
+                break;
+            }
+            else
+            {
+                PRINT_INFO("You can select CYAN COLOR methods in oxms\n");
+            }
+        }
+        else if (DOXM_CANCEL == sel)
+        {
+            return -1;
+        }
+        else
+        {
+            PRINT_WARN("Wrong number.");
+        }
+    }
+    return 0;
+}
+
+static int InputSct(OicSecCredType_t *sct)
+{
+    unsigned int sel = 0;
+    OicSecCredType_t tmpSct = 0;
+    PRINT_PROG("\nInput the Supported Credential Types\n");
+    for (;;)
+    {
+        for (size_t i = 0; i < DOXM_SCT_CNT; i++)
+        {
+            (tmpSct & DOXM_SCT_NUMBER[i]) ? PRINT_DATA("\t%zu. %s\n", i, DOXM_SCT_STRING[i]) :
+            PRINT_NORMAL("\t%zu. %s\n", i, DOXM_SCT_STRING[i]);
+        }
+        PRINT_NORMAL("\t%d. Save\n", DOXM_SAVE);
+        PRINT_NORMAL("\t%d. Cancel\n", DOXM_CANCEL);
+        sel = InputNumber("Select number: ");
+        if (sel < DOXM_SCT_CNT)
+        {
+            tmpSct ^= DOXM_SCT_NUMBER[sel];
+        }
+        else if (DOXM_SAVE == sel)
+        {
+            break;
+        }
+        else if (DOXM_CANCEL == sel)
+        {
+            return -1;
+        }
+        else
+        {
+            PRINT_WARN("Wrong number.");
+        }
+    }
+    *sct = tmpSct;
+    return 0;
+}
+
+static bool InputOwned(void)
+{
+    char ans = 0;
+    for (;;)
+    {
+        PRINT_NORMAL("\tEnter Owned (y/n): ");
+        for (int ret = 0; 1 != ret; )
+        {
+            ret = scanf("%c", &ans);
+            for ( ; 0x20 <= getchar(); ); // for removing overflow garbages
+            // '0x20<=code' is character region
+        }
+        if ('y' == ans || 'Y' == ans || 'n' == ans || 'N' == ans)
+        {
+            ans &= ~0x20;  // for masking lower case, 'y/n'
+            break;
+        }
+        PRINT_NORMAL("\tEntered Wrong Answer. Please Enter 'y/n' Again\n");
+    }
+    return 'Y' == ans;
+}
+
+static OicSecDoxm_t *InputDoxmData(void)
+{
+    OicSecDoxm_t *doxm = NULL;
+    int ret = 0;
+
+    doxm = (OicSecDoxm_t *)OICCalloc(1, sizeof(OicSecDoxm_t));
+    if (NULL == doxm)
+    {
+        PRINT_ERR("Failed to allocate memory");
+        return NULL;
+    }
+
+    PRINT_PROG("\n\nPlease input the each entity of new doxm.\n");
+
+    ret = InputOxm(&(doxm->oxm), &(doxm->oxmLen));
+    if (0 != ret)
+    {
+        PRINT_ERR("Failed InputOxm\n");
+        DeleteDoxmBinData(doxm);
+        return NULL;
+    }
+    ret = InputOxmSel(doxm->oxm, doxm->oxmLen, &(doxm->oxmSel));
+    if (0 != ret)
+    {
+        PRINT_ERR("Failed InputOxmSel\n");
+        DeleteDoxmBinData(doxm);
+        return NULL;
+    }
+
+    ret = InputSct(&(doxm->sct));
+    if (0 != ret)
+    {
+        PRINT_ERR("Failed InputSct\n");
+        DeleteDoxmBinData(doxm);
+        return NULL;
+    }
+
+    doxm->owned = InputOwned();
+
+    PRINT_PROG(
+        "\tInput the device UUID (e.g. 61646D69-6E44-6576-6963-655575696430) : ");
+    ret = InputUuid(&(doxm->deviceID));
+    if (0 != ret)
+    {
+        PRINT_ERR("InputUuid error");
+        DeleteDoxmBinData(doxm);
+        return NULL;
+    }
+
+    PRINT_PROG(
+        "\tInput the owner UUID (e.g. 61646D69-6E44-6576-6963-655575696430) : ");
+    ret = InputUuid(&(doxm->owner));
+    if (0 != ret)
+    {
+        PRINT_ERR("InputUuid error");
+        DeleteDoxmBinData(doxm);
+        return NULL;
+    }
+
+    PRINT_PROG(
+        "\tInput the ROWNER UUID (e.g. 61646D69-6E44-6576-6963-655575696430) : ");
+    ret = InputUuid(&(doxm->rownerID));
+    if (0 != ret)
+    {
+        PRINT_ERR("InputUuid error");
+        DeleteDoxmBinData(doxm);
+        return NULL;
+    }
+
+    return doxm;
+}
+
+static int ModifyDoxm(void)
+{
+    int ret = 0;
+    int modifyMenu = 0;
+    if (NULL == g_doxm)
+    {
+        PRINT_ERR("Doxm is NULL");
+        return -1;
+    }
+
+    PRINT_PROG("\n\nPlease input the attribute you want to modify\n");
+    PRINT_DATA("\t%2d. Edit oxms\n", DOXM_EDIT_OXM);
+    PRINT_DATA("\t%2d. Edit oxmSel\n", DOXM_EDIT_OXMSEL);
+    PRINT_DATA("\t%2d. Edit sct\n", DOXM_EDIT_SCT);
+    PRINT_DATA("\t%2d. Edit owned\n", DOXM_EDIT_OWNED);
+    PRINT_DATA("\t%2d. Edit deviceID\n", DOXM_EDIT_DEVICEID);
+    PRINT_DATA("\t%2d. Edit owner\n", DOXM_EDIT_OWNER);
+    PRINT_DATA("\t%2d. Edit rownerID\n", DOXM_EDIT_ROWNERID);
+    PRINT_DATA("\t%2d. Cancel\n", DOXM_CANCEL);
+    modifyMenu = InputNumber("Select the menu : ");
+    switch (modifyMenu)
+    {
+        case DOXM_EDIT_OXM:
+            if (0 != InputOxm(&(g_doxm->oxm), &(g_doxm->oxmLen)))
+            {
+                PRINT_ERR("Failed InputOxm");
+                return -1;
+            }
+            break;
+        case DOXM_EDIT_OXMSEL:
+            if (0 != InputOxmSel(g_doxm->oxm, g_doxm->oxmLen, &(g_doxm->oxmSel)))
+            {
+                PRINT_ERR("Failed InputOxmSel");
+                return -1;
+            }
+            break;
+        case DOXM_EDIT_SCT:
+            if (0 != InputSct(&(g_doxm->sct)))
+            {
+                PRINT_ERR("Failed InputSct");
+                return -1;
+            }
+            break;
+        case DOXM_EDIT_OWNED:
+            g_doxm->owned = InputOwned();
+            break;
+        case DOXM_EDIT_DEVICEID:
+            PRINT_PROG(
+                "\tInput the DEVICE ID (e.g. 61646D69-6E44-6576-6963-655575696430) : ");
+            ret = InputUuid(&(g_doxm->deviceID));
+            if (0 != ret)
+            {
+                PRINT_ERR("InputUuid error");
+                return ret;
+            }
+            break;
+        case DOXM_EDIT_OWNER:
+            PRINT_PROG(
+                "\tInput the OWNER ID (e.g. 61646D69-6E44-6576-6963-655575696430) : ");
+            ret = InputUuid(&(g_doxm->owner));
+            if (0 != ret)
+            {
+                PRINT_ERR("InputUuid error");
+                return ret;
+            }
+            break;
+        case DOXM_EDIT_ROWNERID:
+            PRINT_PROG(
+                "\tInput the ROWNER ID (e.g. 61646D69-6E44-6576-6963-655575696430) : ");
+            ret = InputUuid(&(g_doxm->rownerID));
+            if (0 != ret)
+            {
+                PRINT_ERR("InputUuid error");
+                return ret;
+            }
+            break;
+        case DOXM_CANCEL:
+            ret = -1;
+            break;
+        default:
+            PRINT_ERR("Invalid menu");
+            ret = -1;
+            break;
+    }
+    return ret;
+}
+
+void HandleDoxmOperation(const SubOperationType_t cmd)
+{
+    if (SVR_EDIT_IDX_SIZE <= cmd)
+    {
+        PRINT_ERR("Invalid menu");
+        return;
+    }
+    switch (cmd)
+    {
+        case SVR_PRINT:
+            PrintDoxm();
+            break;
+        case SVR_ADD:
+            if (g_doxm)
+            {
+                PRINT_ERR("Already exist");
+                return;
+            }
+            else
+            {
+                g_doxm = InputDoxmData();
+                if (NULL == g_doxm)
+                {
+                    PRINT_ERR("Failed to InputDoxmData");
+                    return;
+                }
+                UpdateDoxm();
+                PrintDoxm();
+            }
+            break;
+        case SVR_REMOVE:
+            if (g_doxm)
+            {
+                OCStackResult doxmResult = OC_STACK_ERROR;
+
+                DeleteDoxmBinData(g_doxm);
+                g_doxm = NULL;
+                doxmResult = UpdateSecureResourceInPS(OIC_JSON_DOXM_NAME, NULL, 0);
+                if (OC_STACK_OK != doxmResult)
+                {
+                    PRINT_ERR("UpdateSecureResourceInPS error : %d", doxmResult);
+                    return;
+                }
+            }
+            else
+            {
+                PRINT_ERR("Not exist");
+                return;
+            }
+            break;
+        case SVR_MODIFY:
+            if (0 != ModifyDoxm())
+            {
+                PRINT_ERR("Failed modification");
+                return;
+            }
+            PRINT_INFO("\n\nDoxm Modified");
+            PrintDoxm();
+            UpdateDoxm();
+            break;
+        default:
+            PRINT_ERR("Invalid menu");
+            break;
+    }
+}
diff --git a/resource/csdk/security/tool/svrdbeditor_src/svrdbeditordoxm.h b/resource/csdk/security/tool/svrdbeditor_src/svrdbeditordoxm.h
new file mode 100644 (file)
index 0000000..0c4ac6b
--- /dev/null
@@ -0,0 +1,33 @@
+/* *****************************************************************
+ *
+ * Copyright 2017 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 SVRDBEDITOR_DOXM_H_
+#define SVRDBEDITOR_DOXM_H_
+
+#include "svrdbeditorcommon.h"
+#include "securevirtualresourcetypes.h"
+
+void DeInitDoxm(void);
+int GetDoxmDevID(OicUuid_t *deviceuuid);
+void RefreshDoxm(void);
+void PrintDoxm(void);
+void HandleDoxmOperation(const SubOperationType_t cmd);
+
+#endif /* SVRDBEDITOR_DOXM_H_ */
diff --git a/resource/csdk/security/tool/svrdbeditor_src/svrdbeditorpstat.c b/resource/csdk/security/tool/svrdbeditor_src/svrdbeditorpstat.c
new file mode 100644 (file)
index 0000000..a82dbbc
--- /dev/null
@@ -0,0 +1,490 @@
+/* *****************************************************************
+ *
+ * Copyright 2017 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 "octypes.h"
+#include "oic_malloc.h"
+
+#include "securevirtualresourcetypes.h"
+#include "srmresourcestrings.h"
+#include "psinterface.h"
+
+#include "pstatresource.h"
+#include "svrdbeditorpstat.h"
+
+#define DPM_CNT (6)
+#define DPOM_CNT (3)
+
+static OicSecPstat_t *g_pstat = NULL;
+
+typedef enum PstatModifyType
+{
+    PSTAT_EDIT_ISOP = 1,
+    PSTAT_EDIT_CM,
+    PSTAT_EDIT_TM,
+    PSTAT_EDIT_OM,
+    PSTAT_EDIT_SM,
+    PSTAT_EDIT_ROWNERID = 6
+} PstatModifyType_t;
+
+void DeInitPstat(void)
+{
+    DeletePstatBinData(g_pstat);
+    g_pstat = NULL;
+}
+
+void RefreshPstat(void)
+{
+    OCStackResult ocResult = OC_STACK_ERROR;
+    OicSecPstat_t *tmpPstat = NULL;
+    uint8_t *secPayload = NULL;
+    size_t payloadSize = 0;
+
+    ocResult = GetSecureVirtualDatabaseFromPS(OIC_JSON_PSTAT_NAME, &secPayload, &payloadSize);
+    if (OC_STACK_OK != ocResult)
+    {
+        PRINT_WARN("GetSecureVirtualDatabaseFromPS : %d", ocResult);
+        return;
+    }
+
+    ocResult = CBORPayloadToPstat(secPayload, payloadSize, &tmpPstat);
+    if (OC_STACK_OK != ocResult)
+    {
+        PRINT_ERR("CBORPayloadToPstat : %d", ocResult);
+        OICFree(secPayload);
+        return;
+    }
+    OICFree(secPayload);
+
+    if (g_pstat)
+    {
+        DeInitPstat();
+    }
+    g_pstat = tmpPstat;
+}
+
+static void UpdatePstat(void)
+{
+    OCStackResult pstatResult = OC_STACK_ERROR;
+    uint8_t *pstatPayload = NULL;
+    size_t pstatPayloadSize = 0;
+
+    pstatResult = PstatToCBORPayload(g_pstat, &pstatPayload, &pstatPayloadSize, false);
+    if (OC_STACK_OK != pstatResult)
+    {
+        PRINT_ERR("PstatToCBORPayload error : %d", pstatResult);
+        return;
+    }
+    pstatResult = UpdateSecureResourceInPS(OIC_JSON_PSTAT_NAME, pstatPayload, pstatPayloadSize);
+    if (OC_STACK_OK != pstatResult)
+    {
+        PRINT_ERR("UpdateSecureResourceInPS error : %d", pstatResult);
+        OICFree(pstatPayload);
+        return;
+    }
+    OICFree(pstatPayload);
+}
+
+static void PrintDpm(const OicSecDpm_t dpm)
+{
+    PRINT_DATA("%d (", dpm);
+
+    if (NORMAL == dpm)
+    {
+        PRINT_DATA(" NORMAL ");
+    }
+    if (dpm & RESET)
+    {
+        PRINT_DATA(" RESET ");
+    }
+    if (dpm & TAKE_OWNER)
+    {
+        PRINT_DATA(" TAKE_OWNER ");
+    }
+    if (dpm & BOOTSTRAP_SERVICE)
+    {
+        PRINT_DATA(" BOOTSTRAP_SERVICE ");
+    }
+    if (dpm & SECURITY_MANAGEMENT_SERVICES)
+    {
+        PRINT_DATA(" SECURITY_MANAGEMENT_SERVICES ");
+    }
+    if (dpm & PROVISION_CREDENTIALS)
+    {
+        PRINT_DATA(" PROVISION_CREDENTIALS ");
+    }
+    if (dpm & PROVISION_ACLS)
+    {
+        PRINT_DATA(" PROVISION_ACLS ");
+    }
+
+    PRINT_DATA(") \n");
+}
+
+static void PrintDpom(const OicSecDpom_t dpom)
+{
+    PRINT_DATA("%d (", dpom);
+
+    if (dpom & MULTIPLE_SERVICE_SERVER_DRIVEN)
+    {
+        PRINT_DATA(" MULTIPLE_SERVICE_SERVER_DRIVEN ");
+    }
+    if (dpom & SINGLE_SERVICE_SERVER_DRIVEN)
+    {
+        PRINT_DATA(" SINGLE_SERVICE_SERVER_DRIVEN ");
+    }
+    if (dpom & SINGLE_SERVICE_CLIENT_DRIVEN)
+    {
+        PRINT_DATA(" SINGLE_SERVICE_CLIENT_DRIVEN ");
+    }
+    PRINT_DATA(") \n");
+}
+
+void PrintPstat(void)
+{
+    PRINT_INFO("\n\n********************* [%-20s] *********************",
+               "PSTAT Resource");
+    if (g_pstat)
+    {
+        PRINT_PROG("%15s : ", OIC_JSON_ISOP_NAME);
+        (g_pstat->isOp ? PrintString("True") : PrintString("False"));
+
+        //cm
+        PRINT_PROG("%15s : ", OIC_JSON_CM_NAME);
+        PrintDpm(g_pstat->cm);
+
+        //tm
+        PRINT_PROG("%15s : ", OIC_JSON_TM_NAME);
+        PrintDpm(g_pstat->tm);
+
+        //om
+        PRINT_PROG("%15s : ", OIC_JSON_OM_NAME);
+        PrintDpom(g_pstat->om);
+
+        //sm
+        PRINT_PROG("%15s : \n", OIC_JSON_SM_NAME);
+        for (size_t i = 0; i < g_pstat->smLen; i++)
+        {
+            PRINT_DATA("supported mode #%zu : ", i + 1);
+            PrintDpom(g_pstat->sm[i]);
+        }
+
+        PRINT_PROG("%15s : ", OIC_JSON_ROWNERID_NAME);
+        PrintUuid(&(g_pstat->rownerID));
+    }
+    else
+    {
+        PRINT_PROG("pstat is empty.\n");
+    }
+    PRINT_INFO("********************* [%-20s] *********************",
+               "PSTAT Resource");
+}
+
+static unsigned int InputDpm(void)
+{
+    unsigned int dpm = 0;
+    unsigned int dpm_msk = 1;  //default mask
+    const char *Operation_Mode[DPM_CNT] =
+    {
+        "RESET", "TAKE_OWNER", "BOOTSTRAP_SERVICE", "SECURITY_MANAGEMENT_SERVICES",
+        "PROVISION_CREDENTIALS", "PROVISION_ACLS"
+    };
+
+    for (int i = 0; i < DPM_CNT; i++)
+    {
+        char ans = 0;
+        for (;;)
+        {
+            PRINT_NORMAL("\tEnter %s Mode (y/n): ", Operation_Mode[i]);
+            for (int ret = 0; 1 != ret; )
+            {
+                ret = scanf("%c", &ans);
+                for ( ; 0x20 <= getchar(); ); // for removing overflow garbages
+                // '0x20<=code' is character region
+            }
+            if ('y' == ans || 'Y' == ans || 'n' == ans || 'N' == ans)
+            {
+                ans &= ~0x20;  // for masking lower case, 'y/n'
+                break;
+            }
+            PRINT_NORMAL("\tEntered Wrong Answer. Please Enter 'y/n' Again\n");
+        }
+        if ('Y' == ans)
+        {
+            dpm |= dpm_msk;
+        }
+        dpm_msk <<= 1;
+    }
+    return dpm;
+}
+
+static unsigned int InputDpom()
+{
+    unsigned int dpom = 0;
+    unsigned int dpom_msk = 1;  //default mask
+    const char *Operation_Mode[DPOM_CNT] =
+    {
+        "MULTIPLE_SERVICE_SERVER_DRIVEN", "SINGLE_SERVICE_SERVER_DRIVEN",
+        "SINGLE_SERVICE_CLIENT_DRIVEN"
+    };
+
+    PRINT_PROG("SINGLE_SERVICE_CLIENT_DRIVEN is the only mode IoTivity supports currently\n");
+
+    for (int i = 0; i < DPOM_CNT; i++)
+    {
+        char ans = 0;
+        for (;;)
+        {
+            PRINT_NORMAL("\tEnter %s Mode (y/n): ", Operation_Mode[i]);
+            for (int ret = 0; 1 != ret; )
+            {
+                ret = scanf("%c", &ans);
+                for ( ; 0x20 <= getchar(); ); // for removing overflow garbages
+                // '0x20<=code' is character region
+            }
+            if ('y' == ans || 'Y' == ans || 'n' == ans || 'N' == ans)
+            {
+                ans &= ~0x20;  // for masking lower case, 'y/n'
+                break;
+            }
+            PRINT_NORMAL("\tEntered Wrong Answer. Please Enter 'y/n' Again\n");
+        }
+        if ('Y' == ans)
+        {
+            dpom |= dpom_msk;
+        }
+        dpom_msk <<= 1;
+    }
+    return dpom;
+}
+
+static OicSecPstat_t *InputPstatData(void)
+{
+    OicSecPstat_t *pstat = NULL;
+    int isop = 0;
+
+    pstat = (OicSecPstat_t *)OICCalloc(1, sizeof(OicSecPstat_t));
+    if (NULL == pstat)
+    {
+        PRINT_ERR("Failed to allocate memory");
+        return NULL;
+    }
+
+    PRINT_PROG("\n\nPlease input the each entity of new pstat.\n");
+
+    isop = InputNumber("Input the isop value ( 0.False, 1.True ) : ");
+    if (isop < 0 || 1 < isop)
+    {
+        PRINT_ERR("Invalid input");
+        OICFree(pstat);
+        return NULL;
+    }
+    else
+    {
+        pstat->isOp = (1 == isop ? true : false);
+    }
+
+    PRINT_PROG("Input Current Mode\n");
+    pstat->cm = InputDpm();
+    PRINT_PROG("Input Target Mode\n");
+    pstat->tm = InputDpm();
+    PRINT_PROG("Input Operational Mode\n");
+
+    pstat->om = InputDpom();
+    pstat->smLen = 1; // supported only one dpom mode in current iotivity
+    pstat->sm = (OicSecDpom_t *)OICCalloc(pstat->smLen, sizeof(OicSecDpom_t));
+    if (NULL == pstat->sm)
+    {
+        PRINT_ERR("InputPstatData : Failed to allocate memory");
+        OICFree(pstat);
+        return NULL;
+    }
+    for (size_t i = 0; i < pstat->smLen; i++)
+    {
+        PRINT_PROG("Input dpom #%zu", i);
+        pstat->sm[i] = InputDpom();
+    }
+
+    PRINT_PROG(
+        "\tInput the ROWNER UUID (e.g. 61646D69-6E44-6576-6963-655575696430) : ");
+    if (0 != InputUuid(&(pstat->rownerID)))
+    {
+        PRINT_ERR("InputUuid error");
+        OICFree(pstat->sm);
+        OICFree(pstat);
+        return NULL;
+    }
+    return pstat;
+}
+
+static int ModifyPstat(void)
+{
+    int ret = 0;
+    int modifyMenu = 0;
+    if (NULL == g_pstat)
+    {
+        PRINT_ERR("pstat is NULL");
+        return -1;
+    }
+
+    PRINT_PROG("\n\nPlease input the attribute you want to modify\n");
+    PRINT_DATA("\t%2d. Edit isop\n", PSTAT_EDIT_ISOP);
+    PRINT_DATA("\t%2d. Edit cm\n", PSTAT_EDIT_CM);
+    PRINT_DATA("\t%2d. Edit tm\n", PSTAT_EDIT_TM);
+    PRINT_DATA("\t%2d. Edit om\n", PSTAT_EDIT_OM);
+    PRINT_DATA("\t%2d. Edit sm\n", PSTAT_EDIT_SM);
+    PRINT_DATA("\t%2d. Edit rownerID\n", PSTAT_EDIT_ROWNERID);
+    PRINT_DATA("\t%2d. Back to the previous\n", BACK);
+    modifyMenu = InputNumber("Select the menu : ");
+    switch (modifyMenu)
+    {
+        case PSTAT_EDIT_ISOP:
+            {
+                int isop = InputNumber("Input the isop value ( 0.False, 1.True ) : ");
+                if (isop < 0 || 1 < isop)
+                {
+                    PRINT_ERR("Invalid input");
+                    return -1;
+                }
+                else
+                {
+                    g_pstat->isOp = (1 == isop ? true : false);
+                }
+                break;
+            }
+        case PSTAT_EDIT_CM :
+            PRINT_PROG("Input Current Mode\n");
+            g_pstat->cm = InputDpm();
+            break;
+        case PSTAT_EDIT_TM:
+            PRINT_PROG("Input Target Mode\n");
+            g_pstat->tm = InputDpm();
+            break;
+        case PSTAT_EDIT_OM:
+            PRINT_PROG("Input Operational Mode\n");
+            g_pstat->om = InputDpom();
+            break;
+        case PSTAT_EDIT_SM:
+            {
+                OicSecDpom_t *sm = NULL;
+                size_t smLen = 1;
+
+                sm = (OicSecDpom_t *)OICCalloc(smLen, sizeof(OicSecDpom_t));
+                if (NULL == sm)
+                {
+                    PRINT_ERR("Failed to allocate memory");
+                    return -1;
+                }
+                for (size_t i = 0; i < smLen; i++)
+                {
+                    PRINT_PROG("Input dpom #%zu", i);
+                    sm[i] = InputDpom();
+                }
+                if (g_pstat->sm)
+                {
+                    OICFree(g_pstat->sm);
+                }
+                g_pstat->smLen = smLen;
+                g_pstat->sm = sm;
+                break;
+            }
+        case PSTAT_EDIT_ROWNERID:
+            PRINT_PROG(
+                "\tInput the ROWNER UUID (e.g. 61646D69-6E44-6576-6963-655575696430) : ");
+            ret = InputUuid(&(g_pstat->rownerID));
+            if (0 != ret)
+            {
+                PRINT_ERR("InputUuid error");
+                return ret;
+            }
+            break;
+        case BACK:
+            PRINT_INFO("Back to the previous menu.");
+            break;
+        default:
+            PRINT_ERR("Wrong type Number");
+            ret = -1;
+            break;
+    }
+    return ret;
+}
+
+void HandlePstatOperation(const SubOperationType_t cmd)
+{
+    OCStackResult pstatResult = OC_STACK_ERROR;
+
+    if (SVR_EDIT_IDX_SIZE <= cmd)
+    {
+        PRINT_ERR("Invalid menu for pstat");
+        return;
+    }
+    switch (cmd)
+    {
+        case SVR_PRINT:
+            PrintPstat();
+            break;
+        case SVR_ADD:
+            if (g_pstat)
+            {
+                PRINT_ERR("Already exist");
+                return;
+            }
+            else
+            {
+                g_pstat = InputPstatData();
+                if (NULL == g_pstat)
+                {
+                    PRINT_ERR("Failed to InputPstatData");
+                    return;
+                }
+                UpdatePstat();
+            }
+            break;
+        case SVR_REMOVE:
+            if (g_pstat)
+            {
+                DeInitPstat();
+                pstatResult = UpdateSecureResourceInPS(OIC_JSON_PSTAT_NAME, NULL, 0);
+                if (OC_STACK_OK != pstatResult)
+                {
+                    PRINT_ERR("UpdateSecureResourceInPS error : %d", pstatResult);
+                    return;
+                }
+            }
+            else
+            {
+                PRINT_ERR("pstat is NULL");
+                return;
+            }
+            break;
+        case SVR_MODIFY:
+            if (0 != ModifyPstat())
+            {
+                PRINT_ERR("Failed Modify");
+                return;
+            }
+            PRINT_INFO("\n\nPstat Modified");
+            PrintPstat();
+            UpdatePstat();
+            break;
+        default:
+            PRINT_ERR("Invalid menu for pstat");
+            break;
+    }
+}
diff --git a/resource/csdk/security/tool/svrdbeditor_src/svrdbeditorpstat.h b/resource/csdk/security/tool/svrdbeditor_src/svrdbeditorpstat.h
new file mode 100644 (file)
index 0000000..083730f
--- /dev/null
@@ -0,0 +1,31 @@
+/* *****************************************************************
+ *
+ * Copyright 2017 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 SVRDBEDITOR_PSTAT_H_
+#define SVRDBEDITOR_PSTAT_H_
+
+#include "svrdbeditorcommon.h"
+
+void DeInitPstat(void);
+void RefreshPstat(void);
+void PrintPstat(void);
+void HandlePstatOperation(const SubOperationType_t cmd);
+
+#endif /* SVRDBEDITOR_PSTAT_H_ */
index 6df16cf..705c850 100644 (file)
@@ -62,13 +62,12 @@ srmtest_env.PrependUnique(LIBS = ['ocsrm',
 
 if srmtest_env.get('SECURED') == '1':
     srmtest_env.AppendUnique(LIBS = ['mbedtls','mbedx509','mbedcrypto'])
-    srmtest_env.AppendUnique(LIBS = ['tinydtls'])
 
 if srmtest_env.get('LOGGING') == '1':
        srmtest_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
 
 if srmtest_env.get('MULTIPLE_OWNER') == '1':
-       srmtest_env.AppendUnique(CPPDEFINES=['_ENABLE_MULTIPLE_OWNER_'])
+       srmtest_env.AppendUnique(CPPDEFINES=['MULTIPLE_OWNER'])
 
 if target_os == 'windows':
        srmtest_env.AppendUnique(LINKFLAGS = ['/subsystem:CONSOLE'])
@@ -91,10 +90,10 @@ unittest = srmtest_env.Program('unittest', ['aclresourcetest.cpp',
                                             'srmutility.cpp',
                                             'iotvticalendartest.cpp',
                                             'base64tests.cpp',
-                                            'svcresourcetest.cpp',
                                             'srmtestcommon.cpp',
                                             'directpairingtest.cpp',
-                                            'crlresourcetest.cpp'])
+                                            'crlresourcetest.cpp',
+                                            'psinterface.cpp'])
 
 Alias("test", [unittest])
 
index c20e297..29fb6d3 100644 (file)
@@ -180,7 +180,7 @@ TEST(ACLResourceTest, CBORACLConversion)
     OicSecAce_t *ace = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
     ASSERT_TRUE(NULL != ace);
     ace->permission = permission[0];
-    memcpy(ace->subjectuuid.id, subjectUuid[0], strlen(subjectUuid[0]));
+    memcpy(ace->subjectuuid.id, subjectUuid[0], UUID_LENGTH);
     EXPECT_EQ(true, AddResourceToACE(ace, "/oic/res", "oic.wk.res", "oic.if.ll"));
     EXPECT_EQ(true, AddResourceToACE(ace, "/oic/d", "oic.wk.d", "oic.if.r"));
     EXPECT_EQ(true, AddResourceToACE(ace, "/oic/p", "oic.wk.p", "oic.if.r"));
@@ -192,7 +192,7 @@ TEST(ACLResourceTest, CBORACLConversion)
     OicSecAce_t *ace1 = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
     ASSERT_TRUE(NULL != ace1);
     ace1->permission = permission[1];
-    memcpy(ace1->subjectuuid.id, subjectUuid[1], strlen(subjectUuid[1]));
+    memcpy(ace1->subjectuuid.id, subjectUuid[1], UUID_LENGTH);
     EXPECT_EQ(true, AddResourceToACE(ace1, "/oic/sec/doxm", "oic.r.doxm" ,"oic.if.baseline"));
     EXPECT_EQ(true, AddResourceToACE(ace1, "/oic/sec/pstat", "oic.r.pstat" ,"oic.if.baseline"));
     LL_APPEND(secAcl->aces, ace1);
@@ -200,7 +200,7 @@ TEST(ACLResourceTest, CBORACLConversion)
     OicSecAce_t *ace2 = (OicSecAce_t*)OICCalloc(1, sizeof(OicSecAce_t));
     ASSERT_TRUE(NULL != ace2);
     ace2->permission = permission[2];
-    memcpy(ace2->subjectuuid.id, subjectUuid[2], strlen(subjectUuid[2]));
+    memcpy(ace2->subjectuuid.id, subjectUuid[2], UUID_LENGTH);
     EXPECT_EQ(true, AddResourceToACE(ace2, "/oic/light", "oic.core", "oic.if.baseline"));
     EXPECT_EQ(true, AddResourceToACE(ace2, "/oic/garage", "oic.core", "oic.if.baseline"));
     LL_APPEND(secAcl->aces, ace2);
index 3dd6fd4..6640831 100644 (file)
@@ -19,6 +19,7 @@
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
 #include "gtest/gtest.h"
+extern "C" {
 #include "logger.h"
 #include "ocpayload.h"
 #include "ocstack.h"
 #include "srmutility.h"
 #include "psinterface.h"
 #include "security_internals.h"
-
+#include "secureresourcemanager.h"
+}
 #define TAG "SRM-CRED-UT"
 
+const char *SRP_TEST_FILE_NAME = "secureresourceprovider.dat";
+static OCPersistentStorage ps;
+
 OicSecCred_t * getCredList()
 {
     size_t sz = 0;
@@ -118,6 +123,27 @@ static void printCred(const OicSecCred_t * cred)
     }
 }
 
+FILE *fOpenCustom(const char *path, const char *mode)
+{
+    (void)path;
+    FILE *fp = fopen(SRP_TEST_FILE_NAME, mode);
+    return fp;
+}
+
+//init db
+TEST(CredResourceTest,initDb)
+{
+    ps.open = fOpenCustom;
+    ps.read = fread;
+    ps.write = fwrite;
+    ps.close = fclose;
+    ps.unlink = unlink;
+
+    SRMRegisterPersistentStorageHandler(&ps);
+
+    InitPersistentStorageInterface();
+}
+
  //InitCredResource Tests
 TEST(CredResourceTest, InitCredResource)
 {
@@ -158,17 +184,15 @@ TEST(CredResourceTest, CredEntityHandlerInvalidFlag)
 }
 
 //Cred DELETE request
+/*
 TEST(CredResourceTest, CredEntityHandlerDeleteTest)
 {
     OCEntityHandlerRequest ehReq =  OCEntityHandlerRequest();
-    static OCPersistentStorage ps =  OCPersistentStorage();
     const OicSecCred_t* subjectCred1 = NULL;
     const OicSecCred_t* subjectCred2 = NULL;
     OCEntityHandlerResult ehRet = OC_EH_ERROR;
     char query[] = "subjectuuid=31313131-3131-3131-3131-313131313131"; //canonical uuid of subject1
 
-    SetPersistentHandler(&ps, true);
-
     OicSecCred_t *cred = getCredList();
     ASSERT_TRUE(NULL != cred);
     uint8_t *payload = NULL;
@@ -221,6 +245,7 @@ TEST(CredResourceTest, CredEntityHandlerDeleteTest)
     DeleteCredList(cred);
     OCPayloadDestroy((OCPayload *)ehReq.payload);
 }
+*/
 
 TEST(CredResourceTest, CredToCBORPayloadNULL)
 {
@@ -346,6 +371,7 @@ TEST(CredResourceTest, GenerateCredentialValidInput)
     DeleteCredList(cred);
 }
 
+/*
 TEST(CredResourceTest, GenerateAndAddCredentialValidInput)
 {
     OicUuid_t rownerID = {{0}};
@@ -384,6 +410,7 @@ TEST(CredResourceTest, GenerateAndAddCredentialValidInput)
 
     DeleteCredList(headCred);
 }
+*/
 
 #if 0
 TEST(CredGetResourceDataTest, GetCredResourceDataValidSubject)
index c617a70..1aab21f 100644 (file)
@@ -87,9 +87,7 @@ TEST(CRLResourceTest, CBORPayloadToCrl)
 //GetDerCrl Tests
 TEST(CRLResourceTest, GetDerCrl)
 {
-#define CRL_MAX_LEN 1024
-    uint8_t crlData[CRL_MAX_LEN] = {0};
-    ByteArray crlArray = {crlData, CRL_MAX_LEN};
+    ByteArray crlArray = {NULL, 0};
     GetDerCrl(&crlArray);
     EXPECT_NE(0, crlArray.len);
 }
index 0fc7662..a5a03dd 100644 (file)
@@ -199,25 +199,3 @@ TEST(DoxmResourceTest, CBORPayloadToDoxmVALID)
     DeleteDoxmBinData(doxm);
     OICFree(payload);
 }
-
-#if 0
-//HandleDoxmPostRequest Test
-TEST(HandleDoxmPostRequestTest, HandleDoxmPostRequestValidInput)
-{
-    OCEntityHandlerRequest ehRequest = {};
-    OCServerRequest svRequest = {};
-
-    OicSecDoxm_t * doxm =  getBinDoxm();
-
-    strcpy(svRequest.addressInfo.IP.ipAddress, "10.10.10.10");
-    svRequest.addressInfo.IP.port = 2345;
-    svRequest.connectivityType = CA_ETHERNET;
-
-    ehRequest.reqJSONPayload = (unsigned char *) BinToDoxmJSON(doxm);
-    ehRequest.requestHandle = (OCRequestHandle) &svRequest;
-
-    EXPECT_EQ(OC_EH_ERROR, HandleDoxmPostRequest(&ehRequest));
-    DeleteDoxmBinData(doxm);
-    OICFree(ehRequest.reqJSONPayload);
-}
-#endif
diff --git a/resource/csdk/security/unittest/psinterface.cpp b/resource/csdk/security/unittest/psinterface.cpp
new file mode 100644 (file)
index 0000000..a32a6f4
--- /dev/null
@@ -0,0 +1,124 @@
+/* *****************************************************************
+ *
+ * Copyright 2016 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 <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+
+#include "gtest/gtest.h"
+
+#define STR(...) STR_(__VA_ARGS__)
+#define STR_(...) # __VA_ARGS__
+
+#define DNEF "does_not_exist.dat"
+#define DEFAULT_FILE "oic_svr_db_prov.dat"
+
+extern "C" {
+#include "../src/psinterface.c"
+
+#include "ocstack.h"
+#include "cainterface.h"
+#include "secureresourcemanager.h"
+}
+
+static OCPersistentStorage _ps;
+
+char localPath[PATH_MAX] = {0};
+
+FILE *fopenCustom(const char *path, const char *mode)
+{
+    (void)path;
+    FILE *fp = fopen(localPath, mode);
+    return fp;
+}
+
+TEST(init,db)
+{
+    _ps.open = fopenCustom;
+    _ps.read = fread;
+    _ps.write = fwrite;
+    _ps.close = fclose;
+    _ps.unlink = unlink;
+
+    int len = strlen(STR(SECURITY_BUILD_UNITTEST_DIR)) + strlen(DEFAULT_FILE) + 1;
+    snprintf(localPath, len, "%s%s", STR(SECURITY_BUILD_UNITTEST_DIR), DEFAULT_FILE);
+
+    InitPersistentStorageInterface();
+
+    EXPECT_EQ(OC_STACK_OK, SRMRegisterPersistentStorageHandler(&_ps));
+}
+
+TEST(PersistentStorageInterfaceTest, Null)
+{
+    EXPECT_NE(OC_STACK_OK,GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, NULL, NULL));
+}
+
+TEST(PersistentStorageInterfaceTest, NullPayload)
+{
+
+    size_t payloadSize = 0;
+
+    EXPECT_NE(OC_STACK_OK,GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, NULL, &payloadSize));
+}
+
+TEST(PersistentStorageInterfaceTest, NullPayloadSize)
+{
+
+    uint8_t* payload = NULL;
+
+    EXPECT_NE(OC_STACK_OK,GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &payload, NULL));
+}
+
+TEST(PersistentStorageInterfaceTest, DoesNotExistsDbFile)
+{
+    uint8_t* payload = NULL;
+    size_t payloadSize = 0;
+
+    int len = strlen(STR(SECURITY_BUILD_UNITTEST_DIR)) + strlen(DEFAULT_FILE) + 1;
+    snprintf(localPath, len, "%s%s", STR(SECURITY_BUILD_UNITTEST_DIR), DNEF);
+    unlink(localPath);
+
+    InitPersistentStorageInterface();
+
+    EXPECT_NE(OC_STACK_OK,GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &payload, &payloadSize));
+}
+
+TEST(PersistentStorageInterfaceTest, CredRead)
+{
+
+    uint8_t* payload = NULL;
+    size_t payloadSize = 0;
+
+    int len = strlen(STR(SECURITY_BUILD_UNITTEST_DIR)) + strlen(DEFAULT_FILE) + 1;
+    snprintf(localPath, len, "%s%s", STR(SECURITY_BUILD_UNITTEST_DIR), DEFAULT_FILE);
+    InitPersistentStorageInterface();
+
+    EXPECT_EQ(OC_STACK_OK,GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &payload, &payloadSize));
+}
+
+TEST(PersistentStorageInterfaceTest, FileSizeCashe)
+{
+
+    uint8_t* payload = NULL;
+    size_t payloadSize = 0;
+
+    InitPersistentStorageInterface();
+
+    EXPECT_EQ(OC_STACK_OK,GetSecureVirtualDatabaseFromPS(OIC_JSON_CRED_NAME, &payload, &payloadSize));
+}
index 9a38f48..efc9ff7 100644 (file)
@@ -32,6 +32,7 @@
 #include "ocstack.h"
 #include "cainterface.h"
 #include "secureresourcemanager.h"
+#include "srmtestcommon.h"
 
 using namespace std;
 
@@ -54,34 +55,6 @@ void UTErrorHandler(const CAEndpoint_t * /*endPoint*/,
      EXPECT_TRUE(true) << "UTErrorHandler\n";
 }
 
-FILE *utopen(const char *path, const char *mode)
-{
-    EXPECT_TRUE((path != NULL)) << "utopen\n";
-    FILE *stream = fopen(path, mode);
-    return stream;
-
-}
-
-size_t utread(void *ptr, size_t size, size_t nmemb, FILE *stream)
-{
-    return fread(ptr, size, nmemb, stream);
-}
-
-size_t utwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
-{
-    return fwrite(ptr, size, nmemb, stream);
-}
-
-int utclose(FILE *fp)
-{
-    EXPECT_TRUE((fp != NULL)) << "utclose\n";
-    return fclose(fp);
-}
-int utunlink(const char *path)
-{
-    EXPECT_TRUE((path != NULL)) << "utunlink\n";
-    return unlink(path);
-}
 static OCPersistentStorage gpsi;
 
 //RegisterHandler Tests
@@ -114,14 +87,7 @@ TEST(PersistentStorageHandlerTest, RegisterNullHandler)
 
 TEST(PersistentStorageHandlerTest, RegisterValidHandler)
 {
-    gpsi.open = utopen;
-    gpsi.read = utread;
-    gpsi.write = utwrite;
-    gpsi.close = utclose;
-    gpsi.unlink = utunlink;
-
-    EXPECT_EQ(OC_STACK_OK,
-            SRMRegisterPersistentStorageHandler(&gpsi));
+    SetPersistentHandler(&gpsi, true);
     OCPersistentStorage *ps = SRMGetPersistentStorageHandler();
     EXPECT_TRUE(&gpsi == ps);
 }
index 5bfe64e..9eb7096 100644 (file)
@@ -143,11 +143,20 @@ bool ReadCBORFile(const char* filename, const char* rsrcname, uint8_t **payload,
     return status;
 }
 
+static FILE* utopen(const char *filename, const char *mode)
+{
+    int len = strlen(STRINGIZE(SECURITY_BUILD_UNITTEST_DIR)) + strlen(filename) + 1;
+    char filepath[1024] = {0};
+    int ret = snprintf(filepath, len, "%s%s", STRINGIZE(SECURITY_BUILD_UNITTEST_DIR), filename);
+    printf("Root build path: %s \n", filepath);
+    return fopen(filepath, mode);
+}
+
 void SetPersistentHandler(OCPersistentStorage *ps, bool set)
 {
     if (set)
     {
-        ps->open = fopen;
+        ps->open = utopen;
         ps->read = fread;
         ps->write = fwrite;
         ps->close = fclose;
index 0464d5a..a44332e 100644 (file)
@@ -64,3 +64,24 @@ TEST(ParseRestQueryTest, ParseRestMultipleQuery)
     }
     printf("\n");
 }
+
+#if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
+TEST(SetUuidSeedTest, NullParam)
+{
+    EXPECT_EQ(OC_STACK_INVALID_PARAM, SetDeviceIdSeed(NULL, 0));
+}
+
+TEST(SetUuidSeedTest, InvalidParam)
+{
+    uint8_t seed[1024] = {0};
+
+    EXPECT_EQ(OC_STACK_INVALID_PARAM, SetDeviceIdSeed(seed, 0));
+    EXPECT_EQ(OC_STACK_INVALID_PARAM, SetDeviceIdSeed(seed, sizeof(seed)));
+}
+
+TEST(SetUuidSeedTest, ValidValue)
+{
+    uint8_t seed[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
+    EXPECT_EQ(OC_STACK_OK, SetDeviceIdSeed(seed, sizeof(seed)));
+}
+#endif
diff --git a/resource/csdk/security/unittest/svcresourcetest.cpp b/resource/csdk/security/unittest/svcresourcetest.cpp
deleted file mode 100644 (file)
index 8d4553f..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-//******************************************************************
-//
-// 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.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-
-#include "gtest/gtest.h"
-#include "ocstack.h"
-#include "oic_malloc.h"
-#include "cainterface.h"
-#include "secureresourcemanager.h"
-#include "securevirtualresourcetypes.h"
-#include "srmresourcestrings.h"
-#include "svcresource.h"
-#include "srmtestcommon.h"
-#include "security_internals.h"
-
-using namespace std;
-
-#define NUM_SVC_IN_CBOR_DB (2)
-
-TEST(SVCResourceTest, CBORConversionTests)
-{
-    OicSecSvc_t *svc1 = (OicSecSvc_t *) OICCalloc(1, sizeof(*svc1));
-    ASSERT_TRUE(NULL != svc1);
-    uint8_t svcdid[] = {0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
-                        0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35};
-    memcpy(svc1->svcdid.id, svcdid, sizeof(svcdid));
-    ASSERT_EQ(sizeof(svc1->svcdid.id), sizeof(svcdid));
-
-    svc1->svct = (OicSecSvcType_t) 1;
-    uint8_t owners[] = {0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
-                        0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39};
-    svc1->ownersLen = 1;
-    svc1->owners = (OicUuid_t *)OICCalloc(svc1->ownersLen, sizeof(*svc1->owners));
-    ASSERT_TRUE(NULL != svc1->owners);
-    memcpy(svc1->owners[0].id, owners, sizeof(owners));
-    ASSERT_EQ(sizeof(svc1->owners[0].id), sizeof(owners));
-
-    svc1->next = (OicSecSvc_t *) OICCalloc(1, sizeof(*svc1->next));
-    ASSERT_TRUE(svc1->next != NULL);
-    memcpy(svc1->next->svcdid.id, svcdid, sizeof(svcdid));
-    ASSERT_EQ(sizeof(svc1->next->svcdid.id), sizeof(svcdid));
-    svc1->next->svct = (OicSecSvcType_t) 1;
-    uint8_t owners1[] = {0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-                        0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36};
-    svc1->next->ownersLen = 1;
-    svc1->next->owners = (OicUuid_t *)OICCalloc(svc1->next->ownersLen,
-                                                sizeof(*svc1->next->owners));
-    ASSERT_TRUE(NULL != svc1->next->owners);
-    memcpy(svc1->next->owners[0].id, owners1, sizeof(owners1));
-    svc1->next->next = NULL;
-
-    size_t size = 0;
-    uint8_t *psStorage = NULL;
-    EXPECT_EQ(OC_STACK_OK, SVCToCBORPayload(svc1, &psStorage, &size));
-    ASSERT_TRUE(NULL != psStorage);
-
-    OicSecSvc_t *svc = NULL;
-    EXPECT_EQ(OC_STACK_OK, CBORPayloadToSVC(psStorage, size, &svc));
-    ASSERT_TRUE(NULL != svc);
-
-    int cnt = 0;
-    OicSecSvc_t *tempSvc = svc;
-    while (tempSvc)
-    {
-        EXPECT_EQ(ACCESS_MGMT_SERVICE, tempSvc->svct);
-        cnt++;
-        tempSvc = tempSvc->next;
-    }
-    EXPECT_EQ(NUM_SVC_IN_CBOR_DB, cnt);
-
-    OICFree(psStorage);
-    DeleteSVCList(svc);
-    DeleteSVCList(svc1);
-}
index 2fcdb29..a4c2366 100644 (file)
@@ -36,6 +36,7 @@
 #include "ocresource.h"
 #include "cacommon.h"
 
+#ifdef WITH_PRESENCE
 /**
  * Data structure For presence Discovery.
  * This is the TTL associated with presence.
@@ -51,6 +52,7 @@ typedef struct OCPresence
     /** TTL Level. */
     uint32_t TTLlevel;
 } OCPresence;
+#endif // WITH_PRESENCE
 
 /**
  * Forward declaration of resource type.
index 1e6b12e..091381f 100755 (executable)
@@ -232,7 +232,7 @@ typedef struct OCResource {
     union
     {
         /** An ordinal number that is not repeated - must be unique in the collection context. */
-        uint8_t ins;
+        int64_t ins;
         /** Any unique string including a URI. */
         char *uniqueStr;
         /** Use UUID for universal uniqueness - used in /oic/res to identify the device. */
index 02d725f..93b0427 100644 (file)
@@ -277,11 +277,11 @@ CAMessageType_t qualityOfServiceToMessageType(OCQualityOfService qos);
 //TODO: should the following function be public?
 OCStackResult OCChangeResourceProperty(OCResourceProperty * inputProperty,
         OCResourceProperty resourceProperties, uint8_t enable);
-#endif
 
 const char *convertTriggerEnumToString(OCPresenceTrigger trigger);
 
 OCPresenceTrigger convertTriggerStringToEnum(const char * triggerStr);
+#endif // WITH_PRESENCE
 
 void CopyEndpointToDevAddr(const CAEndpoint_t *in, OCDevAddr *out);
 
@@ -335,6 +335,38 @@ uint32_t GetTicks(uint32_t milliSeconds);
  */
 void OCDeleteResourceAttributes(OCAttribute *rsrcAttributes);
 
+/**
+ *  A request uri consists of the following components in order:
+ *                              example
+ *  optionally one of
+ *      CoAP over UDP prefix    "coap://"
+ *      CoAP over TCP prefix    "coap+tcp://"
+ *      CoAP over DTLS prefix   "coaps://"
+ *      CoAP over TLS prefix    "coaps+tcp://"
+ *  optionally one of
+ *      IPv6 address            "[1234::5678]"
+ *      IPv4 address            "192.168.1.1"
+ *  optional port               ":5683"
+ *  resource uri                "/oc/core..."
+ *
+ *  for PRESENCE requests, extract resource type.
+ *
+ *  @return ::OC_STACK_OK on success, some other value upon failure.
+ */
+OCStackResult ParseRequestUri(const char *fullUri,
+                              OCTransportAdapter adapter,
+                              OCTransportFlags flags,
+                              OCDevAddr **devAddr,
+                              char **resourceUri,
+                              char **resourceType);
+
+/**
+ * Fix up client response data.
+ *
+ * @param cr Response from queries to remote servers.
+ */
+void FixUpClientResponse(OCClientResponse *cr);
+
 #ifdef __cplusplus
 }
 #endif // __cplusplus
@@ -1,6 +1,6 @@
 /* ****************************************************************
  *
- * Copyright 2015 Samsung Electronics All Rights Reserved.
+ * Copyright 2016 Samsung Electronics All Rights Reserved.
  *
  *
  *
 
 /**
  * @file
- * This file contains the APIs for KeepAlive Mechanism.
+ * This file contains the Internal APIs for KeepAlive Mechanism.
  * In order to ensure that the connection between an OIC Devices,
  * when using CoAP over TCP, OIC Device should send application layer
  * KeepAlive messages.
  */
-#ifndef KEEP_ALIVE_H_
-#define KEEP_ALIVE_H_
+#ifndef KEEP_ALIVE__INTERNAL_H_
+#define KEEP_ALIVE__INTERNAL_H_
 
 #include "octypes.h"
 #include "ocserverrequest.h"
@@ -57,19 +57,27 @@ extern "C"
  * @param[in]   mode        Host mode of operation.
  * @return  ::OC_STACK_OK or Appropriate error code.
  */
-OCStackResult InitializeKeepAlive(OCMode mode);
+OCStackResult OCInitializeKeepAlive(OCMode mode);
 
 /**
  * Terminates the KeepAlive.
  * @param[in]   mode        Host mode of operation.
  * @return  ::OC_STACK_OK or Appropriate error code.
  */
-OCStackResult TerminateKeepAlive(OCMode mode);
+OCStackResult OCTerminateKeepAlive(OCMode mode);
+
+/**
+ * API to handle the Response payload.
+ * @param[in]   endpoint        RemoteEndpoint which sent the packet.
+ * @param[in]   payload         Encoded response payload.
+ * @return  ::OC_STACK_OK or Appropriate error code.
+ */
+OCStackResult OCHandleKeepAliveResponse(const CAEndpoint_t *endPoint, const OCPayload *payload);
 
 /**
  * Process the KeepAlive timer to send ping message to OIC Server.
  */
-void ProcessKeepAlive();
+void OCProcessKeepAlive();
 
 /**
  * This API will be called from RI layer whenever there is a request for KeepAlive.
@@ -78,17 +86,19 @@ void ProcessKeepAlive();
  * @param[in]   resource    Resource handle used for sending the response.
  * @return  ::OC_STACK_OK or Appropriate error code.
  */
-OCStackResult HandleKeepAliveRequest(OCServerRequest *request,
-                                     const OCResource *resource);
+OCStackResult OCHandleKeepAliveRequest(OCServerRequest *request,
+                                       const OCResource *resource);
 
 /**
  * API to handle the connected device for KeepAlive.
- * @return  Current Time.
+ * @param[in]   endpoint        Remote endpoint information.
+ * @param[in]   isConnected     Whether keepalive message needs to be sent.
+ * @param[in]   isClient        Host Mode of Operation.
  */
-void HandleKeepAliveConnCB(const CAEndpoint_t *endpoint, bool isConnected);
+void OCHandleKeepAliveConnCB(const CAEndpoint_t *endpoint, bool isConnected, bool isClient);
 
 #ifdef __cplusplus
 } // extern "C"
 #endif
 
-#endif // KEEP_ALIVE_H_
+#endif // KEEP_ALIVE__INTERNAL_H_
index 204af4f..7d39aa8 100644 (file)
@@ -45,12 +45,12 @@ extern "C"
  * Macro to verify the validity of cbor operation.
  */
 #define VERIFY_CBOR_SUCCESS(log_tag, err, log_message) \
-    if ((CborNoError != (err)) && (CborErrorOutOfMemory != (err))) \
+    if ((CborNoError != (CborError)(err)) && (CborErrorOutOfMemory != (CborError)(err))) \
     { \
         if ((log_tag) && (log_message)) \
         { \
             OIC_LOG_V(ERROR, (log_tag), "%s with cbor error: \'%s\'.", \
-                    (log_message), (cbor_error_string(err))); \
+                    (log_message), (cbor_error_string((CborError)err))); \
         } \
         goto exit; \
     } \
@@ -251,10 +251,12 @@ OCResourcePayload* OCDiscoveryPayloadGetResource(OCDiscoveryPayload* payload, si
 void OCDiscoveryResourceDestroy(OCResourcePayload* payload);
 void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload);
 
+#ifdef WITH_PRESENCE
 // Presence Payload
 OCPresencePayload* OCPresencePayloadCreate(uint32_t seqNum, uint32_t maxAge,
         OCPresenceTrigger trigger, const char* resourceType);
 void OCPresencePayloadDestroy(OCPresencePayload* payload);
+#endif
 
 // Helper API
 OCStringLL* CloneOCStringLL (OCStringLL* ll);
index 6769fc1..2a9f595 100644 (file)
@@ -57,6 +57,19 @@ OCStackResult OCInit1(OCMode mode, OCTransportFlags serverFlags, OCTransportFlag
 /**
  * This function Initializes the OC Stack.  Must be called prior to starting the stack.
  *
+ * @param mode            OCMode Host device is client, server, or client-server.
+ * @param serverFlags     OCTransportFlags Default server transport flags.
+ * @param clientFlags     OCTransportFlags Default client transport flags.
+ * @param transportType   OCTransportAdapter value to initialize.
+ *
+ * @return ::OC_STACK_OK on success, some other value upon failure.
+ */
+OCStackResult OCInit2(OCMode mode, OCTransportFlags serverFlags, OCTransportFlags clientFlags,
+                      OCTransportAdapter transportType);
+
+/**
+ * This function Initializes the OC Stack.  Must be called prior to starting the stack.
+ *
  * @param ipAddr      IP Address of host device. Deprecated parameter.
  * @param port        Port of host device. Deprecated parameter.
  * @param mode        OCMode Host device is client, server, or client-server.
@@ -118,6 +131,8 @@ OCStackResult OCProcess();
  * This function discovers or Perform requests on a specified resource
  * (specified by that Resource's respective URI).
  *
+ * @deprecated: Use OCDoRequest instead which does not free given payload.
+ *
  * @param handle            To refer to the request sent out on behalf of
  *                          calling this API. This handle can be used to cancel this operation
  *                          via the OCCancel API.
@@ -125,10 +140,11 @@ OCStackResult OCProcess();
  *                          the consumer.  A NULL handle is permitted in the event where the caller
  *                          has no use for the return value.
  * @param method            To perform on the resource.
- * @param requestUri       URI of the resource to interact with. (Address prefix is deprecated in
+ * @param requestUri        URI of the resource to interact with. (Address prefix is deprecated in
  *                          favor of destination.)
  * @param destination       Complete description of destination.
- * @param payload           Encoded request payload.
+ * @param payload           Encoded request payload,
+                            OCDoResource will free given payload when return OC_STATUS_OK.
  * @param connectivityType  Modifier flags when destination is not given.
  * @param qos               Quality of service. Note that if this API is called on a uri with the
  *                          well-known multicast IP address, the qos will be forced to ::OC_LOW_QOS
@@ -157,6 +173,52 @@ OCStackResult OCDoResource(OCDoHandle *handle,
                            OCCallbackData *cbData,
                            OCHeaderOption *options,
                            uint8_t numOptions);
+
+/**
+ * This function discovers or Perform requests on a specified resource
+ * (specified by that Resource's respective URI).
+ *
+ * @param handle            To refer to the request sent out on behalf of
+ *                          calling this API. This handle can be used to cancel this operation
+ *                          via the OCCancel API.
+ *                          @note: This reference is handled internally, and should not be free'd by
+ *                          the consumer.  A NULL handle is permitted in the event where the caller
+ *                          has no use for the return value.
+ * @param method            To perform on the resource.
+ * @param requestUri        URI of the resource to interact with. (Address prefix is deprecated in
+ *                          favor of destination.)
+ * @param destination       Complete description of destination.
+ * @param payload           Encoded request payload.
+                            OCDoRequest does not free given payload.
+ * @param connectivityType  Modifier flags when destination is not given.
+ * @param qos               Quality of service. Note that if this API is called on a uri with the
+ *                          well-known multicast IP address, the qos will be forced to ::OC_LOW_QOS
+ *                          since it is impractical to send other QOS levels on such addresses.
+ * @param cbData            Asynchronous callback function that is invoked by the stack when
+ *                          discovery or resource interaction is received. The discovery could be
+ *                          related to filtered/scoped/particular resource. The callback is
+ *                          generated for each response received.
+ * @param options           The address of an array containing the vendor specific header options
+ *                          to be sent with the request.
+ * @param numOptions        Number of header options to be included.
+ *
+ * @note: Presence subscription amendments (i.e. adding additional resource type filters by calling
+ * this API again) require the use of the same base URI as the original request to successfully
+ * amend the presence filters.
+ *
+ * @return ::OC_STACK_OK on success, some other value upon failure.
+ */
+OCStackResult OCDoRequest(OCDoHandle *handle,
+                          OCMethod method,
+                          const char *requestUri,
+                          const OCDevAddr *destination,
+                          OCPayload* payload,
+                          OCConnectivityType connectivityType,
+                          OCQualityOfService qos,
+                          OCCallbackData *cbData,
+                          OCHeaderOption *options,
+                          uint8_t numOptions);
+
 /**
  * This function cancels a request associated with a specific @ref OCDoResource invocation.
  *
@@ -215,7 +277,7 @@ OCStackResult OCStartPresence(const uint32_t ttl);
  */
 
 OCStackResult OCStopPresence();
-#endif
+#endif // WITH_PRESENCE
 
 
 /**
@@ -576,7 +638,7 @@ OCStackResult OCSetProxyURI(const char *uri);
  *
  * @return ::OC_STACK_OK on success, some other value upon failure.
  */
-OCStackResult OCBindResourceInsToResource(OCResourceHandle handle, uint8_t ins);
+OCStackResult OCBindResourceInsToResource(OCResourceHandle handle, int64_t ins);
 
 /**
  * This function gets the resource unique id for a resource.
@@ -586,7 +648,7 @@ OCStackResult OCBindResourceInsToResource(OCResourceHandle handle, uint8_t ins);
  *
  * @return Ins if resource found or 0 resource not found.
  */
-OCStackResult OCGetResourceIns(OCResourceHandle handle, uint8_t *ins);
+OCStackResult OCGetResourceIns(OCResourceHandle handle, int64_t *ins);
 
 #endif
 
@@ -670,6 +732,14 @@ OCStackResult OCGetDeviceId(OCUUIdentity *deviceId);
  */
 OCStackResult OCSetDeviceId(const OCUUIdentity *deviceId);
 
+ /**
+ * Gets the bool state of "isOwned" property on the doxm resource.
+ *
+ * @param isOwned a pointer to be assigned to isOwned property
+ * @return Returns ::OC_STACK_OK if success.
+ */
+OCStackResult OCGetDeviceOwnedState(bool *isOwned);
+
 /**
  * Encode an address string to match RFC 6874.
  *
@@ -730,6 +800,84 @@ OCStackResult OCSetPropertyValue(OCPayloadType type, const char *propName, const
  */
 OCStackResult OCGetPropertyValue(OCPayloadType type, const char *propName, void **value);
 
+/**
+* Delete client callback info all.
+*/
+void OCClearCallBackList();
+
+/**
+ * Delete observer info all.
+ */
+void OCClearObserverlist();
+
+/**
+ * API to encrypt the un-encrypted DB file before OCRegisterPersistentStorageHandler
+ * If the API is successful, un-encrypted file will be removed, and if the encrypted file
+ * is currupted, then it restores encrypted file using rescue file.
+ *
+ * @param[in] key key used for encryption
+ * @param[in] psPlain OCPersistentStorage for the plain DB
+ * @param[in] psEnc OCPersistentStorage for the encrypted DB
+ * @param[in] psRescue OCPersistentStorage for the rescue DB
+ *
+ * @return ::OC_STACK_OK on success and other value otherwise.
+ */
+OCStackResult OCSetSecurePSI(const unsigned char *key, const OCPersistentStorage *psPlain,
+        const OCPersistentStorage *psEnc, const OCPersistentStorage *psRescue);
+
+/**
+ * Generic Encryption function to encrypt data buffer in pt
+ * and update in ct and len in ct_len. (AES-CBC-HMAC)
+ *
+ * @param[in] pt plaintext to be encrypted
+ * @param[in] pt_len length of plaintext
+ * @param[out] ct ciphered text
+ * @param[out] ct_len is length of the ciphered text.
+ *
+ * @return ::0 for Success.
+ */
+int OCEncrypt(const unsigned char *pt, size_t pt_len,
+        unsigned char **ct, size_t *ct_len);
+
+/**
+ * Generic Decryption fucntion to decrypt data buffer in ct
+ * and update in pt and len in pt_len. (AES-CBC-HMAC)
+ *
+ * @param[in] ct ciphered to be decrypted
+ * @param[in] ct_len length of cipher text
+ * @param[out] pt plaintext text
+ * @param[out] pt_len is length of the palintext text.
+ *
+ * @return ::0 for Success.
+ */
+int OCDecrypt(const unsigned char *ct, size_t ct_len,
+        unsigned char **pt, size_t *pt_len);
+
+/**
+ * API to set key to psi
+ *
+ * @param[in] key key used for encryption
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
+ */
+OCStackResult OCSetKey(const unsigned char* key);
+
+/**
+ * API to get key from psi
+ *
+ * @param[out] key key used for encryption
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
+ */
+OCStackResult OCGetKey(unsigned char* key);
+
+/**
+ * API to register OTM event handler
+ *
+ * @param[in] ctx user context returned in the callback
+ * @param[in] cb callback function to receive the OTM event on server side
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
+ */
+OCStackResult OCSetOtmEventHandler(void *ctx, OCOtmEventHandler cb);
+
 #ifdef __cplusplus
 }
 #endif // __cplusplus
index d71c096..ee4ffe3 100644 (file)
@@ -33,7 +33,7 @@
  * Maximum length of the URI supported by client/server while processing
  * REST requests/responses.
  */
-#ifdef ARDUINO
+#if defined(ARDUINO) || defined(__TIZENRT__)
 #define MAX_URI_LENGTH (64)
 #else
 #define MAX_URI_LENGTH (256)
@@ -43,7 +43,7 @@
  * Maximum length of the query supported by client/server while processing
  * REST requests/responses.
  */
-#ifdef ARDUINO
+#if defined(ARDUINO) || defined(__TIZENRT__)
 #define MAX_QUERY_LENGTH (64)
 #else
 #define MAX_QUERY_LENGTH (256)
@@ -86,7 +86,7 @@
  *  Maximum number of vendor specific header options an application can set or receive
  *  in PDU
  */
-#ifdef ARDUINO
+#if defined(ARDUINO) || defined(__TIZENRT__)
 #define MAX_HEADER_OPTIONS (2)
 #else
 #define MAX_HEADER_OPTIONS (50)
@@ -95,7 +95,7 @@
 /**
  *  Maximum Length of the vendor specific header option
  */
-#ifdef ARDUINO
+#if defined(ARDUINO) || defined(__TIZENRT__)
 #define MAX_HEADER_OPTION_DATA_LENGTH (20)
 #else
 #define MAX_HEADER_OPTION_DATA_LENGTH (1024)
old mode 100755 (executable)
new mode 100644 (file)
index 2117fc3..f1ed8b1
@@ -43,10 +43,18 @@ extern "C" {
 #define WITH_PRESENCE
 
 #include "ocpresence.h"
+
+// TODO : need for secure psi
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+#define __SECURE_PSI__
+#endif
+
 //-----------------------------------------------------------------------------
 // Defines
 //-----------------------------------------------------------------------------
 
+#define IOTIVITY_VERSION "1.2.1"
+
 /**
  * OIC Virtual resources supported by every OIC device.
  */
@@ -74,7 +82,7 @@ extern "C" {
 /** KeepAlive URI.*/
 #define OC_RSRVD_KEEPALIVE_URI                "/oic/ping"
 
-
+#ifdef WITH_PRESENCE
 /** Presence */
 
 /** Presence URI through which the OIC devices advertise their presence.*/
@@ -83,8 +91,7 @@ extern "C" {
 /** Presence URI through which the OIC devices advertise their device presence.*/
 #define OC_RSRVD_DEVICE_PRESENCE_URI         "/oic/prs"
 
-/** Sets the default time to live (TTL) for presence.*/
-#define OC_DEFAULT_PRESENCE_TTL_SECONDS       (60)
+#endif // WITH_PRESENCE
 
 /** For multicast Discovery mechanism.*/
 #define OC_MULTICAST_DISCOVERY_URI            "/oic/res"
@@ -92,6 +99,7 @@ extern "C" {
 /** Separator for multiple query string.*/
 #define OC_QUERY_SEPARATOR                    "&;"
 
+#ifdef WITH_PRESENCE
 /**
  *  OC_DEFAULT_PRESENCE_TTL_SECONDS sets the default time to live (TTL) for presence.
  */
@@ -119,6 +127,8 @@ extern "C" {
 /** To delete.*/
 #define OC_RSRVD_TRIGGER_DELETE         "delete"
 
+#endif // WITH_PRESENCE
+
 /**
  *  Attributes used to form a proper OIC conforming JSON message.
  */
@@ -145,8 +155,10 @@ extern "C" {
 /** To represent resource type.*/
 #define OC_RSRVD_RESOURCE_TYPE          "rt"
 
+#ifdef WITH_PRESENCE
 /** To represent resource type with presence.*/
 #define OC_RSRVD_RESOURCE_TYPE_PRESENCE "oic.wk.ad"
+#endif
 
 /** To represent resource type with device.*/
 #define OC_RSRVD_RESOURCE_TYPE_DEVICE   "oic.wk.d"
@@ -222,10 +234,10 @@ extern "C" {
 #define OC_RSRVD_HOSTING_PORT           "port"
 
 /** TCP Port. */
-#define OC_RSRVD_TCP_PORT               "tcp"
+#define OC_RSRVD_TCP_PORT               "x.org.iotivity.tcp"
 
 /** TLS Port. */
-#define OC_RSRVD_TLS_PORT               "tls"
+#define OC_RSRVD_TLS_PORT               "x.org.iotivity.tls"
 
 /** For Server instance ID.*/
 #define OC_RSRVD_SERVER_INSTANCE_ID     "sid"
@@ -599,6 +611,29 @@ typedef enum
     OC_ADAPTER_NFC           = (1 << 5)
 } OCTransportAdapter;
 
+typedef enum
+{
+    OC_DEFAULT_BT_FLAGS = 0,
+    // flags for BLE transport
+    OC_LE_ADV_DISABLE   = 0x1,   // disable BLE advertisement.
+    OC_LE_ADV_ENABLE    = 0x2,   // enable BLE advertisement.
+    OC_LE_SERVER_DISABLE = (1 << 4),   // disable gatt server.
+    // flags for EDR transport
+    OC_EDR_SERVER_DISABLE = (1 << 7)   // disable rfcomm server.
+} OCTransportBTFlags_t;
+
+/**
+ * Log level to print can be controlled through this enum.
+ * And privacy logs contained uid, Token, Device id, etc can also disable.
+ * This enum (OCLogLevel) must be kept synchronized with
+ * CAUtilLogLevel_t (in CACommon.h).
+ */
+typedef enum
+{
+    OC_LOG_LEVEL_ALL = 1,             // all logs.
+    OC_LOG_LEVEL_INFO,                // debug level is disabled.
+} OCLogLevel;
+
 /**
  *  Enum layout assumes some targets have 16-bit integer (e.g., Arduino).
  */
@@ -701,9 +736,12 @@ typedef struct
 
     /** usually zero for default interface.*/
     uint32_t                ifindex;
-#if defined (ROUTING_GATEWAY) || defined (ROUTING_EP)
-    char                    routeData[MAX_ADDR_STR_SIZE]; //destination GatewayID:ClientId
-#endif
+
+    /** destination GatewayID:ClientId.*/
+    char                    routeData[MAX_ADDR_STR_SIZE];
+
+    /** device ID of remote.*/
+    char                    remoteId[MAX_IDENTITY_SIZE];
 } OCDevAddr;
 
 /**
@@ -985,6 +1023,7 @@ typedef enum
     OC_STACK_PDM_IS_NOT_INITIALIZED,
     OC_STACK_DUPLICATE_UUID,
     OC_STACK_INCONSISTENT_DB,
+    OC_STACK_SVR_DB_NOT_EXIST,
 
     /**
      * Error code from OTM
@@ -1000,9 +1039,19 @@ typedef enum
     OC_STACK_PRESENCE_DO_NOT_HANDLE,
 #endif
 
+    /** Request is denied by the user*/
+    OC_STACK_USER_DENIED_REQ,
+    OC_STACK_NOT_ACCEPTABLE,
+    OC_STACK_METHOD_NOT_ALLOWED,
+
     /** ERROR code from server */
     OC_STACK_FORBIDDEN_REQ,          /** 403*/
     OC_STACK_INTERNAL_SERVER_ERROR,  /** 500*/
+    OC_STACK_NOT_IMPLEMENTED,        /** 501*/
+    OC_STACK_BAD_GATEWAY,            /** 502*/
+    OC_STACK_SERVICE_UNAVAILABLE,    /** 503*/
+    OC_STACK_GATEWAY_TIMEOUT,        /** 504*/
+    OC_STACK_PROXY_NOT_SUPPORTED,    /** 505*/
 
     /** ERROR in stack.*/
     OC_STACK_ERROR = 255
@@ -1077,6 +1126,14 @@ typedef struct {
 
     /** Persistent storage unlink handler.*/
     int (* unlink)(const char *path);
+
+    /** Persistent Storage Handler for Encryption.*/
+    int (* encrypt)(const unsigned char *pt, size_t size,
+            unsigned char**ct, size_t *ct_len);
+
+    /**Persistent Storage Handler for Decryption.*/
+    int (* decrypt)(const unsigned char *ct, size_t size,
+            unsigned char**pt, size_t *pt_len);
 } OCPersistentStorage;
 
 /**
@@ -1114,9 +1171,11 @@ typedef enum
     OC_EH_TOO_LARGE = 413,
     OC_EH_UNSUPPORTED_MEDIA_TYPE = 415,
     OC_EH_INTERNAL_SERVER_ERROR = 500,
+    OC_EH_NOT_IMPLEMENTED = 501,
     OC_EH_BAD_GATEWAY = 502,
     OC_EH_SERVICE_UNAVAILABLE = 503,
-    OC_EH_RETRANSMIT_TIMEOUT = 504
+    OC_EH_RETRANSMIT_TIMEOUT = 504,
+    OC_EH_PROXY_NOT_SUPPORTED = 505
 } OCEntityHandlerResult;
 
 /**
@@ -1256,8 +1315,10 @@ typedef enum
     PAYLOAD_TYPE_REPRESENTATION,
     /** The payload is an OCSecurityPayload */
     PAYLOAD_TYPE_SECURITY,
+#ifdef WITH_PRESENCE
     /** The payload is an OCPresencePayload */
     PAYLOAD_TYPE_PRESENCE
+#endif
 } OCPayloadType;
 
 /**
@@ -1374,9 +1435,6 @@ typedef struct OCDiscoveryPayload
     /** Name */
     char *name;
 
-    /** HREF */
-    char *uri;
-
     /** Resource Type */
     OCStringLL *type;
 
@@ -1686,7 +1744,6 @@ typedef OCEntityHandlerResult (*OCDeviceEntityHandler)
  */
 typedef void (*OCDirectPairingCB)(void *ctx, OCDPDev_t *peer, OCStackResult result);
 //#endif // DIRECT_PAIRING
-
 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
 /**
  * Callback function definition for Change in TrustCertChain
@@ -1709,6 +1766,29 @@ typedef struct trustCertChainContext
 } trustCertChainContext_t;
 #endif
 
+/**
+ * OTM State
+ */
+typedef enum
+{
+    OC_OTM_READY = 0,
+    OC_OTM_STARTED = 1,
+    OC_OTM_DONE = 2,
+    OC_OTM_ERROR = 3
+} OCOtmEvent_t;
+
+/**
+ * Callback function to receive the OTM event on server side.
+ *
+ * @param[in] ctx user context returned in the callback
+ * @param[in] addr PT's address (address can be NULL in case of init state)
+ * @param[in] port PT's port (It is meaningless in case of init state & BLE)
+ * @param[in] uuid PT's UUID (UUID can be NULL in case of init state & coap reqest)
+ * @param[in] event OTM state (@ref OCOtmEvent_t)
+ */
+typedef void (*OCOtmEventHandler)(void *ctx, const char *addr, uint16_t port,
+        const char *ownerId, OCOtmEvent_t event);
+
 #ifdef __cplusplus
 }
 #endif // __cplusplus
diff --git a/resource/csdk/stack/include/oickeepalive.h b/resource/csdk/stack/include/oickeepalive.h
new file mode 100644 (file)
index 0000000..d813665
--- /dev/null
@@ -0,0 +1,84 @@
+/* ****************************************************************
+ *
+ * Copyright 2016 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 KeepAlive Mechanism.
+ * In order to ensure that the connection between an OIC Devices,
+ * when using CoAP over TCP, OIC Device should send application layer
+ * KeepAlive messages.
+ */
+#ifndef KEEP_ALIVE_H_
+#define KEEP_ALIVE_H_
+
+#include "octypes.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * This function discovers on a /oic/ping resource.
+ *
+ * @param handle            To refer to the request sent out on behalf of
+ *                          calling this API. This handle can be used to cancel this operation
+ *                          via the OCCancel API.
+ *                          @note: This reference is handled internally, and should not be free'd by
+ *                          the consumer.  A NULL handle is permitted in the event where the caller
+ *                          has no use for the return value.
+ * @param remoteAddr        The target device address to discovery a resource.
+ * @param cbData            Asynchronous callback function that is invoked by the stack when
+ *                          discovery or resource interaction is received. The discovery could be
+ *                          related to filtered/scoped/particular resource. The callback is
+ *                          generated for each response received.
+ *
+ * @return ::OC_STACK_OK on success, some other value upon failure.
+ */
+OCStackResult OCFindKeepAliveResource(OCDoHandle *handle, const char *remoteAddr,
+                                      OCCallbackData *cbData);
+
+/**
+ * Send ping message to remote endpoint.
+ *
+ * @param handle            To refer to the request sent out on behalf of
+ *                          calling this API. This handle can be used to cancel this operation
+ *                          via the OCCancel API.
+ *                          @note: This reference is handled internally, and should not be free'd by
+ *                          the consumer.  A NULL handle is permitted in the event where the caller
+ *                          has no use for the return value.
+ * @param remoteAddr        The target device address to discovery a resource.
+ * @param payload           Encoded request payload.
+ * @param cbData            Asynchronous callback function that is invoked by the stack when
+ *                          discovery or resource interaction is received. The discovery could be
+ *                          related to filtered/scoped/particular resource. The callback is
+ *                          generated for each response received.
+ *
+ * @return ::OC_STACK_OK on success, some other value upon failure.
+ */
+OCStackResult OCSendKeepAliveRequest(OCDoHandle *handle, const char *remoteAddr,
+                                     OCPayload *payload, OCCallbackData *cbData);
+
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // KEEP_ALIVE_H_
index 1b81907..9b86e38 100644 (file)
@@ -50,8 +50,10 @@ extern "C"
     #define OIC_LOG_PAYLOAD(level, payload) OCPayloadLog((level),(payload))
     #define UUID_SIZE (16)
 
+#ifdef WITH_PRESENCE
 const char *convertTriggerEnumToString(OCPresenceTrigger trigger);
 OCPresenceTrigger convertTriggerStringToEnum(const char * triggerStr);
+#endif
 
 INLINE_API void OCPayloadLogRep(LogLevel level, OCRepPayload* payload);
 
@@ -203,13 +205,21 @@ INLINE_API void OCPayloadLogRep(LogLevel level, OCRepPayload* payload)
     }
 }
 
+static void OCStringLLPrint(LogLevel level, OCStringLL *type)
+{
+    for (OCStringLL *strll = type; strll; strll = strll->next)
+    {
+        OIC_LOG_V(level, PL_TAG, "\t\t %s", strll->value);
+    }
+}
+
 INLINE_API void OCPayloadLogDiscovery(LogLevel level, OCDiscoveryPayload* payload)
 {
     OIC_LOG(level, PL_TAG, "Payload Type: Discovery");
 
     while(payload && payload->resources)
     {
-        OIC_LOG_V(level, PL_TAG, "\tSID: %s", payload->sid);
+        OIC_LOG_V(level, PL_TAG, "\tDI: %s", payload->sid);
         if (payload->baseURI)
         {
             OIC_LOG_V(level, PL_TAG, "\tBase URI:%s", payload->baseURI);
@@ -218,21 +228,17 @@ INLINE_API void OCPayloadLogDiscovery(LogLevel level, OCDiscoveryPayload* payloa
         {
             OIC_LOG_V(level, PL_TAG, "\tNAME: %s", payload->name);
         }
-        if (payload->uri)
-        {
-            OIC_LOG_V(level, PL_TAG, "\tURI: %s", payload->uri);
-        }
+
         if (payload->type)
         {
-            for (OCStringLL *strll = payload->type; strll; strll = strll->next)
-            {
-                OIC_LOG_V(level, PL_TAG, "\tResource Type: %s", strll->value);
-            }
+            OIC_LOG(level, PL_TAG, "\tResource Type:");
+            OCStringLLPrint(level, payload->type);
         }
-        OIC_LOG(level, PL_TAG, "\tInterface:");
-        for (OCStringLL *itf = payload->iface; itf; itf = itf->next)
+
+        if (payload->iface)
         {
-            OIC_LOG_V(level, PL_TAG, "\t\t%s", itf->value);
+            OIC_LOG(level, PL_TAG, "\tInterface:");
+            OCStringLLPrint(level, payload->iface);
         }
 
         OCResourcePayload* res = payload->resources;
@@ -240,7 +246,7 @@ INLINE_API void OCPayloadLogDiscovery(LogLevel level, OCDiscoveryPayload* payloa
         int i = 1;
         while(res)
         {
-            OIC_LOG_V(level, PL_TAG, "\tResource #%d", i);
+            OIC_LOG_V(level, PL_TAG, "\tLink#%d", i);
             OIC_LOG_V(level, PL_TAG, "\tURI:%s", res->uri);
             OIC_LOG(level, PL_TAG, "\tResource Types:");
             OCStringLL* strll =  res->types;
@@ -268,6 +274,7 @@ INLINE_API void OCPayloadLogDiscovery(LogLevel level, OCDiscoveryPayload* payloa
     }
 }
 
+#ifdef WITH_PRESENCE
 INLINE_API void OCPayloadLogPresence(LogLevel level, OCPresencePayload* payload)
 {
     OIC_LOG(level, PL_TAG, "Payload Type: Presence");
@@ -276,6 +283,7 @@ INLINE_API void OCPayloadLogPresence(LogLevel level, OCPresencePayload* payload)
     OIC_LOG_V(level, PL_TAG, "\tTrigger:%s", convertTriggerEnumToString(payload->trigger));
     OIC_LOG_V(level, PL_TAG, "\tResource Type:%s", payload->resourceType);
 }
+#endif // WITH_PRESENCE
 
 INLINE_API void OCPayloadLogSecurity(LogLevel level, OCSecurityPayload* payload)
 {
@@ -313,9 +321,11 @@ INLINE_API void OCPayloadLog(LogLevel level, OCPayload* payload)
         case PAYLOAD_TYPE_DISCOVERY:
             OCPayloadLogDiscovery(level, (OCDiscoveryPayload*)payload);
             break;
+#ifdef WITH_PRESENCE
         case PAYLOAD_TYPE_PRESENCE:
             OCPayloadLogPresence(level, (OCPresencePayload*)payload);
             break;
+#endif
         case PAYLOAD_TYPE_SECURITY:
             OCPayloadLogSecurity(level, (OCSecurityPayload*)payload);
             break;
index 020be7c..6f4dd48 100644 (file)
@@ -58,9 +58,6 @@ if target_os not in ['arduino', 'windows', 'darwin', 'ios', 'msys_nt']:
 if target_os not in ['windows']:
        samples_env.PrependUnique(LIBS = ['m'])
 
-if samples_env.get('SECURED') == '1':
-    samples_env.AppendUnique(LIBS = ['tinydtls'])
-
 samples_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
 
 ######################################################################
index 91e445a..f16adf4 100644 (file)
@@ -158,9 +158,12 @@ OCStackResult InvokeOCDoResource(std::ostringstream &query,
     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
     cbData.cd = NULL;
 
-    ret = OCDoResource(&handle, method, query.str().c_str(), remoteAddr,
-                       (method == OC_REST_PUT) ? putPayload() : NULL,
-                       (ConnType), qos, &cbData, options, numOptions);
+    OCPayload* payload = (method == OC_REST_PUT) ? putPayload() : NULL;
+
+    ret = OCDoRequest(&handle, method, query.str().c_str(), remoteAddr,
+                      payload, (ConnType), qos, &cbData, options, numOptions);
+
+    OCPayloadDestroy(payload);
 
     if (ret != OC_STACK_OK)
     {
@@ -754,9 +757,9 @@ int InitPlatformDiscovery(OCQualityOfService qos)
     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
     cbData.cd = NULL;
 
-    ret = OCDoResource(NULL, OC_REST_DISCOVER, szQueryUri, NULL, 0, CT_DEFAULT,
-                       (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS,
-                       &cbData, NULL, 0);
+    ret = OCDoRequest(NULL, OC_REST_DISCOVER, szQueryUri, NULL, 0, CT_DEFAULT,
+                      (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS,
+                      &cbData, NULL, 0);
     if (ret != OC_STACK_OK)
     {
         OIC_LOG(ERROR, TAG, "OCStack device error");
@@ -779,9 +782,9 @@ int InitDeviceDiscovery(OCQualityOfService qos)
     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
     cbData.cd = NULL;
 
-    ret = OCDoResource(NULL, OC_REST_DISCOVER, szQueryUri, NULL, 0, CT_DEFAULT,
-                       (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS,
-                       &cbData, NULL, 0);
+    ret = OCDoRequest(NULL, OC_REST_DISCOVER, szQueryUri, NULL, 0, CT_DEFAULT,
+                      (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS,
+                      &cbData, NULL, 0);
     if (ret != OC_STACK_OK)
     {
         OIC_LOG(ERROR, TAG, "OCStack device error");
@@ -802,9 +805,9 @@ int InitDiscovery(OCQualityOfService qos)
     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
     cbData.cd = NULL;
 
-    ret = OCDoResource(NULL, OC_REST_DISCOVER, szQueryUri, NULL, 0, CT_DEFAULT,
-                       (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS,
-                       &cbData, NULL, 0);
+    ret = OCDoRequest(NULL, OC_REST_DISCOVER, szQueryUri, NULL, 0, CT_DEFAULT,
+                      (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS,
+                      &cbData, NULL, 0);
     if (ret != OC_STACK_OK)
     {
         OIC_LOG(ERROR, TAG, "OCStack resource error");
index a37f64a..13bc01c 100644 (file)
@@ -119,9 +119,12 @@ OCStackResult InvokeOCDoResource(std::ostringstream &query,
     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
     cbData.cd = NULL;
 
-    ret = OCDoResource(NULL, method, query.str().c_str(), dest,
-        (method == OC_REST_PUT || method == OC_REST_POST) ? putPayload() : NULL,
-         CT_DEFAULT, qos, &cbData, options, numOptions);
+    OCPayload* payload = (method == OC_REST_PUT || method == OC_REST_POST) ? putPayload() : NULL;
+
+    ret = OCDoRequest(NULL, method, query.str().c_str(), dest,
+                      payload, CT_DEFAULT, qos, &cbData, options, numOptions);
+
+    OCPayloadDestroy(payload);
 
     if (ret != OC_STACK_OK)
     {
@@ -367,8 +370,8 @@ int InitDiscovery()
     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
     cbData.cd = NULL;
 
-    ret = OCDoResource(NULL, OC_REST_DISCOVER, queryUri, 0, 0, CT_DEFAULT,
-                       OC_LOW_QOS, &cbData, NULL, 0);
+    ret = OCDoRequest(NULL, OC_REST_DISCOVER, queryUri, 0, 0, CT_DEFAULT,
+                      OC_LOW_QOS, &cbData, NULL, 0);
     if (ret != OC_STACK_OK)
     {
         OIC_LOG(ERROR, TAG, "OCStack resource error");
index 16ca072..5063181 100644 (file)
@@ -270,9 +270,9 @@ int InitGetRequestToUnavailableResource(OCClientResponse * clientResponse)
     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
     cbData.cd = NULL;
 
-    ret = OCDoResource(NULL, OC_REST_GET, getQuery.str().c_str(),
-                       &clientResponse->devAddr, 0, ConnType, OC_LOW_QOS,
-                       &cbData, NULL, 0);
+    ret = OCDoRequest(NULL, OC_REST_GET, getQuery.str().c_str(),
+                      &clientResponse->devAddr, 0, ConnType, OC_LOW_QOS,
+                      &cbData, NULL, 0);
     if (ret != OC_STACK_OK)
     {
         OIC_LOG(ERROR, TAG, "OCStack resource error");
@@ -296,9 +296,9 @@ int InitObserveRequest(OCClientResponse * clientResponse)
     OIC_LOG_PAYLOAD(INFO, payload);
     OCPayloadDestroy(payload);
 
-    ret = OCDoResource(&handle, OC_REST_OBSERVE, obsReg.str().c_str(),
-                       &clientResponse->devAddr, 0, ConnType,
-                       OC_LOW_QOS, &cbData, NULL, 0);
+    ret = OCDoRequest(&handle, OC_REST_OBSERVE, obsReg.str().c_str(),
+                      &clientResponse->devAddr, 0, ConnType,
+                      OC_LOW_QOS, &cbData, NULL, 0);
     if (ret != OC_STACK_OK)
     {
         OIC_LOG(ERROR, TAG, "OCStack resource error");
@@ -326,11 +326,13 @@ int InitPutRequest(OCClientResponse * clientResponse)
     OIC_LOG_V(INFO, TAG, "PUT payload from client = ");
     OCPayload* payload = putPayload();
     OIC_LOG_PAYLOAD(INFO, payload);
+
+    ret = OCDoRequest(NULL, OC_REST_PUT, getQuery.str().c_str(),
+                      &clientResponse->devAddr, payload, ConnType,
+                      OC_LOW_QOS, &cbData, NULL, 0);
+
     OCPayloadDestroy(payload);
 
-    ret = OCDoResource(NULL, OC_REST_PUT, getQuery.str().c_str(),
-                       &clientResponse->devAddr, putPayload(), ConnType,
-                       OC_LOW_QOS, &cbData, NULL, 0);
     if (ret != OC_STACK_OK)
     {
         OIC_LOG(ERROR, TAG, "OCStack resource error");
@@ -353,9 +355,9 @@ int InitGetRequest(OCClientResponse * clientResponse)
     cbData.cb = getReqCB;
     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
     cbData.cd = NULL;
-    ret = OCDoResource(NULL, OC_REST_GET, getQuery.str().c_str(),
-                       &clientResponse->devAddr, 0, ConnType, OC_LOW_QOS,
-                       &cbData, NULL, 0);
+    ret = OCDoRequest(NULL, OC_REST_GET, getQuery.str().c_str(),
+                      &clientResponse->devAddr, 0, ConnType, OC_LOW_QOS,
+                      &cbData, NULL, 0);
     if (ret != OC_STACK_OK)
     {
         OIC_LOG(ERROR, TAG, "OCStack resource error");
@@ -370,14 +372,14 @@ int InitDiscovery()
     /* Start a discovery query*/
     char szQueryUri[MAX_QUERY_LENGTH] = { 0 };
 
-    OICStrcpy(szQueryUri, sizeof(RESOURCE_DISCOVERY_QUERY), RESOURCE_DISCOVERY_QUERY);
+    OICStrcpy(szQueryUri, sizeof(szQueryUri), RESOURCE_DISCOVERY_QUERY);
 
     cbData.cb = discoveryReqCB;
     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
     cbData.cd = NULL;
-    ret = OCDoResource(NULL, OC_REST_DISCOVER, szQueryUri, NULL, 0, ConnType,
-                        OC_LOW_QOS,
-            &cbData, NULL, 0);
+    ret = OCDoRequest(NULL, OC_REST_DISCOVER, szQueryUri, NULL, 0, ConnType,
+                      OC_LOW_QOS,
+                      &cbData, NULL, 0);
     if (ret != OC_STACK_OK)
     {
         OIC_LOG(ERROR, TAG, "OCStack resource error");
index aa45b6c..c4b762b 100644 (file)
@@ -104,9 +104,12 @@ OCStackResult InvokeOCDoResource(std::ostringstream &query,
     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
     cbData.cd = NULL;
 
-    ret = OCDoResource(NULL, method, query.str().c_str(), dest,
-            (method == OC_REST_PUT) ? putPayload() : NULL,
-            adapterType, qos, &cbData, options, numOptions);
+    OCPayload* payload = (method == OC_REST_PUT) ? putPayload() : NULL;
+
+    ret = OCDoRequest(NULL, method, query.str().c_str(), dest,
+                      payload, adapterType, qos, &cbData, options, numOptions);
+
+    OCPayloadDestroy(payload);
 
     if (ret != OC_STACK_OK)
     {
@@ -250,8 +253,8 @@ int InitDiscovery()
     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
     cbData.cd = NULL;
 
-    ret = OCDoResource(NULL, OC_REST_DISCOVER, queryUri, 0, 0, CT_DEFAULT,
-                       OC_LOW_QOS, &cbData, NULL, 0);
+    ret = OCDoRequest(NULL, OC_REST_DISCOVER, queryUri, 0, 0, CT_DEFAULT,
+                      OC_LOW_QOS, &cbData, NULL, 0);
     if (ret != OC_STACK_OK)
     {
         OIC_LOG(ERROR, TAG, "OCStack resource error");
index 39627df..7090bef 100644 (file)
@@ -110,17 +110,20 @@ OCStackResult InvokeOCDoResource(std::ostringstream &query,
     cbData.context  = (void*)DEFAULT_CONTEXT_VALUE;
     cbData.cd       = NULL;
 
-    OCStackResult ret = OCDoResource(
-        &handle,
-        method,
-        query.str().c_str(),
-        &responseAddr,
-        (method == OC_REST_PUT) ? putPayload() : NULL,
-        CT_ADAPTER_REMOTE_ACCESS,
-        qos,
-        &cbData,
-        options,
-        numOptions);
+    OCPayload* payload = (method == OC_REST_PUT) ? putPayload() : NULL;
+
+    OCStackResult ret = OCDoRequest(&handle,
+                                    method,
+                                    query.str().c_str(),
+                                    &responseAddr,
+                                    payload,
+                                    CT_ADAPTER_REMOTE_ACCESS,
+                                    qos,
+                                    &cbData,
+                                    options,
+                                    numOptions);
+
+    OCPayloadDestroy(payload);
 
     if (ret != OC_STACK_OK)
     {
@@ -424,17 +427,16 @@ int InitDiscovery(OCQualityOfService qos)
     dest.flags      = OC_DEFAULT_FLAGS;
     strncpy (dest.addr, remoteServerJabberID, MAX_ADDR_STR_SIZE - 1);
 
-    OCStackResult ret = OCDoResource(NULL,
-                OC_REST_GET,
-                MULTICAST_RESOURCE_DISCOVERY_QUERY,
-                &dest,
-                NULL,
-                CT_ADAPTER_REMOTE_ACCESS,
-                (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS,
-                &cbData,
-                NULL,
-                0
-            );
+    OCStackResult ret = OCDoRequest(NULL,
+                                    OC_REST_GET,
+                                    MULTICAST_RESOURCE_DISCOVERY_QUERY,
+                                    &dest,
+                                    NULL,
+                                    CT_ADAPTER_REMOTE_ACCESS,
+                                    (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS,
+                                    &cbData,
+                                    NULL,
+                                    0);
 
     if (ret != OC_STACK_OK)
     {
index e203bb5..b832193 100644 (file)
@@ -522,6 +522,7 @@ OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
         }
     }
 
+    OCPayloadDestroy(response.payload);
     return ehResult;
 }
 
index ed18975..bedce0d 100644 (file)
@@ -319,9 +319,9 @@ OCEntityHandlerResult OCEntityHandlerRoomCb(OCEntityHandlerFlag flag,
         {
             OIC_LOG_V (INFO, TAG, "Received unsupported method %d from client",
                     ehRequest->method);
-            OCRepPayloadDestroy(payload);
             ret = OC_EH_ERROR;
         }
+        OCRepPayloadDestroy(payload);
     }
     else if (ehRequest && flag == OC_OBSERVE_FLAG)
     {
@@ -382,10 +382,7 @@ OCEntityHandlerResult OCEntityHandlerLightCb(OCEntityHandlerFlag flag,
                 ret = OC_EH_ERROR;
             }
         }
-        else
-        {
-            OCRepPayloadDestroy(payload);
-        }
+        OCRepPayloadDestroy(payload);
     }
     else if (ehRequest && flag == OC_OBSERVE_FLAG)
     {
index 997b789..2e45cbc 100644 (file)
 #include "oic_malloc.h"
 #include "oic_string.h"
 #include "logger.h"
+#if defined (__TIZENRT__)
+#include <apps/netutils/cJSON.h>
+#else
 #include "cJSON.h"
+#endif
 #include "ocserverslow.h"
 #include "ocpayload.h"
 #include "payload_logging.h"
@@ -149,7 +153,7 @@ void ProcessGetPutRequest (OCEntityHandlerRequest *ehRequest)
         OIC_LOG(ERROR, TAG, "Error sending response");
     }
 
-    free(getResp);
+    OCRepPayloadDestroy(getResp);
 }
 
 OCEntityHandlerRequest *CopyRequest(OCEntityHandlerRequest *entityHandlerRequest)
index b271acd..9c90b49 100644 (file)
@@ -29,7 +29,6 @@ samples_env.PrependUnique(CPPPATH = [
                '../../../../stack/include',
                '../../../../security/include',
                '../../../../../../extlibs/cjson',
-               '../../../../../../extlibs/tinydtls',
                '../../../../../oc_logger/include'
                ])
 
index 10aa3ff..d6ce307 100644 (file)
@@ -124,9 +124,12 @@ OCStackResult InvokeOCDoResource(std::ostringstream &query,
     cbData.context = NULL;
     cbData.cd = NULL;
 
-    ret = OCDoResource(NULL, method, query.str().c_str(), dest,
-            (method == OC_REST_PUT || method == OC_REST_POST) ? putPayload() : NULL,
-            ocConnType, qos, &cbData, options, numOptions);
+    OCPayload* payload = (method == OC_REST_PUT || method == OC_REST_POST) ? putPayload() : NULL;
+
+    ret = OCDoRequest(NULL, method, query.str().c_str(), dest,
+                      payload, ocConnType, qos, &cbData, options, numOptions);
+
+    OCPayloadDestroy(payload);
 
     if (ret != OC_STACK_OK)
     {
@@ -144,7 +147,7 @@ OCStackApplicationResult putReqCB(void*, OCDoHandle, OCClientResponse * clientRe
     {
         OIC_LOG_V(INFO, TAG, "StackResult: %s",  getResult(clientResponse->result));
         OIC_LOG_PAYLOAD(INFO, clientResponse->payload);
-        OIC_LOG(INFO, TAG, ("=============> Put Response"));
+        OIC_LOG(INFO, TAG, "=============> Put Response");
     }
     return OC_STACK_DELETE_TRANSACTION;
 }
@@ -157,7 +160,7 @@ OCStackApplicationResult postReqCB(void *, OCDoHandle, OCClientResponse *clientR
     {
         OIC_LOG_V(INFO, TAG, "StackResult: %s",  getResult(clientResponse->result));
         OIC_LOG_PAYLOAD(INFO, clientResponse->payload);
-        OIC_LOG(INFO, TAG, ("=============> Post Response"));
+        OIC_LOG(INFO, TAG, "=============> Post Response");
     }
     return OC_STACK_DELETE_TRANSACTION;
 }
@@ -171,7 +174,7 @@ OCStackApplicationResult getReqCB(void*, OCDoHandle, OCClientResponse * clientRe
         OIC_LOG_V(INFO, TAG, "StackResult: %s",  getResult(clientResponse->result));
         OIC_LOG_V(INFO, TAG, "SEQUENCE NUMBER: %d", clientResponse->sequenceNumber);
         OIC_LOG_PAYLOAD(INFO, clientResponse->payload);
-        OIC_LOG(INFO, TAG, ("=============> Get Response"));
+        OIC_LOG(INFO, TAG, "=============> Get Response");
     }
     return OC_STACK_DELETE_TRANSACTION;
 }
@@ -327,8 +330,8 @@ int InitDiscovery()
         (UnicastDiscovery) ? "Unicast" : "Multicast",
         queryUri);
 
-    ret = OCDoResource(NULL, OC_REST_DISCOVER, queryUri, 0, 0, CT_DEFAULT,
-                       OC_LOW_QOS, &cbData, NULL, 0);
+    ret = OCDoRequest(NULL, OC_REST_DISCOVER, queryUri, 0, 0, CT_DEFAULT,
+                      OC_LOW_QOS, &cbData, NULL, 0);
     if (ret != OC_STACK_OK)
     {
         OIC_LOG(ERROR, TAG, "OCStack resource error");
index 5ae096b..74dd822 100644 (file)
@@ -61,8 +61,8 @@ static char DISCOVERY_QUERY[] = "%s/oic/res";
 //Secure Virtual Resource database for Iotivity Client application\r
 //It contains Client's Identity and the PSK credentials\r
 //of other devices which the client trusts\r
-static char CRED_FILE[] = "oic_svr_db_client_directpairing.dat";
-
+static char CRED_FILE[] = "oic_svr_db_client_directpairing.dat";\r
+\r
 static const OCDPDev_t *discoveredDevs = NULL;\r
 static const OCDPDev_t *pairedDevs = NULL;\r
 \r
@@ -335,8 +335,8 @@ int DeviceDiscovery()
     /* Start a discovery query*/\r
     OIC_LOG_V(INFO, TAG, "Resource Discovery : %s\n", queryUri);\r
 \r
-    ret = OCDoResource(NULL, OC_REST_DISCOVER, queryUri, 0, 0, CT_DEFAULT,\r
-                       OC_LOW_QOS, &cbData, NULL, 0);\r
+    ret = OCDoRequest(NULL, OC_REST_DISCOVER, queryUri, 0, 0, CT_DEFAULT,\r
+                      OC_LOW_QOS, &cbData, NULL, 0);\r
     if (ret != OC_STACK_OK)\r
     {\r
         OIC_LOG(ERROR, TAG, "OCStack resource error");\r
@@ -400,8 +400,8 @@ OCStackResult SendGetRequest(OCDPDev_t* peer)
     cbData.cd = NULL;\r
 \r
     OIC_LOG(INFO, TAG, "Request to /a/light ");\r
-    ret = OCDoResource(&handle, OC_REST_GET, szQueryUri,\r
-               &endpoint, NULL, peer->connType, OC_LOW_QOS, &cbData, NULL, 0);\r
+    ret = OCDoRequest(&handle, OC_REST_GET, szQueryUri,\r
+                      &endpoint, NULL, peer->connType, OC_LOW_QOS, &cbData, NULL, 0);\r
     if (ret != OC_STACK_OK)\r
     {\r
         OIC_LOG_V(ERROR, TAG, "OCDoResource returns error %d with method %d", ret, OC_REST_GET);\r
@@ -527,8 +527,8 @@ void *CLInterface(void *data)
                     OIC_LOG(ERROR, TAG, "Invalid PIN");\r
                     continue;\r
                 }\r
-                sscanf(input, "%8s", pinNumber);
-                printf("\n");
+                sscanf(input, "%8s", pinNumber);\r
+                printf("\n");\r
 \r
                 ret = DoDirectPairing(peer, pmSel, pinNumber);\r
                 if (OC_STACK_OK != ret)\r
index 6ebc856..9e161ef 100644 (file)
@@ -301,7 +301,7 @@ OCEntityHandlerCb (OCEntityHandlerFlag flag,
         }
     }
 
-    OCPayloadDestroy(response.payload);
+    OCRepPayloadDestroy(payload);
     return ehResult;
 }
 
index da6064e..56f60b9 100644 (file)
Binary files a/resource/csdk/stack/samples/linux/secure/oic_svr_db_client_directpairing.dat and b/resource/csdk/stack/samples/linux/secure/oic_svr_db_client_directpairing.dat differ
index ddb7cb9..1fcceb7 100644 (file)
                             "if": ["oic.if.baseline"]
                         },
                         {
-                            "href": "/oic/sec/acl",
-                            "rel": "",
-                            "rt": ["oic.r.acl"],
-                            "if": ["oic.if.baseline"]
-                        },
-                        {
                             "href": "/oic/sec/cred",
                             "rel": "",
                             "rt": ["oic.r.cred"],
@@ -66,8 +60,8 @@
         "rowneruuid": "64697265-6374-7061-6972-696e67446576",
         "cm": 2,
         "tm": 0,
-        "om": 3,
-        "sm": 3
+        "om": 4,
+        "sm": 4
         },
     "doxm": {
         "oxms": [0],
index c48d813..a50a65a 100644 (file)
Binary files a/resource/csdk/stack/samples/linux/secure/oic_svr_db_server.dat and b/resource/csdk/stack/samples/linux/secure/oic_svr_db_server.dat differ
index 52004cb..8d52f5c 100644 (file)
                     "subjectuuid": "32323232-3232-3232-3232-323232323232",\r
                     "resources": [\r
                         {\r
-                            "href": "/oic/sec/acl",\r
-                            "rel": "",\r
-                            "rt": ["oic.r.acl"],\r
-                            "if": ["oic.if.baseline"]\r
-                        },\r
-                        {\r
-                            "href": "/oic/sec/cred",\r
+                            "href": "*",\r
                             "rel": "",\r
-                            "rt": ["oic.r.cred"],\r
-                            "if": ["oic.if.baseline"]\r
+                            "rt": ["*"],\r
+                            "if": ["*"]\r
                         }\r
                     ],\r
-                    "permission": 8\r
+                    "permission": 7\r
                 },\r
                 {\r
                     "subjectuuid": "31393139-3139-3139-3139-313931393139",\r
@@ -78,7 +72,7 @@
                             "if": ["oic.if.baseline"]\r
                         }\r
                     ],\r
-                    "permission": 6\r
+                    "permission": 7\r
                 },\r
                 {\r
                     "subjectuuid": "37373737-3737-3737-3737-373737373737",\r
index 135d7b3..e02d465 100644 (file)
Binary files a/resource/csdk/stack/samples/linux/secure/oic_svr_db_server_justworks.dat and b/resource/csdk/stack/samples/linux/secure/oic_svr_db_server_justworks.dat differ
index a3b7018..b8941d4 100644 (file)
                             "rel": ""\r
                         },\r
                         {\r
-                            "href": "/oic/sec/acl",\r
-                            "rt": ["oic.r.acl"],\r
-                            "if": ["oic.if.baseline"],\r
-                            "rel": ""\r
-                        },\r
-                        {\r
                             "href": "/oic/sec/cred",\r
                             "rt": ["oic.r.cred"],\r
                             "if": ["oic.if.baseline"],\r
@@ -78,4 +72,4 @@
         "devowneruuid": "",\r
         "rowneruuid": "6a757374-776f-726b-4465-765575696430"\r
     }\r
-}
\ No newline at end of file
+}\r
index 5bcb4ec..8872a4d 100644 (file)
@@ -58,6 +58,7 @@ help_vars.Add(EnumVariable('SECURED', 'Build with DTLS', '0', allowed_values=('0
 help_vars.Add(EnumVariable('ROUTING', 'Enable routing', 'EP', allowed_values=('GW', 'EP')))
 help_vars.Add(BoolVariable('WITH_PROXY', 'CoAP-HTTP Proxy', False)) # set to 'no', 'false' or 0 for debug
 help_vars.Add(ListVariable('WITH_MQ', 'Build with MQ publisher/subscriber/broker', 'OFF', ['OFF', 'SUB', 'PUB', 'BROKER']))
+help_vars.Add(BoolVariable('WITH_TCP', 'Build with TCP', False))
 
 ######################################################################
 # Platform(build target) specific options: SDK/NDK & toolchain
index fe1f95f..6736a69 100644 (file)
@@ -59,6 +59,8 @@ static const char *DEVICE_DISCOVERY_QUERY = "%s/oic/d";
 static const char *PLATFORM_DISCOVERY_QUERY = "%s/oic/p";
 static const char *RESOURCE_DISCOVERY_QUERY = "%s/oic/res";
 
+static const char *DEFAULT_DB_FILE_PATH = "/opt/usr/etc/oic_svr_db_client.dat";
+
 //The following variable determines the interface protocol (IPv4, IPv6, etc)
 //to be used for sending unicast messages. Default set to IP dual stack.
 static OCConnectivityType g_connType = CT_ADAPTER_IP;
@@ -110,11 +112,12 @@ OCPayload* putPayload()
 static void PrintUsage()
 {
     cout << "Hello";
-    cout << "\nUsage : occlient -u <0|1> -t <1..17> -c <0|1|2>";
+    cout << "\nUsage : occlient -u <0|1> -t <1..17> -c <0|1|2|3>";
     cout << "\n-u <0|1> : Perform multicast/unicast discovery of resources";
     cout << "\n-c 0 : Default IP selection";
     cout << "\n-c 1 : IP Connectivity Type";
     cout << "\n-c 2 : EDR Connectivity Type (IPv6 not currently supported)";
+    cout << "\n-c 3 : TCP Connectivity Type";
     cout << "\n-t 1  :  Discover Resources";
     cout << "\n-t 2  :  Discover Resources and Initiate Nonconfirmable Get Request";
     cout << "\n-t 3  :  Discover Resources and Initiate Nonconfirmable Get Request with query filter";
@@ -161,9 +164,12 @@ OCStackResult InvokeOCDoResource(std::ostringstream &query,
     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
     cbData.cd = NULL;
 
-    ret = OCDoResource(&handle, method, query.str().c_str(), remoteAddr,
-                       (method == OC_REST_PUT) ? putPayload() : NULL,
-                       (g_connType), qos, &cbData, options, numOptions);
+    OCPayload* payload = (method == OC_REST_PUT) ? putPayload() : NULL;
+
+    ret = OCDoRequest(&handle, method, query.str().c_str(), remoteAddr,
+                      payload, (g_connType), qos, &cbData, options, numOptions);
+
+    OCPayloadDestroy(payload);
 
     if (ret != OC_STACK_OK)
     {
@@ -390,16 +396,61 @@ OCStackApplicationResult discoveryReqCB(void* ctx, OCDoHandle /*handle*/,
         cout << "\nDiscovered on " << connectionType.c_str();
         cout << "\nDevice ======> Discovered ";
         cout << clientResponse->devAddr.addr;
-        if (CT_ADAPTER_IP == clientResponse->connType)
+        if (CT_ADAPTER_IP == (clientResponse->connType & CT_MASK_ADAPTER))
         {
             cout << ":" << clientResponse->devAddr.port;
         }
         //OIC_LOG_PAYLOAD(INFO, clientResponse->payload);
         cout << "\nConnectivity type: " << clientResponse->connType;
-        g_connType = clientResponse->connType;
         g_serverAddr = clientResponse->devAddr;
         parseClientResponse(clientResponse);
 
+        OCDiscoveryPayload *payload = (OCDiscoveryPayload*) clientResponse->payload;
+        if (!payload)
+        {
+            cout << "\nDiscovery payload is empty!";
+            return OC_STACK_KEEP_TRANSACTION;
+        }
+
+        OCResourcePayload *resource = (OCResourcePayload*) payload->resources;
+        int targetResourceFound = 0;
+        while(resource)
+        {
+            cout << "\nFound resource: " << resource->uri;
+            if (resource->uri && strcmp(resource->uri, coapServerResource.c_str()) == 0)
+            {
+                cout << "\nLight resource found.";
+                targetResourceFound = 1;
+
+                if (g_testCase >= TEST_OBS_PRESENCE) break;
+
+                if (resource->secure && resource->port)
+                {
+                    cout << "\nLight resource with secure flag";
+                    g_serverAddr.flags = (OCTransportFlags) (clientResponse->devAddr.flags | OC_SECURE);
+                    g_serverAddr.port = resource->port;
+                }
+
+#ifdef WITH_TCP
+                if(g_connType == CT_ADAPTER_TCP && resource->tcpPort)
+                {
+                    cout << "\nRequest will be send with TCP";
+                    g_serverAddr.port = resource->tcpPort;
+                    g_serverAddr.adapter = OC_ADAPTER_TCP;
+                }
+#endif
+
+                break;
+            }
+            resource = resource->next;
+        }
+
+        if (!targetResourceFound)
+        {
+            OIC_LOG_V(INFO, TAG, "No %s in payload", coapServerResource.c_str());
+            return OC_STACK_KEEP_TRANSACTION;
+        }
+
         switch(g_testCase)
         {
             case TEST_GET_REQ_NON:
@@ -728,9 +779,9 @@ int InitPlatformDiscovery(OCQualityOfService qos)
     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
     cbData.cd = NULL;
 
-    ret = OCDoResource(NULL, OC_REST_DISCOVER, szQueryUri, NULL, 0, CT_DEFAULT,
-                       (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS,
-                       &cbData, NULL, 0);
+    ret = OCDoRequest(NULL, OC_REST_DISCOVER, szQueryUri, NULL, 0, CT_DEFAULT,
+                      (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS,
+                      &cbData, NULL, 0);
     if (ret != OC_STACK_OK)
     {
         cout << "\nOCStack device error";
@@ -753,9 +804,9 @@ int InitDeviceDiscovery(OCQualityOfService qos)
     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
     cbData.cd = NULL;
 
-    ret = OCDoResource(NULL, OC_REST_DISCOVER, szQueryUri, NULL, 0, CT_DEFAULT,
-                       (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS,
-                       &cbData, NULL, 0);
+    ret = OCDoRequest(NULL, OC_REST_DISCOVER, szQueryUri, NULL, 0, CT_DEFAULT,
+                      (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS,
+                      &cbData, NULL, 0);
     if (ret != OC_STACK_OK)
     {
         cout << "\nOCStack device error";
@@ -776,9 +827,9 @@ int InitDiscovery(OCQualityOfService qos)
     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
     cbData.cd = NULL;
 
-    ret = OCDoResource(NULL, OC_REST_DISCOVER, szQueryUri, NULL, 0, CT_DEFAULT,
-                       (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS,
-                       &cbData, NULL, 0);
+    ret = OCDoRequest(NULL, OC_REST_DISCOVER, szQueryUri, NULL, 0, CT_DEFAULT,
+                      (qos == OC_HIGH_QOS) ? OC_HIGH_QOS : OC_LOW_QOS,
+                      &cbData, NULL, 0);
     if (ret != OC_STACK_OK)
     {
         cout << "\nOCStack resource error";
@@ -821,6 +872,11 @@ void *GMainLoopThread(void *param)
     return NULL;
 }
 
+static FILE *client_fopen(const char */*path*/, const char *mode)
+{
+    return fopen(DEFAULT_DB_FILE_PATH, mode);
+}
+
 int main(int argc, char* argv[])
 {
     int opt;
@@ -861,7 +917,10 @@ int main(int argc, char* argv[])
 
     cout << "\nEntering occlient main loop...\n";
 
-    if (OCInit1(OC_CLIENT, OC_DEFAULT_FLAGS, OC_DEFAULT_FLAGS) != OC_STACK_OK)
+    OCPersistentStorage ps{ client_fopen, fread, fwrite, fclose, unlink };
+    OCRegisterPersistentStorageHandler(&ps);
+
+    if (OCInit1(OC_CLIENT_SERVER, OC_DEFAULT_FLAGS, OC_DEFAULT_FLAGS) != OC_STACK_OK)
     {
         cout << "\nOCStack init error";
         return 0;
@@ -892,6 +951,11 @@ int main(int argc, char* argv[])
         cout << "\nSelected EDR Adapter\n";
         g_connType = CT_ADAPTER_RFCOMM_BTEDR;
     }
+    else if(g_connectivity == CT_TCP)
+    {
+        cout << "\nSelected TCP Adapter\n";
+        g_connType = CT_ADAPTER_TCP;
+    }
     else
     {
         cout << "\nDefault Connectivity type selected...";
index e63d947..60b4f14 100644 (file)
@@ -75,6 +75,7 @@ typedef enum {
     CT_ADAPTER_DEFAULT = 0,
     CT_IP,
     CT_EDR,
+    CT_TCP,
     MAX_CT
 } CLIENT_CONNECTIVITY_TYPE;
 
index 4305399..650b428 100644 (file)
@@ -39,8 +39,10 @@ using namespace std;
 //string length of "/a/light/" + std::numeric_limits<int>::digits10 + '\0'"
 // 9 + 9 + 1 = 19
 const int URI_MAXSIZE = 19;
+static const char* DEFAULT_DB_FILE_PATH = "/opt/usr/etc/oic_svr_db_server.dat";
 
 static int gObserveNotifyType = 3;
+static int gSecure = 0;
 
 int gQuitFlag = 0;
 int gLightUnderObservation = 0;
@@ -505,6 +507,7 @@ OCDeviceEntityHandlerCb (OCEntityHandlerFlag flag,
         }
     }
 
+    OCPayloadDestroy(response.payload);
     return ehResult;
 }
 
@@ -735,13 +738,20 @@ void *presenceNotificationGenerator(void *param)
         if(res == OC_STACK_OK)
         {
             sleep(2);
+
+            uint8_t resourceProperties = OC_DISCOVERABLE | OC_OBSERVABLE;
+            if (gSecure)
+            {
+                resourceProperties |= OC_SECURE;
+            }
+
             res = OCCreateResource(&presenceNotificationHandles[i],
                     presenceNotificationResources.at(i).c_str(),
                     OC_RSRVD_INTERFACE_DEFAULT,
                     presenceNotificationUris.at(i).c_str(),
                     OCNOPEntityHandlerCb,
                     NULL,
-                    OC_DISCOVERABLE|OC_OBSERVABLE);
+                    resourceProperties);
         }
         if(res != OC_STACK_OK)
         {
@@ -780,13 +790,20 @@ int createLightResource (char *uri, LightResource *lightResource)
 
     lightResource->state = false;
     lightResource->power= 0;
+
+    uint8_t resourceProperties = OC_DISCOVERABLE | OC_OBSERVABLE;
+    if (gSecure)
+    {
+        resourceProperties |= OC_SECURE;
+    }
+
     OCStackResult res = OCCreateResource(&(lightResource->handle),
             "core.light",
             "oc.mi.def",
             uri,
             OCEntityHandlerCb,
             NULL,
-            OC_DISCOVERABLE|OC_OBSERVABLE);
+            resourceProperties);
     cout << "\nCreated Light resource with result " << getResult(res);
 
     return 0;
@@ -936,9 +953,11 @@ OCStackResult SetDeviceInfo(const char* deviceName, const char* specVersion, con
 
 static void PrintUsage()
 {
-    cout << "\nUsage : ocserver -o <0|1>";
+    cout << "\nUsage : ocserver -o <0|1> -s <0|1>";
     cout << "\n-o 0 : Notify all observers";
     cout << "\n-o 1 : Notify list of observers";
+    cout << "\n-s 0 : Non secure resource";
+    cout << "\n-s 1 : Secure resource";
 }
 
 void *GMainLoopThread(void *param)
@@ -963,6 +982,11 @@ void *GMainLoopThread(void *param)
     return NULL;
 }
 
+static FILE *server_fopen(const char */*path*/, const char *mode)
+{
+    return fopen(DEFAULT_DB_FILE_PATH, mode);
+}
+
 int main(int argc, char* argv[])
 {
     pthread_t threadId;
@@ -976,20 +1000,24 @@ int main(int argc, char* argv[])
         return 0;
     }
 
-    while ((opt = getopt(argc, argv, "o:")) != -1)
+    while ((opt = getopt(argc, argv, "o:s:")) != -1)
     {
         switch(opt)
         {
             case 'o':
                 gObserveNotifyType = atoi(optarg);
                 break;
+            case 's':
+                gSecure = atoi(optarg);
+                break;
             default:
                 PrintUsage();
                 return -1;
         }
     }
 
-    if ((gObserveNotifyType != 0) && (gObserveNotifyType != 1))
+    if ((gObserveNotifyType != 0) && (gObserveNotifyType != 1) &&
+            (gSecure != 0) && (gSecure != 1))
     {
         PrintUsage();
         return -1;
@@ -997,6 +1025,9 @@ int main(int argc, char* argv[])
 
     cout << "\nOCServer is starting...";
 
+    OCPersistentStorage ps{ server_fopen, fread, fwrite, fclose, unlink };
+    OCRegisterPersistentStorageHandler(&ps);
+
     if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
     {
         cout << "\nOCStack init error";
diff --git a/resource/csdk/stack/samples/tizen/SimpleClientServer/oic_svr_db_client.dat b/resource/csdk/stack/samples/tizen/SimpleClientServer/oic_svr_db_client.dat
new file mode 100644 (file)
index 0000000..8574d70
Binary files /dev/null and b/resource/csdk/stack/samples/tizen/SimpleClientServer/oic_svr_db_client.dat differ
diff --git a/resource/csdk/stack/samples/tizen/SimpleClientServer/oic_svr_db_client.json b/resource/csdk/stack/samples/tizen/SimpleClientServer/oic_svr_db_client.json
new file mode 100644 (file)
index 0000000..43d07b9
--- /dev/null
@@ -0,0 +1,89 @@
+{\r
+    "acl": {\r
+        "aclist": {\r
+            "aces": [\r
+                {\r
+                    "subjectuuid": "*",\r
+                    "resources": [\r
+                        {\r
+                            "href": "/oic/res",\r
+                            "rel": "",\r
+                            "rt": ["oic.wk.res"],\r
+                            "if": ["oic.if.ll"]\r
+                        },\r
+                        {\r
+                            "href": "/oic/d",\r
+                            "rel": "",\r
+                            "rt": ["oic.wk.d"],\r
+                            "if": ["oic.if.baseline", "oic.if.r"]\r
+                        },\r
+                        {\r
+                            "href": "/oic/p",\r
+                            "rel": "",\r
+                            "rt": ["oic.wk.p"],\r
+                            "if": ["oic.if.baseline", "oic.if.r"]\r
+                        },\r
+                        {\r
+                            "href": "/oic/sec/acl",\r
+                            "rel": "",\r
+                            "rt": ["oic.r.acl"],\r
+                            "if": ["oic.if.baseline"]\r
+                        }\r
+                    ],\r
+                    "permission": 2\r
+                },\r
+                {\r
+                    "subjectuuid": "*",\r
+                    "resources": [\r
+                        {\r
+                            "href": "/oic/sec/doxm",\r
+                            "rel": "",\r
+                            "rt": ["oic.r.doxm"],\r
+                            "if": ["oic.if.baseline"]\r
+                        },\r
+                        {\r
+                            "href": "/oic/sec/pstat",\r
+                            "rel": "",\r
+                            "rt": ["oic.r.pstat"],\r
+                            "if": ["oic.if.baseline"]\r
+                        }\r
+                    ],\r
+                    "permission": 2\r
+                }\r
+            ]\r
+        },\r
+        "rowneruuid" : "32323232-3232-3232-3232-323232323232"\r
+    },\r
+    "pstat": {\r
+        "isop": true,\r
+        "deviceuuid": "32323232-3232-3232-3232-323232323232",\r
+        "rowneruuid": "32323232-3232-3232-3232-323232323232",\r
+        "cm": 0,\r
+        "tm": 0,\r
+        "om": 4,\r
+        "sm": 4\r
+        },\r
+    "doxm": {\r
+        "oxms": [0],\r
+        "oxmsel": 0,\r
+        "sct": 1,\r
+        "owned": true,\r
+        "deviceuuid": "32323232-3232-3232-3232-323232323232",\r
+        "devowneruuid": "32323232-3232-3232-3232-323232323232",\r
+        "rowneruuid": "32323232-3232-3232-3232-323232323232"\r
+    },\r
+    "cred": {\r
+        "creds": [\r
+            {\r
+                "credid": 1,\r
+                "subjectuuid": "31313131-3131-3131-3131-313131313131",\r
+                "credtype": 1,\r
+                "privatedata": {\r
+                    "data": "AAAAAAAAAAAAAAAA",\r
+                    "encoding": "oic.sec.encoding.raw"\r
+                }\r
+            }\r
+        ],\r
+        "rowneruuid": "32323232-3232-3232-3232-323232323232"\r
+    }\r
+}
\ No newline at end of file
diff --git a/resource/csdk/stack/samples/tizen/SimpleClientServer/oic_svr_db_server.dat b/resource/csdk/stack/samples/tizen/SimpleClientServer/oic_svr_db_server.dat
new file mode 100644 (file)
index 0000000..6b13e58
Binary files /dev/null and b/resource/csdk/stack/samples/tizen/SimpleClientServer/oic_svr_db_server.dat differ
diff --git a/resource/csdk/stack/samples/tizen/SimpleClientServer/oic_svr_db_server.json b/resource/csdk/stack/samples/tizen/SimpleClientServer/oic_svr_db_server.json
new file mode 100644 (file)
index 0000000..3046075
--- /dev/null
@@ -0,0 +1,101 @@
+{\r
+    "acl": {\r
+        "aclist": {\r
+            "aces": [\r
+                {\r
+                    "subjectuuid": "*",\r
+                    "resources": [\r
+                        {\r
+                            "href": "/oic/res",\r
+                            "rel": "",\r
+                            "rt": ["oic.wk.res"],\r
+                            "if": ["oic.if.ll"]\r
+                        },\r
+                        {\r
+                            "href": "/oic/d",\r
+                            "rel": "",\r
+                            "rt": ["oic.wk.d"],\r
+                            "if": ["oic.if.baseline", "oic.if.r"]\r
+                        },\r
+                        {\r
+                            "href": "/oic/p",\r
+                            "rel": "",\r
+                            "rt": ["oic.wk.p"],\r
+                            "if": ["oic.if.baseline", "oic.if.r"]\r
+                        },\r
+                        {\r
+                            "href": "/oic/sec/acl",\r
+                            "rel": "",\r
+                            "rt": ["oic.r.acl"],\r
+                            "if": ["oic.if.baseline"]\r
+                        }\r
+                    ],\r
+                    "permission": 2\r
+                },\r
+                {\r
+                    "subjectuuid": "*",\r
+                    "resources": [\r
+                        {\r
+                            "href": "/oic/sec/doxm",\r
+                            "rel": "",\r
+                            "rt": ["oic.r.doxm"],\r
+                            "if": ["oic.if.baseline"]\r
+                        },\r
+                        {\r
+                            "href": "/oic/sec/pstat",\r
+                            "rel": "",\r
+                            "rt": ["oic.r.pstat"],\r
+                            "if": ["oic.if.baseline"]\r
+                        }\r
+                    ],\r
+                    "permission": 2\r
+                },\r
+                {\r
+                    "subjectuuid": "*",\r
+                    "resources": [\r
+                        {\r
+                            "href": "/a/light",\r
+                            "rel": "",\r
+                            "rt": ["oic.core"],\r
+                            "if": ["oic.if.baseline"]\r
+                        }\r
+                    ],\r
+                    "permission": 31\r
+                }\r
+            ]\r
+        },\r
+        "rowneruuid" : "31313131-3131-3131-3131-313131313131"\r
+    },\r
+    "pstat": {\r
+        "isop": true,\r
+        "deviceuuid": "31313131-3131-3131-3131-313131313131",\r
+        "rowneruuid": "31313131-3131-3131-3131-313131313131",\r
+        "cm": 0,\r
+        "tm": 0,\r
+        "om": 4,\r
+        "sm": 4\r
+        },\r
+    "doxm": {\r
+        "oxms": [0],\r
+        "oxmsel": 0,\r
+        "sct": 1,\r
+        "owned": true,\r
+        "deviceuuid": "31313131-3131-3131-3131-313131313131",\r
+        "devowneruuid": "32323232-3232-3232-3232-323232323232",\r
+        "rowneruuid": "31313131-3131-3131-3131-313131313131"\r
+    },\r
+    "cred": {\r
+        "creds": [\r
+            {\r
+                "credid": 1,\r
+                "subjectuuid": "32323232-3232-3232-3232-323232323232",\r
+                "credtype": 1,\r
+                "privatedata": {\r
+                    "data": "AAAAAAAAAAAAAAAA",\r
+                    "encoding": "oic.sec.encoding.raw"\r
+                }\r
+            }\r
+        ],\r
+        "rowneruuid": "31313131-3131-3131-3131-313131313131"\r
+    }\r
+}\r
index 34afbb6..8fd0e1b 100644 (file)
@@ -53,8 +53,10 @@ if secured == '1':
        env.Append(LIBS=['mbedtls', 'mbedx509','mbedcrypto'])
 
 if 'ALL' in transport:
-               env.AppendUnique(CPPDEFINES = ['IP_ADAPTER','EDR_ADAPTER','LE_ADAPTER','BT_ADAPTER_TEST','BLE_ADAPTER_TEST'])
-               print "CA Transport is ALL"
+       env.AppendUnique(CPPDEFINES = ['IP_ADAPTER','EDR_ADAPTER','LE_ADAPTER','BT_ADAPTER_TEST','BLE_ADAPTER_TEST'])
+       print "CA Transport is ALL"
+       if env.get('WITH_TCP'):
+               env.AppendUnique(CPPDEFINES = ['TCP_ADAPTER', 'WITH_TCP'])
 else:
        if 'BT' in transport:
                env.AppendUnique(CPPDEFINES = ['EDR_ADAPTER','BT_ADAPTER_TEST'])
old mode 100644 (file)
new mode 100755 (executable)
index 1af1de6..bde1850
@@ -53,7 +53,6 @@ mkdir ./tmp/packaging
 cp -LR ./extlibs/tinycbor $sourcedir/tmp/extlibs
 cp -Rf ./extlibs/mbedtls $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 ./extlibs/libcoap $sourcedir/tmp/extlibs
index 9a6c5d6..9f1cec9 100644 (file)
@@ -33,6 +33,7 @@ Source0: http://mirrors.kernel.org/%{name}/%{version}/%{name}-%{version}.tar.gz
 %{!?WITH_TCP: %define WITH_TCP 0}
 
 BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(ttrace)
 BuildRequires: pkgconfig(glib-2.0)
 BuildRequires: pkgconfig(capi-network-connection)
 BuildRequires: pkgconfig(capi-network-bluetooth)
@@ -78,9 +79,8 @@ cp -f %{ROOTDIR}/extlibs/libcoap/libcoap.a %{buildroot}/%{_libdir}
 cp -av /usr/lib*/libuuid.so.1 %{buildroot}%{_libdir}/libuuid1.so ||:
 
 if echo %{SECURED}|grep -qi '1'; then
-       cp -f %{ROOTDIR}/out/tizen/*/*/extlibs/tinydtls/libtinydtls.a %{buildroot}/%{_libdir}
        cp -f %{ROOTDIR}/out/tizen/*/*/libmbedcrypto.a %{buildroot}/%{_libdir}
-       cp -f %{ROOTDIR}/out/tizen/*/*/libmbedtls.a %{buildroot}/%{_libdir}
+       cp -f %{ROOTDIR}/out/tizen/*/*/libmbedtls.so %{buildroot}/%{_libdir}
        cp -f %{ROOTDIR}/out/tizen/*/*/libmbedx509.a %{buildroot}/%{_libdir}
 fi
 
@@ -114,3 +114,7 @@ cp -rf %{ROOTDIR}/com.oic.ri.pc %{DEST_LIB_DIR}/pkgconfig/
 %{_libdir}/lib*.a*
 %{_includedir}/OICHeaders/*
 %{_libdir}/pkgconfig/*.pc
+%if 0%{?SECURED} == 1
+%{_libdir}/libmbedtls.so
+%endif
+
index ae3b2df..87564ec 100644 (file)
@@ -21,6 +21,9 @@ if env.get('LOGGING'):
     env.AppendUnique(CPPDEFINES = ['TB_LOG'])
 
 env.ParseConfig("pkg-config --cflags --libs capi-network-connection dlog glib-2.0")
+if env.get('OIC_SUPPORT_TIZEN_TRACE') == 'True':
+    env.ParseConfig("pkg-config --cflags --libs ttrace")
+    env.AppendUnique(CPPDEFINES = ['OIC_SUPPORT_TIZEN_TRACE'])
 if 'ALL' in transport:
                env.AppendUnique(CPPDEFINES = ['WIFI_ADAPTER', 'NO_ETHERNET_ADAPTER','EDR_ADAPTER','LE_ADAPTER'])
                print "CA Transport is ALL"
old mode 100644 (file)
new mode 100755 (executable)
index 40912b4..82f46ce
@@ -20,8 +20,8 @@
 
 #include "iotivity_config.h"
 #include "occlientcb.h"
-#include <coap/coap.h>
 #include "logger.h"
+#include "trace.h"
 #include "oic_malloc.h"
 #include <string.h>
 
@@ -34,6 +34,7 @@
 
 #include "cacommon.h"
 #include "cainterface.h"
+#include <coap/coap.h>
 
 /// Module Name
 #define TAG "OIC_RI_CLIENTCB"
@@ -52,6 +53,8 @@ AddClientCB (ClientCB** clientCB, OCCallbackData* cbData,
         return OC_STACK_INVALID_PARAM;
     }
 
+    OIC_TRACE_BEGIN(%s:AddClientCB, TAG);
+
     ClientCB *cbNode = NULL;
 
 #ifdef WITH_PRESENCE
@@ -73,6 +76,8 @@ AddClientCB (ClientCB** clientCB, OCCallbackData* cbData,
         {
             OIC_LOG(INFO, TAG, "Adding client callback with token");
             OIC_LOG_BUFFER(INFO, TAG, (const uint8_t *)token, tokenLength);
+            OIC_TRACE_BUFFER("OIC_RI_CLIENTCB:AddClientCB:token",
+                             (const uint8_t *) token, tokenLength);
             cbNode->callBack = cbData->cb;
             cbNode->context = cbData->context;
             cbNode->deleteCallback = cbData->cd;
@@ -88,7 +93,10 @@ AddClientCB (ClientCB** clientCB, OCCallbackData* cbData,
             cbNode->filterResourceType = NULL;
 #endif // WITH_PRESENCE
 
-            if (method == OC_REST_PRESENCE ||
+            if (
+#ifdef WITH_PRESENCE
+                method == OC_REST_PRESENCE ||
+#endif
                 method == OC_REST_OBSERVE  ||
                 method == OC_REST_OBSERVE_ALL)
             {
@@ -101,6 +109,7 @@ AddClientCB (ClientCB** clientCB, OCCallbackData* cbData,
             cbNode->requestUri = requestUri;    // I own it now
             cbNode->devAddr = devAddr;          // I own it now
             OIC_LOG_V(INFO, TAG, "Added Callback for uri : %s", requestUri);
+            OIC_TRACE_MARK(%s:AddClientCB:uri:%s, TAG, requestUri);
             LL_APPEND(cbList, cbNode);
             *clientCB = cbNode;
         }
@@ -126,6 +135,7 @@ AddClientCB (ClientCB** clientCB, OCCallbackData* cbData,
 
     if (method == OC_REST_PRESENCE && resourceTypeName)
     {
+        OIC_TRACE_END();
         // Amend the found or created node by adding a new resourceType to it.
         return InsertResourceTypeFilter(cbNode,(char *)resourceTypeName);
         // I own resourceTypName now.
@@ -138,25 +148,31 @@ AddClientCB (ClientCB** clientCB, OCCallbackData* cbData,
     OICFree(resourceTypeName);
 #endif
 
+    OIC_TRACE_END();
     return OC_STACK_OK;
 
 exit:
+    OIC_TRACE_END();
     return OC_STACK_NO_MEMORY;
 }
 
 void DeleteClientCB(ClientCB * cbNode)
 {
+    OIC_TRACE_BEGIN(%s:DeleteClientCB, TAG);
     if (cbNode)
     {
         LL_DELETE(cbList, cbNode);
         OIC_LOG (INFO, TAG, "Deleting token");
         OIC_LOG_BUFFER(INFO, TAG, (const uint8_t *)cbNode->token, cbNode->tokenLength);
+        OIC_TRACE_BUFFER("OIC_RI_CLIENTCB:DeleteClientCB:token",
+                         (const uint8_t *)cbNode->token, cbNode->tokenLength);
         CADestroyToken (cbNode->token);
         OICFree(cbNode->devAddr);
         OICFree(cbNode->handle);
         if (cbNode->requestUri)
         {
             OIC_LOG_V (INFO, TAG, "Deleting callback with uri %s", cbNode->requestUri);
+            OIC_TRACE_MARK(%s:DeleteClientCB:uri:%s, TAG, cbNode->requestUri);
             OICFree(cbNode->requestUri);
         }
         if (cbNode->deleteCallback)
@@ -186,6 +202,7 @@ void DeleteClientCB(ClientCB * cbNode)
         OICFree(cbNode);
         cbNode = NULL;
     }
+    OIC_TRACE_END();
 }
 
 /*
index aafb5ab..66b5dce 100755 (executable)
@@ -48,6 +48,7 @@ static bool AddRTSBaslinePayload(OCRepPayload **linkArray, int size, OCRepPayloa
         {
             OICFree(rt[l]);
         }
+        OICFree(rt);
     }
 
     for (OCStringLL *rsrcType = (*colPayload)->types; rsrcType; rsrcType = rsrcType->next, arraySize++);
@@ -71,6 +72,7 @@ static bool AddRTSBaslinePayload(OCRepPayload **linkArray, int size, OCRepPayloa
             rts[k++] = OICStrdup(rt[l]);
             OICFree(rt[l]);
         }
+        OICFree(rt);
     }
     for (OCStringLL *rsrcType = (*colPayload)->types; rsrcType; rsrcType = rsrcType->next, size++)
     {
@@ -173,7 +175,7 @@ exit:
     }
     ret = SendResponse(colPayload, ehRequest, collResource, ehResult);
     OIC_LOG_PAYLOAD(DEBUG, (OCPayload *)colPayload);
-
+    OCRepPayloadDestroy(colPayload);
     return ret;
 }
 
@@ -186,16 +188,14 @@ static OCStackResult HandleBatchInterface(OCEntityHandlerRequest *ehRequest)
 
     OCStackResult stackRet = OC_STACK_OK;
     char *storeQuery = NULL;
-    OCRepPayload *payload = OCRepPayloadCreate();
     OCResource *collResource = (OCResource *)ehRequest->resource;
-    VERIFY_PARAM_NON_NULL(TAG, payload, "Failed creating RepPayload");
 
     if (stackRet == OC_STACK_OK)
     {
 
         if (collResource->rsrcChildResourcesHead)
         {
-            storeQuery = OICStrdup(ehRequest->query);
+            storeQuery = ehRequest->query;
             ehRequest->query = NULL;
             OIC_LOG_V(DEBUG, TAG, "Query : %s", ehRequest->query);
         }
@@ -240,12 +240,8 @@ static OCStackResult HandleBatchInterface(OCEntityHandlerRequest *ehRequest)
         }
         ehRequest->resource = (OCResourceHandle) collResource;
     }
-    ehRequest->query = OICStrdup(storeQuery);
-    OICFree(storeQuery);
+    ehRequest->query = storeQuery;
     return stackRet;
-exit:
-    OICFree(storeQuery);
-    return OC_STACK_NO_MEMORY;
 }
 
 OCStackResult DefaultCollectionEntityHandler(OCEntityHandlerFlag flag, OCEntityHandlerRequest *ehRequest)
@@ -273,6 +269,9 @@ OCStackResult DefaultCollectionEntityHandler(OCEntityHandlerFlag flag, OCEntityH
     {
         ifQueryParam = OICStrdup(OC_RSRVD_INTERFACE_LL);
     }
+
+    VERIFY_PARAM_NON_NULL(TAG, ifQueryParam, "Invalid Parameter root");
+
     if (0 == strcmp(ifQueryParam, OC_RSRVD_INTERFACE_LL) || 0 == strcmp (ifQueryParam, OC_RSRVD_INTERFACE_DEFAULT))
     {
         if (ehRequest->method == OC_REST_PUT || ehRequest->method == OC_REST_POST)
index f7b2d3c..9cc6557 100644 (file)
@@ -370,7 +370,10 @@ OCStackResult GenerateObserverId (OCObservationId *observationId)
 
     do
     {
-        *observationId = OCGetRandomByte();
+        do
+        {
+            *observationId = OCGetRandomByte();
+        } while (0 == *observationId); //Make sure *observationId is not 0
         // Check if observation Id already exists
         resObs = GetObserverUsingId (*observationId);
     } while (NULL != resObs);
@@ -435,11 +438,13 @@ OCStackResult AddObserver (const char         *resUri,
         obsNode->devAddr = *devAddr;
         obsNode->resource = resHandle;
 
+#ifdef WITH_PRESENCE
         if ((strcmp(resUri, OC_RSRVD_PRESENCE_URI) == 0))
         {
             obsNode->TTL = 0;
         }
         else
+#endif
         {
             obsNode->TTL = GetTicks(MAX_OBSERVER_TTL_SECONDS * MILLISECONDS_PER_SECOND);
         }
old mode 100644 (file)
new mode 100755 (executable)
index a04f840..a80eb21
@@ -52,9 +52,11 @@ void OCPayloadDestroy(OCPayload* payload)
         case PAYLOAD_TYPE_DISCOVERY:
             OCDiscoveryPayloadDestroy((OCDiscoveryPayload*)payload);
             break;
+#ifdef WITH_PRESENCE
         case PAYLOAD_TYPE_PRESENCE:
             OCPresencePayloadDestroy((OCPresencePayload*)payload);
             break;
+#endif
         case PAYLOAD_TYPE_SECURITY:
             OCSecurityPayloadDestroy((OCSecurityPayload*)payload);
             break;
@@ -222,7 +224,10 @@ static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val)
 
     if (val->type == OCREP_PROP_STRING)
     {
-        OICFree(val->str);
+        if (val->str != NULL)
+        {
+            OICFree(val->str);
+        }
     }
     else if (val->type == OCREP_PROP_BYTE_STRING)
     {
@@ -245,28 +250,37 @@ static void OCFreeRepPayloadValueContents(OCRepPayloadValue* val)
                 OICFree(val->arr.iArray);
                 break;
             case OCREP_PROP_STRING:
-                for(size_t i = 0; i < dimTotal; ++i)
+                if (val->arr.strArray != NULL)
                 {
-                    OICFree(val->arr.strArray[i]);
+                    for(size_t i = 0; i < dimTotal; ++i)
+                    {
+                        OICFree(val->arr.strArray[i]);
+                    }
+                    OICFree(val->arr.strArray);
                 }
-                OICFree(val->arr.strArray);
                 break;
             case OCREP_PROP_BYTE_STRING:
-                for (size_t i = 0; i < dimTotal; ++i)
+                if (val->arr.ocByteStrArray != NULL)
                 {
-                    if (val->arr.ocByteStrArray[i].bytes)
+                    for (size_t i = 0; i < dimTotal; ++i)
                     {
-                        OICFree(val->arr.ocByteStrArray[i].bytes);
+                        if (val->arr.ocByteStrArray[i].bytes)
+                        {
+                            OICFree(val->arr.ocByteStrArray[i].bytes);
+                        }
                     }
+                    OICFree(val->arr.ocByteStrArray);
                 }
-                OICFree(val->arr.ocByteStrArray);
                 break;
             case OCREP_PROP_OBJECT: // This case is the temporary fix for string input
-                for(size_t i = 0; i< dimTotal; ++i)
+                if (val->arr.objArray != NULL)
                 {
-                    OCRepPayloadDestroy(val->arr.objArray[i]);
+                    for(size_t i = 0; i< dimTotal; ++i)
+                    {
+                        OCRepPayloadDestroy(val->arr.objArray[i]);
+                    }
+                    OICFree(val->arr.objArray);
                 }
-                OICFree(val->arr.objArray);
                 break;
             case OCREP_PROP_NULL:
             case OCREP_PROP_ARRAY:
@@ -818,7 +832,7 @@ bool OCRepPayloadGetPropPubDataType(const OCRepPayload *payload, const char *nam
         else
         {
             value->data = val.bytes;
-            value->len  = strlen(val.bytes);
+            value->len  = strlen((char *)val.bytes);
         }
     }
     else
@@ -1454,7 +1468,7 @@ OCStringLL* OCCreateOCStringLL(const char* text)
         {
             break;
         }
-        iter = (OCStringLL *)OICCalloc(1,sizeof(OCStringLL));
+        iter = (OCStringLL *)OICCalloc(1, sizeof(OCStringLL));
         VERIFY_PARAM_NON_NULL(TAG, iter, "Failed allocating memory");
         if (!result)
         {
@@ -1467,7 +1481,6 @@ OCStringLL* OCCreateOCStringLL(const char* text)
         iter->value = OICStrdup(token);
         VERIFY_PARAM_NON_NULL(TAG, iter->value, "Failed allocating memory");
         prev = iter;
-        iter = iter->next;
     }
     OICFree(backup);
     return result;
@@ -1895,7 +1908,6 @@ void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload)
     }
     OICFree(payload->sid);
     OICFree(payload->baseURI);
-    OICFree(payload->uri);
     OCFreeOCStringLL(payload->type);
     OICFree(payload->name);
     OCFreeOCStringLL(payload->iface);
@@ -1904,6 +1916,7 @@ void OCDiscoveryPayloadDestroy(OCDiscoveryPayload* payload)
     OICFree(payload);
 }
 
+#ifdef WITH_PRESENCE
 OCPresencePayload* OCPresencePayloadCreate(uint32_t seqNum, uint32_t maxAge,
         OCPresenceTrigger trigger, const char* resourceType)
 {
@@ -1930,3 +1943,4 @@ void OCPresencePayloadDestroy(OCPresencePayload* payload)
     OICFree(payload->resourceType);
     OICFree(payload);
 }
+#endif // WITH_PRESENCE
\ No newline at end of file
index 9961f72..daa9003 100755 (executable)
@@ -47,8 +47,10 @@ static int64_t OCConvertDiscoveryPayload(OCDiscoveryPayload *payload, uint8_t *o
         size_t *size);
 static int64_t OCConvertRepPayload(OCRepPayload *payload, uint8_t *outPayload, size_t *size);
 static int64_t OCConvertRepMap(CborEncoder *map, const OCRepPayload *payload);
+#ifdef WITH_PRESENCE
 static int64_t OCConvertPresencePayload(OCPresencePayload *payload, uint8_t *outPayload,
         size_t *size);
+#endif
 static int64_t OCConvertSecurityPayload(OCSecurityPayload *payload, uint8_t *outPayload,
         size_t *size);
 static int64_t OCConvertSingleRepPayload(CborEncoder *parent, const OCRepPayload *payload);
@@ -100,12 +102,14 @@ OCStackResult OCConvertPayload(OCPayload* payload, uint8_t** outPayload, size_t*
         // reallocate "out" and try again!
         uint8_t *out2 = (uint8_t *)OICRealloc(out, curSize);
         VERIFY_PARAM_NON_NULL(TAG, out2, "Failed to increase payload size");
+        memset(out2, 0, curSize);
         out = out2;
         err = OCConvertPayloadHelper(payload, out, &curSize);
         while (err == CborErrorOutOfMemory)
         {
             uint8_t *out2 = (uint8_t *)OICRealloc(out, curSize);
             VERIFY_PARAM_NON_NULL(TAG, out2, "Failed to increase payload size");
+            memset(out2, 0, curSize);
             out = out2;
             err = OCConvertPayloadHelper(payload, out, &curSize);
         }
@@ -143,8 +147,10 @@ static int64_t OCConvertPayloadHelper(OCPayload* payload, uint8_t* outPayload, s
             return OCConvertDiscoveryPayload((OCDiscoveryPayload*)payload, outPayload, size);
         case PAYLOAD_TYPE_REPRESENTATION:
             return OCConvertRepPayload((OCRepPayload*)payload, outPayload, size);
+#ifdef WITH_PRESENCE
         case PAYLOAD_TYPE_PRESENCE:
             return OCConvertPresencePayload((OCPresencePayload*)payload, outPayload, size);
+#endif
         case PAYLOAD_TYPE_SECURITY:
             return OCConvertSecurityPayload((OCSecurityPayload*)payload, outPayload, size);
         default:
@@ -647,6 +653,7 @@ exit:
     return checkError(err, &encoder, outPayload, size);
 }
 
+#ifdef WITH_PRESENCE
 static int64_t OCConvertPresencePayload(OCPresencePayload *payload, uint8_t *outPayload,
         size_t *size)
 {
@@ -691,6 +698,7 @@ static int64_t OCConvertPresencePayload(OCPresencePayload *payload, uint8_t *out
 exit:
     return checkError(err, &encoder, outPayload, size);
 }
+#endif // WITH_PRESENCE
 
 static int64_t AddTextStringToMap(CborEncoder* map, const char* key, size_t keylen,
         const char* value)
index ebb7d55..59c4c62 100755 (executable)
@@ -42,7 +42,9 @@
 static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue *arrayVal);
 static CborError OCParseSingleRepPayload(OCRepPayload **outPayload, CborValue *repParent, bool isRoot);
 static OCStackResult OCParseRepPayload(OCPayload **outPayload, CborValue *arrayVal);
+#ifdef WITH_PRESENCE
 static OCStackResult OCParsePresencePayload(OCPayload **outPayload, CborValue *arrayVal);
+#endif
 static OCStackResult OCParseSecurityPayload(OCPayload **outPayload, const uint8_t *payload, size_t size);
 
 OCStackResult OCParsePayload(OCPayload **outPayload, OCPayloadType payloadType,
@@ -56,7 +58,6 @@ OCStackResult OCParsePayload(OCPayload **outPayload, OCPayloadType payloadType,
 
     OIC_LOG_V(INFO, TAG, "CBOR Parsing size: %zu of Payload Type: %d, Payload:",
             payloadSize, payloadType);
-    OIC_LOG_BUFFER(DEBUG, TAG, payload, payloadSize);
 
     CborParser parser;
     CborValue rootValue;
@@ -72,9 +73,11 @@ OCStackResult OCParsePayload(OCPayload **outPayload, OCPayloadType payloadType,
         case PAYLOAD_TYPE_REPRESENTATION:
             result = OCParseRepPayload(outPayload, &rootValue);
             break;
+#ifdef WITH_PRESENCE
         case PAYLOAD_TYPE_PRESENCE:
             result = OCParsePresencePayload(outPayload, &rootValue);
             break;
+#endif
         case PAYLOAD_TYPE_SECURITY:
             result = OCParseSecurityPayload(outPayload, payload, payloadSize);
             break;
@@ -217,26 +220,18 @@ static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue *
             // BaseURI - Not a mandatory field
             err = cbor_value_map_find_value(&rootMap, OC_RSRVD_BASE_URI, &curVal);
             VERIFY_CBOR_SUCCESS(TAG, err, "to find uri tag");
-            if (cbor_value_is_valid(&curVal))
+            if (cbor_value_is_text_string(&curVal))
             {
                 err = cbor_value_dup_text_string(&curVal, &(temp->baseURI), &len, NULL);
                 VERIFY_CBOR_SUCCESS(TAG, err, "to find base uri value");
             }
 
-            // HREF - Not a mandatory field
-            err = cbor_value_map_find_value(&rootMap, OC_RSRVD_HREF, &curVal);
-            if (cbor_value_is_valid(&curVal))
-            {
-                err = cbor_value_dup_text_string(&curVal, &(temp->uri), &len, NULL);
-                VERIFY_CBOR_SUCCESS(TAG, err, "to find uri value");
-            }
-
             // RT - Not a mandatory field
             err = cbor_value_map_find_value(&rootMap, OC_RSRVD_RESOURCE_TYPE, &curVal);
             if (cbor_value_is_valid(&curVal))
             {
                 err = OCParseStringLL(&rootMap, OC_RSRVD_RESOURCE_TYPE, &temp->type);
-                VERIFY_CBOR_SUCCESS(TAG, err, "to find base uri value");
+                VERIFY_CBOR_SUCCESS(TAG, err, "to find resource type");
             }
 
             // IF - Not a mandatory field
@@ -244,18 +239,12 @@ static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue *
             if (cbor_value_is_valid(&curVal))
             {
                 err =  OCParseStringLL(&rootMap, OC_RSRVD_INTERFACE, &temp->iface);
-            }
-            if (!temp->iface)
-            {
-                if (!OCResourcePayloadAddStringLL(&temp->iface, OC_RSRVD_INTERFACE_LL))
-                {
-                    err = CborErrorOutOfMemory;
-                }
+                VERIFY_CBOR_SUCCESS(TAG, err, "to find interface");
             }
 
             // Name - Not a mandatory field
             err = cbor_value_map_find_value(&rootMap, OC_RSRVD_DEVICE_NAME, &curVal);
-            if (cbor_value_is_valid(&curVal))
+            if (cbor_value_is_text_string(&curVal))
             {
                 err = cbor_value_dup_text_string(&curVal, &temp->name, &len, NULL);
                 VERIFY_CBOR_SUCCESS(TAG, err, "to find device name");
@@ -315,7 +304,7 @@ static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue *
                 // Secure Flag
                 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_SECURE, &curVal);
                 VERIFY_CBOR_SUCCESS(TAG, err, "to find secure tag");
-                if (cbor_value_is_valid(&curVal))
+                if (cbor_value_is_boolean(&curVal))
                 {
                     err = cbor_value_get_boolean(&curVal, &(resource->secure));
                     VERIFY_CBOR_SUCCESS(TAG, err, "to find secure value");
@@ -324,7 +313,7 @@ static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue *
                 // Port
                 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_HOSTING_PORT, &curVal);
                 VERIFY_CBOR_SUCCESS(TAG, err, "to find port tag");
-                if (cbor_value_is_valid(&curVal))
+                if (cbor_value_is_integer(&curVal))
                 {
                     int port;
 
@@ -336,7 +325,7 @@ static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue *
 #ifdef TCP_ADAPTER
                 // TCP Port
                 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_TCP_PORT, &curVal);
-                if (cbor_value_is_valid(&curVal))
+                if (cbor_value_is_integer(&curVal))
                 {
                     int tcpPort;
 
@@ -348,7 +337,7 @@ static OCStackResult OCParseDiscoveryPayload(OCPayload **outPayload, CborValue *
 #ifdef __WITH_TLS__
                 // TLS Port
                 err = cbor_value_map_find_value(&policyMap, OC_RSRVD_TLS_PORT, &curVal);
-                if (cbor_value_is_valid(&curVal))
+                if (cbor_value_is_integer(&curVal))
                 {
                     int tlsPort;
 
@@ -775,6 +764,7 @@ static CborError OCParseSingleRepPayload(OCRepPayload **outPayload, CborValue *o
                 {
                     err = cbor_value_advance(&repMap);
                     OICFree(name);
+                    name = NULL;
                     continue;
                 }
             }
@@ -904,7 +894,7 @@ static OCStackResult OCParseRepPayload(OCPayload **outPayload, CborValue *root)
         {
             err = cbor_value_map_find_value(&rootMap, OC_RSRVD_HREF, &curVal);
             VERIFY_CBOR_SUCCESS(TAG, err, "to find href tag");
-            if (cbor_value_is_valid(&curVal))
+            if (cbor_value_is_text_string(&curVal))
             {
                 size_t len = 0;
                 err = cbor_value_dup_text_string(&curVal, &temp->uri, &len, NULL);
@@ -965,6 +955,7 @@ exit:
     return ret;
 }
 
+#ifdef WITH_PRESENCE
 static OCStackResult OCParsePresencePayload(OCPayload **outPayload, CborValue *rootValue)
 {
     OCStackResult ret = OC_STACK_INVALID_PARAM;
@@ -1010,7 +1001,7 @@ static OCStackResult OCParsePresencePayload(OCPayload **outPayload, CborValue *r
         // Resource type name
         err = cbor_value_map_find_value(rootValue, OC_RSRVD_RESOURCE_TYPE, &curVal);
         VERIFY_CBOR_SUCCESS(TAG, err, "to find res type tag");
-        if (cbor_value_is_valid(&curVal))
+        if (cbor_value_is_text_string(&curVal))
         {
             size_t len = 0;
             err = cbor_value_dup_text_string(&curVal, &payload->resourceType, &len, NULL);
@@ -1028,3 +1019,4 @@ exit:
     OCPresencePayloadDestroy(payload);
     return ret;
 }
+#endif // WITH_PRESENCE
index 70f6924..16579f8 100755 (executable)
@@ -49,7 +49,7 @@
 #include "cacommon.h"
 #include "cainterface.h"
 #include "ocpayload.h"
-#include "oickeepalive.h"
+#include "oickeepaliveinternal.h"
 #include "platform_features.h"
 #include "payload_logging.h"
 #ifdef ROUTING_GATEWAY
@@ -418,14 +418,12 @@ static OCStackResult BuildDevicePlatformPayload(const OCResource *resourcePtr, O
 OCStackResult BuildResponseRepresentation(const OCResource *resourcePtr,
                     OCRepPayload** payload, OCDevAddr *devAddr)
 {
-    OCRepPayload *tempPayload = OCRepPayloadCreate();
-
     if (!resourcePtr)
     {
-        OCRepPayloadDestroy(tempPayload);
         return OC_STACK_INVALID_PARAM;
     }
 
+    OCRepPayload *tempPayload = OCRepPayloadCreate();
     if(!tempPayload)
     {
         return OC_STACK_NO_MEMORY;
@@ -438,6 +436,12 @@ OCStackResult BuildResponseRepresentation(const OCResource *resourcePtr,
     {
         size_t rtDim[MAX_REP_ARRAY_DEPTH] = {numElement, 0, 0};
         char **rt = (char **)OICMalloc(sizeof(char *) * numElement);
+        if (!rt)
+        {
+            OIC_LOG(ERROR, TAG, "Resource type allocation failed.");
+            OCRepPayloadDestroy(tempPayload);
+            return OC_STACK_NO_MEMORY;
+        }
         for (uint8_t i = 0; i < numElement; ++i)
         {
             const char *value = OCGetResourceTypeName((OCResource *)resourcePtr, i);
@@ -452,6 +456,12 @@ OCStackResult BuildResponseRepresentation(const OCResource *resourcePtr,
     {
         size_t ifDim[MAX_REP_ARRAY_DEPTH] = {numElement, 0, 0};
         char **itf = (char **)OICMalloc(sizeof(char *) * numElement);
+        if (!itf)
+        {
+            OIC_LOG(ERROR, TAG, "Resource interface allocation failed.");
+            OCRepPayloadDestroy(tempPayload);
+            return OC_STACK_NO_MEMORY;
+        }
         for (uint8_t i = 0; i < numElement; ++i)
         {
             const char *value = OCGetResourceInterfaceName((OCResource *)resourcePtr, i);
@@ -658,9 +668,6 @@ OCStackResult EntityHandlerCodeToOCStackCode(OCEntityHandlerResult ehResult)
         case OC_EH_FORBIDDEN:
             result = OC_STACK_FORBIDDEN_REQ;
             break;
-        case OC_EH_INTERNAL_SERVER_ERROR:
-            result = OC_STACK_INTERNAL_SERVER_ERROR;
-            break;
         case OC_EH_RESOURCE_CREATED:
             result = OC_STACK_RESOURCE_CREATED;
             break;
@@ -673,6 +680,24 @@ OCStackResult EntityHandlerCodeToOCStackCode(OCEntityHandlerResult ehResult)
         case OC_EH_RESOURCE_NOT_FOUND:
             result = OC_STACK_NO_RESOURCE;
             break;
+        case OC_EH_INTERNAL_SERVER_ERROR:
+            result = OC_STACK_INTERNAL_SERVER_ERROR;
+            break;
+        case OC_EH_NOT_IMPLEMENTED:
+            result = OC_STACK_NOT_IMPLEMENTED;
+            break;
+        case OC_EH_BAD_GATEWAY:
+            result = OC_STACK_BAD_GATEWAY;
+            break;
+        case OC_EH_SERVICE_UNAVAILABLE:
+            result = OC_STACK_SERVICE_UNAVAILABLE;
+            break;
+        case OC_EH_RETRANSMIT_TIMEOUT:
+            result = OC_STACK_GATEWAY_TIMEOUT;
+            break;
+        case OC_EH_PROXY_NOT_SUPPORTED:
+            result = OC_STACK_PROXY_NOT_SUPPORTED;
+            break;
         default:
             result = OC_STACK_ERROR;
     }
@@ -687,12 +712,18 @@ static bool resourceMatchesRTFilter(OCResource *resource, char *resourceTypeFilt
         return false;
     }
 
-    // Null or empty is analogous to no filter.
-    if (resourceTypeFilter == NULL || *resourceTypeFilter == 0)
+    // Null is analogous to no filter.
+    if (NULL == resourceTypeFilter)
     {
         return true;
     }
 
+    // Empty resourceType filter is analogous to error query
+    if (0 == strlen(resourceTypeFilter))
+    {
+        return false;
+    }
+
     for (OCResourceType *rtPtr = resource->rsrcType; rtPtr; rtPtr = rtPtr->next)
     {
         if (0 == strcmp(rtPtr->resourcetypename, resourceTypeFilter))
@@ -712,12 +743,18 @@ static bool resourceMatchesIFFilter(OCResource *resource, char *interfaceFilter)
         return false;
     }
 
-    // Null or empty is analogous to no filter.
-    if (interfaceFilter == NULL || *interfaceFilter == 0)
+    // Null is analogous to no filter.
+    if (NULL == interfaceFilter)
     {
         return true;
     }
 
+    // Empty interface filter is analogous to error query
+    if (0 == strlen(interfaceFilter))
+    {
+        return false;
+    }
+
     for (OCResourceInterface *ifPtr = resource->rsrcInterface; ifPtr; ifPtr = ifPtr->next)
     {
         if (0 == strcmp(ifPtr->name, interfaceFilter) ||
@@ -845,7 +882,7 @@ static OCStackResult discoveryPayloadCreateAndAddDeviceId(OCPayload **payload)
 {
     if (*payload)
     {
-        OIC_LOG_V(DEBUG, TAG, "Payload is already allocated");
+        OIC_LOG(DEBUG, TAG, "Payload is already allocated");
         return OC_STACK_OK;
     }
 
@@ -880,10 +917,13 @@ exit:
  */
 static OCStackResult addDiscoveryBaselineCommonProperties(OCDiscoveryPayload *discPayload)
 {
-    discPayload->uri = OICStrdup(OC_RSRVD_WELL_KNOWN_URI);
-    VERIFY_PARAM_NON_NULL(TAG, discPayload->uri, "Failed adding href to discovery payload.");
+    if (!discPayload)
+    {
+        OIC_LOG(ERROR, TAG, "Payload is not allocated");
+        return OC_STACK_ERROR;
+    }
 
-    OCGetPropertyValue(PAYLOAD_TYPE_DEVICE, "deviceName", (void **)&discPayload->name);
+    OCGetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DEVICE_NAME, (void **)&discPayload->name);
 
     discPayload->type = (OCStringLL*)OICCalloc(1, sizeof(OCStringLL));
     VERIFY_PARAM_NON_NULL(TAG, discPayload->type, "Failed adding rt to discovery payload.");
@@ -900,6 +940,14 @@ exit:
     return OC_STACK_NO_MEMORY;
 }
 
+static bool isUnicast(OCServerRequest *request)
+{
+    bool isMulticast = request->devAddr.flags &  OC_MULTICAST;
+    return (isMulticast == false &&
+           (request->devAddr.adapter != OC_ADAPTER_RFCOMM_BTEDR) &&
+           (request->devAddr.adapter != OC_ADAPTER_GATT_BTLE));
+}
+
 static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource* resource)
 {
     if (!request || !resource)
@@ -910,7 +958,6 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource
     OCPayload* payload = NULL;
     char *interfaceQuery = NULL;
     char *resourceTypeQuery = NULL;
-    char *dataModelVersions = NULL;
 
     OIC_LOG(INFO, TAG, "Entering HandleVirtualResource");
 
@@ -921,7 +968,7 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource
     {
         // Received request for a keepalive
         OIC_LOG(INFO, TAG, "Request is for KeepAlive Request");
-        return HandleKeepAliveRequest(request, resource);
+        return OCHandleKeepAliveRequest(request, resource);
     }
 #endif
 
@@ -944,24 +991,19 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource
         discoveryResult = getQueryParamsForFiltering(virtualUriInRequest, request->query,
                 &interfaceQuery, &resourceTypeQuery);
         VERIFY_SUCCESS(discoveryResult);
+
         if (!interfaceQuery && !resourceTypeQuery)
         {
             // If no query is sent, default interface is used i.e. oic.if.ll.
             interfaceQuery = OICStrdup(OC_RSRVD_INTERFACE_LL);
         }
 
-        bool baselineQuery = false;
-        if (interfaceQuery && 0 == strcmp(interfaceQuery, OC_RSRVD_INTERFACE_DEFAULT))
-        {
-            baselineQuery = true;
-        }
-
         discoveryResult = discoveryPayloadCreateAndAddDeviceId(&payload);
         VERIFY_PARAM_NON_NULL(TAG, payload, "Failed creating Discovery Payload.");
         VERIFY_SUCCESS(discoveryResult);
 
         OCDiscoveryPayload *discPayload = (OCDiscoveryPayload *)payload;
-        if (baselineQuery)
+        if (interfaceQuery && 0 == strcmp(interfaceQuery, OC_RSRVD_INTERFACE_DEFAULT))
         {
             discoveryResult = addDiscoveryBaselineCommonProperties(discPayload);
             VERIFY_SUCCESS(discoveryResult);
@@ -972,26 +1014,24 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource
 #endif
         for (; resource && discoveryResult == OC_STACK_OK; resource = resource->next)
         {
-            discoveryResult = OC_STACK_NO_RESOURCE;
-#ifdef RD_SERVER
-            discoveryResult = findResourceAtRD(resource, interfaceQuery, resourceTypeQuery,
-                discPayload);
-#endif
-            if (OC_STACK_NO_RESOURCE == discoveryResult)
+            // This case will handle when no resource type and it is oic.if.ll.
+            // Do not assume check if the query is ll
+            if (!resourceTypeQuery &&
+                (interfaceQuery && 0 == strcmp(interfaceQuery, OC_RSRVD_INTERFACE_LL)))
             {
-                // This case will handle when no resource type and it is oic.if.ll.
-                if (!resourceTypeQuery && !baselineQuery && (resource->resourceProperties & prop))
+                // Only include discoverable type
+                if (resource->resourceProperties & prop)
                 {
                     discoveryResult = BuildVirtualResourceResponse(resource, discPayload, &request->devAddr);
                 }
-                else if (includeThisResourceInResponse(resource, interfaceQuery, resourceTypeQuery))
-                {
-                    discoveryResult = BuildVirtualResourceResponse(resource, discPayload, &request->devAddr);
-                }
-                else
-                {
-                    discoveryResult = OC_STACK_OK;
-                }
+            }
+            else if (includeThisResourceInResponse(resource, interfaceQuery, resourceTypeQuery))
+            {
+                discoveryResult = BuildVirtualResourceResponse(resource, discPayload, &request->devAddr);
+            }
+            else
+            {
+                discoveryResult = OC_STACK_OK;
             }
         }
         if (discPayload->resources == NULL)
@@ -1061,25 +1101,28 @@ static OCStackResult HandleVirtualResource (OCServerRequest *request, OCResource
         OIC_LOG_PAYLOAD(DEBUG, payload);
         if(discoveryResult == OC_STACK_OK)
         {
+
             SendNonPersistantDiscoveryResponse(request, resource, payload, OC_EH_OK);
         }
-        else if(((request->devAddr.flags &  OC_MULTICAST) == false) &&
-            (request->devAddr.adapter != OC_ADAPTER_RFCOMM_BTEDR) &&
-            (request->devAddr.adapter != OC_ADAPTER_GATT_BTLE))
+        else // Error handling
         {
-            OIC_LOG_V(ERROR, TAG, "Sending a (%d) error to (%d) discovery request",
-                discoveryResult, virtualUriInRequest);
-            SendNonPersistantDiscoveryResponse(request, resource, NULL,
-                (discoveryResult == OC_STACK_NO_RESOURCE) ?
+            if (isUnicast(request))
+            {
+                OIC_LOG_V(ERROR, TAG, "Sending a (%d) error to (%d) discovery request",
+                    discoveryResult, virtualUriInRequest);
+                SendNonPersistantDiscoveryResponse(request, resource, NULL,
+                    (discoveryResult == OC_STACK_NO_RESOURCE) ?
                         OC_EH_RESOURCE_NOT_FOUND : OC_EH_ERROR);
-        }
-        else
-        {
-            // Ignoring the discovery request as per RFC 7252, Section #8.2
-            OIC_LOG(INFO, TAG, "Silently ignoring the request since no useful data to send.");
-            // the request should be removed.
-            // since it never remove and causes a big memory waste.
-            FindAndDeleteServerRequest(request);
+            }
+            else // Multicast
+            {
+                // Ignoring the discovery request as per RFC 7252, Section #8.2
+                OIC_LOG(INFO, TAG, "Silently ignoring the request since no useful data to send.");
+                // the request should be removed.
+                // since it never remove and causes a big memory waste.
+                FindAndDeleteServerRequest(request);
+            }
+            discoveryResult = OC_STACK_CONTINUE;
         }
     }
 
@@ -1094,10 +1137,8 @@ exit:
         OICFree(resourceTypeQuery);
     }
     OCPayloadDestroy(payload);
-    if (dataModelVersions)
-    {
-        OICFree(dataModelVersions);
-    }
+
+    // To ignore the message, OC_STACK_CONTINUE is sent
     return discoveryResult;
 }
 
@@ -1230,7 +1271,7 @@ HandleResourceWithEntityHandler(OCServerRequest *request,
         {
             // Stack does not contain this observation request
             // Either token is incorrect or observation list is corrupted
-            result = OC_STACK_ERROR;
+            result = OC_STACK_NO_RESOURCE;
             goto exit;
         }
         ehRequest.obsInfo.obsId = resObs->observeId;
@@ -1436,7 +1477,9 @@ OCStackResult OCSetDeviceInfo(OCDeviceInfo info)
     {
         dataModelVersion = OCCreateOCStringLL(OC_DATA_MODEL_VERSION);
         VERIFY_SUCCESS(OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DATA_MODEL_VERSION, dataModelVersion));
+#ifdef __TIZENRT__
         OCFreeOCStringLL(dataModelVersion);
+#endif
     }
     OIC_LOG(INFO, TAG, "Device parameter initialized successfully.");
     return OC_STACK_OK;
@@ -1507,7 +1550,7 @@ OCStackResult OCGetPropertyValue(OCPayloadType type, const char *prop, void **va
 OCStackResult OCSetAttribute(OCResource* resource, const char* attribute, const void* value)
 {
     // See if the attribute already exists in the list.
-    OCAttribute *resAttrib = NULL;
+    OCAttribute *resAttrib;
     for (resAttrib = resource->rsrcAttributes; resAttrib; resAttrib = resAttrib->next)
     {
         if (0 == strcmp(attribute, resAttrib->attrName))
index 39290d3..46afb69 100644 (file)
@@ -211,7 +211,7 @@ OCServerRequest * GetServerRequestUsingToken (const CAToken_t token, uint8_t tok
             return out;
         }
     }
-    OIC_LOG(ERROR, TAG, "Server Request not found!!");
+    OIC_LOG(INFO, TAG, "Server Request not found!!");
     return NULL;
 }
 
@@ -254,7 +254,7 @@ OCServerResponse * GetServerResponseUsingHandle (const OCRequestHandle handle)
             return out;
         }
     }
-    OIC_LOG(ERROR, TAG, "Server Response not found!!");
+    OIC_LOG(INFO, TAG, "Server Response not found!!");
     return NULL;
 }
 
@@ -480,9 +480,21 @@ CAResponseResult_t ConvertEHResultToCAResult (OCEntityHandlerResult result, OCMe
         case OC_EH_INTERNAL_SERVER_ERROR: // 5.00
             caResult = CA_INTERNAL_SERVER_ERROR;
             break;
+        case OC_EH_NOT_IMPLEMENTED: // 5.01
+            caResult = CA_NOT_IMPLEMENTED;
+            break;
+        case OC_EH_BAD_GATEWAY: // 5.02
+            caResult = CA_BAD_GATEWAY;
+            break;
+        case OC_EH_SERVICE_UNAVAILABLE: // 5.03
+            caResult = CA_SERVICE_UNAVAILABLE;
+            break;
         case OC_EH_RETRANSMIT_TIMEOUT: // 5.04
             caResult = CA_RETRANSMIT_TIMEOUT;
             break;
+        case OC_EH_PROXY_NOT_SUPPORTED: // 5.05
+            caResult = CA_PROXY_NOT_SUPPORTED;
+            break;
         default:
             caResult = CA_BAD_REQ;
             break;
@@ -627,11 +639,13 @@ OCStackResult HandleSingleResponse(OCEntityHandlerResponse * ehResponse)
     // Put the JSON prefix and suffix around the payload
     if(ehResponse->payload)
     {
+#ifdef WITH_PRESENCE
         if (ehResponse->payload->type == PAYLOAD_TYPE_PRESENCE)
         {
             responseInfo.isMulticast = true;
         }
         else
+#endif
         {
             responseInfo.isMulticast = false;
         }
index 277cd6e..c603445 100644 (file)
 #include "oic_malloc.h"
 #include "oic_string.h"
 #include "logger.h"
+#include "trace.h"
 #include "ocserverrequest.h"
 #include "secureresourcemanager.h"
 #include "psinterface.h"
+#include "psiutils.h"
 #include "doxmresource.h"
 #include "cacommon.h"
 #include "cainterface.h"
@@ -69,7 +71,7 @@
 #endif
 
 #ifdef TCP_ADAPTER
-#include "oickeepalive.h"
+#include "oickeepaliveinternal.h"
 #endif
 
 //#ifdef DIRECT_PAIRING
@@ -110,6 +112,14 @@ typedef enum
 } OCPresenceState;
 #endif
 
+#if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
+typedef struct
+{
+    OCOtmEventHandler cb;
+    void *ctx;
+} OCOtmEventHandler_t;
+#endif
+
 //-----------------------------------------------------------------------------
 // Private variables
 //-----------------------------------------------------------------------------
@@ -144,6 +154,10 @@ static const char CORESPEC[] = "core";
 CAAdapterStateChangedCB g_adapterHandler = NULL;
 CAConnectionStateChangedCB g_connectionHandler = NULL;
 
+#if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
+static OCOtmEventHandler_t g_otmEventHandler = {NULL, NULL};
+#endif
+
 //-----------------------------------------------------------------------------
 // Macros
 //-----------------------------------------------------------------------------
@@ -258,6 +272,13 @@ static void deleteResourceType(OCResourceType *resourceType);
 static void deleteResourceInterface(OCResourceInterface *resourceInterface);
 
 /**
+ * Delete all child resources.
+ *
+ * @param resourceChild Specified binded resource is deleted from parent.
+ */
+static void deleteResourceChild(OCChildResource *resourceChild);
+
+/**
  * Delete all of the dynamically allocated elements that were created for the resource.
  *
  * @param resource Specified resource.
@@ -291,10 +312,10 @@ static void incrementSequenceNumber(OCResource * resPtr);
  *
  * Note: At least one interface must succeed to initialize. If all calls to @ref CASelectNetwork
  * return something other than @ref CA_STATUS_OK, then this function fails.
- *
+ * @param transportType  OCTransportAdapter value to select.
  * @return ::CA_STATUS_OK on success, some other value upon failure.
  */
-static CAResult_t OCSelectNetwork();
+static CAResult_t OCSelectNetwork(OCTransportAdapter transportType);
 
 /**
  * Convert CAResponseResult_t to OCStackResult.
@@ -370,6 +391,7 @@ static OCStackResult getQueryFromUri(const char * uri, char** resourceType, char
 static OCResourceType *findResourceType(OCResourceType * resourceTypeList,
         const char * resourceTypeName);
 
+#ifdef WITH_PRESENCE
 /**
  * Reset presence TTL for a ClientCB struct. ttlLevel will be set to 0.
  * TTL will be set to maxAge.
@@ -380,6 +402,7 @@ static OCResourceType *findResourceType(OCResourceType * resourceTypeList,
  * @return ::OC_STACK_OK on success, some other value upon failure.
  */
 static OCStackResult ResetPresenceTTL(ClientCB *cbNode, uint32_t maxAgeSeconds);
+#endif
 
 /**
  * Ensure the accept header option is set appropriatly before sending the requests and routing
@@ -484,6 +507,7 @@ void CopyDevAddrToEndpoint(const OCDevAddr *in, CAEndpoint_t *out)
     out->adapter = (CATransportAdapter_t)in->adapter;
     out->flags = OCToCATransportFlags(in->flags);
     OICStrcpy(out->addr, sizeof(out->addr), in->addr);
+    OICStrcpy(out->remoteId, sizeof(out->remoteId), in->remoteId);
 #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP)
     /* This assert is to prevent accidental mismatch between address size macros defined in
      * RI and CA and cause crash here. */
@@ -508,12 +532,14 @@ static OCStackResult OCSendRequest(const CAEndpoint_t *object, CARequestInfo_t *
 {
     VERIFY_NON_NULL(object, FATAL, OC_STACK_INVALID_PARAM);
     VERIFY_NON_NULL(requestInfo, FATAL, OC_STACK_INVALID_PARAM);
+    OIC_TRACE_BEGIN(%s:OCSendRequest, TAG);
 
 #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP)
     OCStackResult rmResult = RMAddInfo(object->routeData, requestInfo, true, NULL);
     if (OC_STACK_OK != rmResult)
     {
         OIC_LOG(ERROR, TAG, "Add destination option failed");
+        OIC_TRACE_END();
         return rmResult;
     }
 #endif
@@ -524,8 +550,11 @@ static OCStackResult OCSendRequest(const CAEndpoint_t *object, CARequestInfo_t *
     if(CA_STATUS_OK != result)
     {
         OIC_LOG_V(ERROR, TAG, "CASendRequest failed with CA error %u", result);
+        OIC_TRACE_END();
         return CAResultToOCResult(result);
     }
+
+    OIC_TRACE_END();
     return OC_STACK_OK;
 }
 //-----------------------------------------------------------------------------
@@ -683,18 +712,36 @@ OCStackResult CAResponseToOCStackResult(CAResponseResult_t caCode)
         case CA_NOT_FOUND:
             ret = OC_STACK_NO_RESOURCE;
             break;
-        case CA_RETRANSMIT_TIMEOUT:
-            ret = OC_STACK_COMM_ERROR;
-            break;
         case CA_REQUEST_ENTITY_TOO_LARGE:
             ret = OC_STACK_TOO_LARGE_REQ;
             break;
+        case CA_METHOD_NOT_ALLOWED:
+            ret = OC_STACK_METHOD_NOT_ALLOWED;
+            break;
+        case CA_NOT_ACCEPTABLE:
+            ret = OC_STACK_NOT_ACCEPTABLE;
+            break;
         case CA_FORBIDDEN_REQ:
             ret = OC_STACK_FORBIDDEN_REQ;
             break;
         case CA_INTERNAL_SERVER_ERROR:
             ret = OC_STACK_INTERNAL_SERVER_ERROR;
             break;
+        case CA_NOT_IMPLEMENTED:
+            ret = OC_STACK_NOT_IMPLEMENTED;
+            break;
+        case CA_BAD_GATEWAY:
+            ret = OC_STACK_BAD_GATEWAY;
+            break;
+        case CA_SERVICE_UNAVAILABLE:
+            ret = OC_STACK_SERVICE_UNAVAILABLE;
+            break;
+        case CA_RETRANSMIT_TIMEOUT:
+            ret = OC_STACK_GATEWAY_TIMEOUT;
+            break;
+        case CA_PROXY_NOT_SUPPORTED:
+            ret = OC_STACK_PROXY_NOT_SUPPORTED;
+            break;
         default:
             break;
     }
@@ -750,6 +797,12 @@ CAResponseResult_t OCToCAStackResult(OCStackResult ocCode, OCMethod method)
         case OC_STACK_COMM_ERROR:
             ret = CA_RETRANSMIT_TIMEOUT;
             break;
+        case OC_STACK_METHOD_NOT_ALLOWED:
+            ret = CA_METHOD_NOT_ALLOWED;
+            break;
+        case OC_STACK_NOT_ACCEPTABLE:
+            ret = CA_NOT_ACCEPTABLE;
+            break;
         case OC_STACK_UNAUTHORIZED_REQ:
             ret = CA_UNAUTHORIZED_REQ;
             break;
@@ -759,6 +812,21 @@ CAResponseResult_t OCToCAStackResult(OCStackResult ocCode, OCMethod method)
         case OC_STACK_INTERNAL_SERVER_ERROR:
             ret = CA_INTERNAL_SERVER_ERROR;
             break;
+        case OC_STACK_NOT_IMPLEMENTED:
+            ret = CA_NOT_IMPLEMENTED;
+            break;
+        case OC_STACK_BAD_GATEWAY:
+            ret = CA_BAD_GATEWAY;
+            break;
+        case OC_STACK_SERVICE_UNAVAILABLE:
+            ret = CA_SERVICE_UNAVAILABLE;
+            break;
+        case OC_STACK_GATEWAY_TIMEOUT:
+            ret = CA_RETRANSMIT_TIMEOUT;
+            break;
+        case OC_STACK_PROXY_NOT_SUPPORTED:
+            ret = CA_PROXY_NOT_SUPPORTED;
+            break;
         default:
             break;
     }
@@ -786,6 +854,7 @@ OCTransportFlags CAToOCTransportFlags(CATransportFlags_t caFlags)
     return (OCTransportFlags)caFlags;
 }
 
+#ifdef WITH_PRESENCE
 static OCStackResult ResetPresenceTTL(ClientCB *cbNode, uint32_t maxAgeSeconds)
 {
     uint32_t lowerBound  = 0;
@@ -875,6 +944,7 @@ OCPresenceTrigger convertTriggerStringToEnum(const char * triggerStr)
         return OC_PRESENCE_TRIGGER_DELETE;
     }
 }
+#endif // WITH_PRESENCE
 
 OCStackResult OCEncodeAddressForRFC6874(char *outputAddress,
                                         size_t outputSize,
@@ -939,8 +1009,8 @@ OCStackResult OCEncodeAddressForRFC6874(char *outputAddress,
 
     // Restore the null terminator with an escaped '%' character, per RFC 6874
     OICStrcpy(outputAddress, scopeIdPart - addressPart, addressPart);
-    strcat(outputAddress, "%25");
-    strcat(outputAddress, scopeIdPart);
+    OICStrcat(outputAddress, outputSize, "%25");
+    OICStrcat(outputAddress, outputSize, scopeIdPart);
 
     return OC_STACK_OK;
 }
@@ -980,6 +1050,7 @@ OCStackResult OCDecodeAddressForRFC6874(char *outputAddress,
     return OC_STACK_OK;
 }
 
+#ifdef WITH_PRESENCE
 /**
  * The cononical presence allows constructed URIs to be string compared.
  *
@@ -1101,7 +1172,7 @@ OCStackResult HandlePresenceResponse(const CAEndpoint_t *endpoint,
     {
         return OC_STACK_INVALID_URI;
     }
-    OIC_LOG(ERROR, TAG, "check for unicast presence");
+    OIC_LOG(INFO, TAG, "check for unicast presence");
     cbNode = GetClientCB(NULL, 0, NULL, presenceUri);
     if (cbNode)
     {
@@ -1110,7 +1181,7 @@ OCStackResult HandlePresenceResponse(const CAEndpoint_t *endpoint,
     else
     {
         // check for multicast presence
-        OIC_LOG(ERROR, TAG, "check for multicast presence");
+        OIC_LOG(INFO, TAG, "check for multicast presence");
         cbNode = GetClientCB(NULL, 0, NULL, OC_RSRVD_PRESENCE_URI);
         if (cbNode)
         {
@@ -1120,7 +1191,8 @@ OCStackResult HandlePresenceResponse(const CAEndpoint_t *endpoint,
 
     if (!presenceSubscribe && !multicastPresenceSubscribe)
     {
-        OIC_LOG(ERROR, TAG, "Received a presence notification, but no callback, ignoring");
+        OIC_LOG(INFO, TAG, "Received a presence notification, "
+                "but need to register presence callback, ignoring");
         goto exit;
     }
 
@@ -1210,17 +1282,59 @@ exit:
     OCPayloadDestroy(response.payload);
     return result;
 }
+#endif // WITH_PRESENCE
+
+OCStackResult HandleBatchResponse(char *requestUri, OCRepPayload **payload)
+{
+    if (requestUri && *payload)
+    {
+        char *interfaceName = NULL;
+        char *rtTypeName = NULL;
+        char *uriQuery = NULL;
+        char *uriWithoutQuery = NULL;
+        if (OC_STACK_OK == getQueryFromUri(requestUri, &uriQuery, &uriWithoutQuery))
+        {
+            if (OC_STACK_OK == ExtractFiltersFromQuery(uriQuery, &interfaceName, &rtTypeName))
+            {
+                if (interfaceName && (0 == strcmp(OC_RSRVD_INTERFACE_BATCH, interfaceName)))
+                {
+                    char *uri = (*payload)->uri;
+                    if (uri && 0 != strcmp(uriWithoutQuery, uri))
+                    {
+                        OCRepPayload *newPayload = OCRepPayloadCreate();
+                        if (newPayload)
+                        {
+                            OCRepPayloadSetUri(newPayload, uri);
+                            newPayload->next = *payload;
+                            *payload = newPayload;
+                        }
+                    }
+                }
+            }
+        }
+
+        OICFree(interfaceName);
+        OICFree(rtTypeName);
+        OICFree(uriQuery);
+        OICFree(uriWithoutQuery);
+        return OC_STACK_OK;
+    }
+    return OC_STACK_INVALID_PARAM;
+}
 
 void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* responseInfo)
 {
+    OIC_TRACE_MARK(%s:OCHandleResponse:%s, TAG, responseInfo->info.resourceUri);
     OIC_LOG(DEBUG, TAG, "Enter OCHandleResponse");
 
+#ifdef WITH_PRESENCE
     if(responseInfo->info.resourceUri &&
         strcmp(responseInfo->info.resourceUri, OC_RSRVD_PRESENCE_URI) == 0)
     {
         HandlePresenceResponse(endPoint, responseInfo);
         return;
     }
+#endif
 
     ClientCB *cbNode = GetClientCB(responseInfo->info.token,
             responseInfo->info.tokenLength, NULL, NULL);
@@ -1231,6 +1345,20 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp
     if(cbNode)
     {
         OIC_LOG(INFO, TAG, "There is a cbNode associated with the response token");
+#ifdef __TIZENRT__
+        // check obs header option
+        bool obsHeaderOpt = false;
+        CAHeaderOption_t *options = responseInfo->info.options;
+        for (uint8_t i = 0; i< responseInfo->info.numOptions; i++)
+        {
+            if (options && options[i].protocolID == CA_COAP_ID &&
+                           options[i].optionID == COAP_OPTION_OBSERVE)
+            {
+                obsHeaderOpt = true;
+                break;
+            }
+        }
+#endif
         if(responseInfo->result == CA_EMPTY)
         {
             OIC_LOG(INFO, TAG, "Receiving A ACK/RESET for this token");
@@ -1252,7 +1380,7 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp
                 {.devAddr = {.adapter = OC_DEFAULT_ADAPTER}};
             CopyEndpointToDevAddr(endPoint, &response.devAddr);
             FixUpClientResponse(&response);
-            response.resourceUri = responseInfo->info.resourceUri;
+            response.resourceUri = OICStrdup(responseInfo->info.resourceUri);
             memcpy(response.identity.id, responseInfo->info.identity.id,
                                                 sizeof (response.identity.id));
             response.identity.id_length = responseInfo->info.identity.id_length;
@@ -1261,18 +1389,42 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp
             cbNode->callBack(cbNode->context,
                     cbNode->handle, &response);
             FindAndDeleteClientCB(cbNode);
+            OICFree(response.resourceUri);
+        }
+#ifdef __TIZENRT__
+        else if ((cbNode->method == OC_REST_OBSERVE || cbNode->method == OC_REST_OBSERVE_ALL)
+                && (responseInfo->result == CA_CONTENT) && !obsHeaderOpt)
+        {
+            OCClientResponse response =
+                {.devAddr = {.adapter = OC_DEFAULT_ADAPTER}};
+            CopyEndpointToDevAddr(endPoint, &response.devAddr);
+            FixUpClientResponse(&response);
+            response.resourceUri =  OICStrdup(responseInfo->info.resourceUri);
+            memcpy(response.identity.id, responseInfo->info.identity.id,
+                                    sizeof (response.identity.id));
+            response.identity.id_length = responseInfo->info.identity.id_length;
+            response.result = OC_STACK_UNAUTHORIZED_REQ;
+
+            cbNode->callBack(cbNode->context,
+                             cbNode->handle,
+                             &response);
+            FindAndDeleteClientCB(cbNode);
+            OICFree(response.resourceUri);
         }
+#endif
         else
         {
             OIC_LOG(INFO, TAG, "This is a regular response, A client call back is found");
             OIC_LOG(INFO, TAG, "Calling into application address space");
 
-            OCClientResponse response =
-                {.devAddr = {.adapter = OC_DEFAULT_ADAPTER}};
+            OCClientResponse response;
+            memset(&response, 0, sizeof(OCClientResponse));
+            response.devAddr.adapter = OC_DEFAULT_ADAPTER;
+
             response.sequenceNumber = MAX_SEQUENCE_NUMBER + 1;
             CopyEndpointToDevAddr(endPoint, &response.devAddr);
             FixUpClientResponse(&response);
-            response.resourceUri = responseInfo->info.resourceUri;
+            response.resourceUri = OICStrdup(responseInfo->info.resourceUri);
             memcpy(response.identity.id, responseInfo->info.identity.id,
                                                 sizeof (response.identity.id));
             response.identity.id_length = responseInfo->info.identity.id_length;
@@ -1330,6 +1482,7 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp
                     {
                         OIC_LOG_V(ERROR, TAG, "Unknown Payload type in Discovery: %d %s",
                                 cbNode->method, cbNode->requestUri);
+                        OICFree(response.resourceUri);
                         return;
                     }
                 }
@@ -1367,17 +1520,27 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp
                 {
                     OIC_LOG_V(ERROR, TAG, "Unknown Payload type: %d %s",
                             cbNode->method, cbNode->requestUri);
+                    OICFree(response.resourceUri);
                     return;
                 }
 
-                if(OC_STACK_OK != OCParsePayload(&response.payload,
+                // In case of error, still want application to receive the error message.
+                if (OCResultToSuccess(response.result) || PAYLOAD_TYPE_REPRESENTATION == type)
+                {
+                    if(OC_STACK_OK != OCParsePayload(&response.payload,
                             type,
                             responseInfo->info.payload,
                             responseInfo->info.payloadSize))
+                    {
+                        OIC_LOG(ERROR, TAG, "Error converting payload");
+                        OCPayloadDestroy(response.payload);
+                        OICFree(response.resourceUri);
+                        return;
+                    }
+                }
+                else
                 {
-                    OIC_LOG(ERROR, TAG, "Error converting payload");
-                    OCPayloadDestroy(response.payload);
-                    return;
+                    response.resourceUri = OICStrdup(cbNode->requestUri);
                 }
             }
 
@@ -1412,6 +1575,7 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp
                 {
                     OIC_LOG(ERROR, TAG, "#header options are more than MAX_HEADER_OPTIONS");
                     OCPayloadDestroy(response.payload);
+                    OICFree(response.resourceUri);
                     return;
                 }
 
@@ -1436,13 +1600,52 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp
             else
             {
 #ifdef RD_CLIENT
-                // if request uri is '/oic/rd', update ins value of resource.
-                char *targetUri = strstr(cbNode->requestUri, OC_RSRVD_RD_URI);
-                if (targetUri)
+                if (cbNode->requestUri)
+                {
+                    // if request uri is '/oic/rd', update ins value of resource.
+                    char *targetUri = strstr(cbNode->requestUri, OC_RSRVD_RD_URI);
+                    if (targetUri)
+                    {
+                        OCUpdateResourceInsWithResponse(cbNode->requestUri, &response);
+                    }
+                }
+#endif
+                // set remoteID(device ID) into OCClientResponse callback parameter
+                if (OC_REST_DISCOVER == cbNode->method)
                 {
-                    OCUpdateResourceInsWithResponse(cbNode->requestUri, &response);
+                    OIC_LOG(INFO, TAG, "cbNode method is OC_REST_DISCOVER");
+                    OCDiscoveryPayload *payload = (OCDiscoveryPayload*) response.payload;
+                    // Payload can be empty in case of error message.
+                    if (payload && payload->sid)
+                    {
+                        OICStrcpy(response.devAddr.remoteId, sizeof(response.devAddr.remoteId),
+                                  payload->sid);
+                        OIC_LOG_V(INFO_PRIVATE, TAG, "Device ID of response : %s",
+                                  response.devAddr.remoteId);
+                    }
+
+                    if(NULL == response.resourceUri)
+                    {
+                        response.resourceUri = OICStrdup(cbNode->requestUri);
+                    }
+                }
+#ifdef TCP_ADAPTER
+                if (cbNode->requestUri)
+                {
+                    OIC_LOG_V(INFO, TAG, "cbNode requestUri is %s", cbNode->requestUri);
+                    if (cbNode->method == OC_REST_POST &&
+                            strcmp(cbNode->requestUri, OC_RSRVD_KEEPALIVE_URI) == 0)
+                    {
+                        OCHandleKeepAliveResponse(endPoint, response.payload);
+                    }
                 }
 #endif
+                if (response.payload && response.payload->type == PAYLOAD_TYPE_REPRESENTATION)
+                {
+                    OIC_LOG(INFO, TAG, "Handle batch response");
+                    HandleBatchResponse(cbNode->requestUri, (OCRepPayload **)&response.payload);
+                }
+
                 OCStackApplicationResult appFeedback = cbNode->callBack(cbNode->context,
                                                                         cbNode->handle,
                                                                         &response);
@@ -1463,10 +1666,15 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp
             //Need to send ACK when the response is CON
             if(responseInfo->info.type == CA_MSG_CONFIRM)
             {
-                SendDirectStackResponse(endPoint, responseInfo->info.messageId, CA_EMPTY,
+                if (!(endPoint->adapter & CA_ADAPTER_TCP))
+                {
+                    OIC_LOG(INFO, TAG, "Received a confirmable message. Sending EMPTY");
+                    SendDirectStackResponse(endPoint, responseInfo->info.messageId, CA_EMPTY,
                         CA_MSG_ACKNOWLEDGE, 0, NULL, NULL, 0, NULL, CA_RESPONSE_FOR_RES);
+                }
             }
 
+            OICFree(response.resourceUri);
             OCPayloadDestroy(response.payload);
         }
         return;
@@ -1512,9 +1720,13 @@ void OCHandleResponse(const CAEndpoint_t* endPoint, const CAResponseInfo_t* resp
             }
             else
             {
-                OIC_LOG(INFO, TAG, "Received a message without callbacks. Sending RESET");
-                SendDirectStackResponse(endPoint, responseInfo->info.messageId, CA_EMPTY,
-                                        CA_MSG_RESET, 0, NULL, NULL, 0, NULL, CA_RESPONSE_FOR_RES);
+                if (!(endPoint->adapter & CA_ADAPTER_TCP))
+                {
+                    OIC_LOG(INFO, TAG, "Received a message without callbacks. Sending RESET");
+                    SendDirectStackResponse(endPoint, responseInfo->info.messageId, CA_EMPTY,
+                                            CA_MSG_RESET, 0, NULL, NULL, 0, NULL,
+                                            CA_RESPONSE_FOR_RES);
+                }
             }
         }
 
@@ -1544,6 +1756,7 @@ void HandleCAResponses(const CAEndpoint_t* endPoint, const CAResponseInfo_t* res
     VERIFY_NON_NULL_NR(responseInfo, FATAL);
 
     OIC_LOG(INFO, TAG, "Enter HandleCAResponses");
+    OIC_TRACE_BEGIN(%s:HandleCAResponses, TAG);
 
 #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP)
 #ifdef ROUTING_GATEWAY
@@ -1559,6 +1772,7 @@ void HandleCAResponses(const CAEndpoint_t* endPoint, const CAResponseInfo_t* res
     if(ret != OC_STACK_OK || !needRIHandling)
     {
         OIC_LOG_V(INFO, TAG, "Routing status![%d]. Not forwarding to RI", ret);
+        OIC_TRACE_END();
         return;
     }
 #endif
@@ -1574,7 +1788,7 @@ void HandleCAResponses(const CAEndpoint_t* endPoint, const CAResponseInfo_t* res
 #endif
 
     OCHandleResponse(endPoint, responseInfo);
-
+    OIC_TRACE_END();
     OIC_LOG(INFO, TAG, "Exit HandleCAResponses");
 }
 
@@ -1588,6 +1802,7 @@ void HandleCAErrorResponse(const CAEndpoint_t *endPoint, const CAErrorInfo_t *er
     VERIFY_NON_NULL_NR(errorInfo, FATAL);
 
     OIC_LOG(INFO, TAG, "Enter HandleCAErrorResponse");
+    OIC_TRACE_BEGIN(%s:HandleCAErrorResponse, TAG);
 
     ClientCB *cbNode = GetClientCB(errorInfo->info.token,
                                    errorInfo->info.tokenLength, NULL, NULL);
@@ -1619,6 +1834,7 @@ void HandleCAErrorResponse(const CAEndpoint_t *endPoint, const CAErrorInfo_t *er
     }
 
     OIC_LOG(INFO, TAG, "Exit HandleCAErrorResponse");
+    OIC_TRACE_END();
 }
 
 /*
@@ -1633,9 +1849,14 @@ OCStackResult SendDirectStackResponse(const CAEndpoint_t* endPoint, const uint16
         CADataType_t dataType)
 {
     OIC_LOG(DEBUG, TAG, "Entering SendDirectStackResponse");
-    CAResponseInfo_t respInfo = {
-        .result = responseResult
-    };
+
+    if (endPoint->flags & CA_MULTICAST)
+    {
+        OIC_LOG(ERROR, TAG, "It is unnecessary to respond to a multicast request");
+        return OC_STACK_OK;
+    }
+
+    CAResponseInfo_t respInfo = { .result = responseResult };
     respInfo.info.messageId = coapID;
     respInfo.info.numOptions = numOptions;
 
@@ -1795,6 +2016,7 @@ OCStackResult HandleStackRequests(OCServerProtocolRequest * protocolRequest)
 
 void OCHandleRequests(const CAEndpoint_t* endPoint, const CARequestInfo_t* requestInfo)
 {
+    OIC_TRACE_MARK(%s:OCHandleRequests:%s, TAG, requestInfo->info.resourceUri);
     OIC_LOG(DEBUG, TAG, "Enter OCHandleRequests");
 
     OCStackResult requestResult = OC_STACK_ERROR;
@@ -1983,11 +2205,25 @@ void OCHandleRequests(const CAEndpoint_t* endPoint, const CARequestInfo_t* reque
                                     CA_RESPONSE_DATA);
         }
     }
+#ifndef __TIZENRT__
     if (requestResult == OC_STACK_RESOURCE_ERROR
             && serverRequest.observationOption == OC_OBSERVE_REGISTER)
     {
         OIC_LOG_V(ERROR, TAG, "Observe Registration failed due to resource error");
     }
+#else
+    if (serverRequest.observationOption == OC_OBSERVE_REGISTER)
+    {
+        if (requestResult == OC_STACK_RESOURCE_ERROR)
+        {
+            OIC_LOG_V(ERROR, TAG, "Observe Registration failed due to resource error");
+        }
+        else if (!OCResultToSuccess(requestResult))
+        {
+            DeleteObserverUsingToken(requestInfo->info.token, requestInfo->info.tokenLength);
+        }
+    }
+#endif
     else if(!OCResultToSuccess(requestResult))
     {
         OIC_LOG_V(ERROR, TAG, "HandleStackRequests failed. error: %d", requestResult);
@@ -2012,15 +2248,18 @@ void OCHandleRequests(const CAEndpoint_t* endPoint, const CARequestInfo_t* reque
 void HandleCARequests(const CAEndpoint_t* endPoint, const CARequestInfo_t* requestInfo)
 {
     OIC_LOG(INFO, TAG, "Enter HandleCARequests");
+    OIC_TRACE_BEGIN(%s:HandleCARequests, TAG);
     if(!endPoint)
     {
         OIC_LOG(ERROR, TAG, "endPoint is NULL");
+        OIC_TRACE_END();
         return;
     }
 
     if(!requestInfo)
     {
         OIC_LOG(ERROR, TAG, "requestInfo is NULL");
+        OIC_TRACE_END();
         return;
     }
 
@@ -2040,6 +2279,7 @@ void HandleCARequests(const CAEndpoint_t* endPoint, const CARequestInfo_t* reque
     if(OC_STACK_OK != ret || !needRIHandling)
     {
         OIC_LOG_V(INFO, TAG, "Routing status![%d]. Not forwarding to RI", ret);
+        OIC_TRACE_END();
         return;
     }
 #endif
@@ -2075,6 +2315,7 @@ void HandleCARequests(const CAEndpoint_t* endPoint, const CARequestInfo_t* reque
         OCHandleRequests(endPoint, requestInfo);
     }
     OIC_LOG(INFO, TAG, "Exit HandleCARequests");
+    OIC_TRACE_END();
 }
 
 //-----------------------------------------------------------------------------
@@ -2107,6 +2348,13 @@ OCStackResult OCInit(const char *ipAddr, uint16_t port, OCMode mode)
 
 OCStackResult OCInit1(OCMode mode, OCTransportFlags serverFlags, OCTransportFlags clientFlags)
 {
+    OIC_LOG(DEBUG, TAG, "call OCInit1");
+    return OCInit2(mode, OC_DEFAULT_FLAGS, OC_DEFAULT_FLAGS, OC_DEFAULT_ADAPTER);
+}
+
+OCStackResult OCInit2(OCMode mode, OCTransportFlags serverFlags, OCTransportFlags clientFlags,
+                      OCTransportAdapter transportType)
+{
     if(stackState == OC_STACK_INITIALIZED)
     {
         OIC_LOG(INFO, TAG, "Subsequent calls to OCInit() without calling \
@@ -2168,10 +2416,10 @@ OCStackResult OCInit1(OCMode mode, OCTransportFlags serverFlags, OCTransportFlag
     result = InitializeScheduleResourceList();
     VERIFY_SUCCESS(result, OC_STACK_OK);
 
-    result = CAResultToOCResult(CAInitialize());
+    result = CAResultToOCResult(CAInitialize((CATransportAdapter_t)transportType));
     VERIFY_SUCCESS(result, OC_STACK_OK);
 
-    result = CAResultToOCResult(OCSelectNetwork());
+    result = CAResultToOCResult(OCSelectNetwork(transportType));
     VERIFY_SUCCESS(result, OC_STACK_OK);
 
     result = CAResultToOCResult(CARegisterNetworkMonitorHandler(
@@ -2203,7 +2451,7 @@ OCStackResult OCInit1(OCMode mode, OCTransportFlags serverFlags, OCTransportFlag
     VERIFY_SUCCESS(result, OC_STACK_OK);
 
 #ifdef TCP_ADAPTER
-    CARegisterKeepAliveHandler(HandleKeepAliveConnCB);
+    CARegisterKeepAliveHandler(OCHandleKeepAliveConnCB);
 #endif
 
 #ifdef WITH_PRESENCE
@@ -2238,7 +2486,7 @@ OCStackResult OCInit1(OCMode mode, OCTransportFlags serverFlags, OCTransportFlag
 #ifdef TCP_ADAPTER
     if (result == OC_STACK_OK)
     {
-        result = InitializeKeepAlive(myStackMode);
+        result = OCInitializeKeepAlive(myStackMode);
     }
 #endif
 
@@ -2265,10 +2513,14 @@ OCStackResult OCStop()
     }
     else if (stackState != OC_STACK_INITIALIZED)
     {
-        OIC_LOG(ERROR, TAG, "Stack not initialized");
+        OIC_LOG(INFO, TAG, "Stack not initialized");
         return OC_STACK_ERROR;
     }
 
+    // unset cautil config
+    CAUtilConfig_t configs = {(CATransportBTFlags_t)CA_DEFAULT_BT_FLAGS};
+    CAUtilSetBTConfigure(configs);
+
     stackState = OC_STACK_UNINIT_IN_PROGRESS;
 
     CAUnregisterNetworkMonitorHandler(OCDefaultAdapterStateChangedHandler,
@@ -2289,7 +2541,7 @@ OCStackResult OCStop()
 #endif
 
 #ifdef TCP_ADAPTER
-    TerminateKeepAlive(myStackMode);
+    OCTerminateKeepAlive(myStackMode);
 #endif
 
     TerminateScheduleResourceList();
@@ -2351,28 +2603,12 @@ CAMessageType_t qualityOfServiceToMessageType(OCQualityOfService qos)
     }
 }
 
-/**
- *  A request uri consists of the following components in order:
- *                              example
- *  optionally one of
- *      CoAP over UDP prefix    "coap://"
- *      CoAP over TCP prefix    "coap+tcp://"
- *      CoAP over DTLS prefix   "coaps://"
- *      CoAP over TLS prefix    "coaps+tcp://"
- *  optionally one of
- *      IPv6 address            "[1234::5678]"
- *      IPv4 address            "192.168.1.1"
- *  optional port               ":5683"
- *  resource uri                "/oc/core..."
- *
- *  for PRESENCE requests, extract resource type.
- */
-static OCStackResult ParseRequestUri(const char *fullUri,
-                                        OCTransportAdapter adapter,
-                                        OCTransportFlags flags,
-                                        OCDevAddr **devAddr,
-                                        char **resourceUri,
-                                        char **resourceType)
+OCStackResult ParseRequestUri(const char *fullUri,
+                              OCTransportAdapter adapter,
+                              OCTransportFlags flags,
+                              OCDevAddr **devAddr,
+                              char **resourceUri,
+                              char **resourceType)
 {
     VERIFY_NON_NULL(fullUri, FATAL, OC_STACK_INVALID_CALLBACK);
 
@@ -2547,7 +2783,7 @@ static OCStackResult ParseRequestUri(const char *fullUri,
                 result = OC_STACK_NO_MEMORY;
                 goto error;
             }
-            strcpy(*resourceUri, slash);
+            OICStrcpy(*resourceUri, (ulen + 1), slash);
         }
         // resource type
         if (type && resourceType)
@@ -2582,6 +2818,7 @@ error:
     return result;
 }
 
+#ifdef WITH_PRESENCE
 static OCStackResult OCPreparePresence(CAEndpoint_t *endpoint,
                                        char **requestUri,
                                        bool isMulticast)
@@ -2598,6 +2835,7 @@ static OCStackResult OCPreparePresence(CAEndpoint_t *endpoint,
 
     return OC_STACK_OK;
 }
+#endif // WITH_PRESENCE
 
 /**
  * Discover or Perform requests on a specified resource
@@ -2613,7 +2851,30 @@ OCStackResult OCDoResource(OCDoHandle *handle,
                             OCHeaderOption *options,
                             uint8_t numOptions)
 {
+    OCStackResult ret = OCDoRequest(handle, method, requestUri,destination, payload,
+                connectivityType, qos, cbData, options, numOptions);
+
+    // This is the owner of the payload object, so we free it
+    OCPayloadDestroy(payload);
+    return ret;
+}
+
+/**
+ * Discover or Perform requests on a specified resource
+ */
+OCStackResult OCDoRequest(OCDoHandle *handle,
+                            OCMethod method,
+                            const char *requestUri,
+                            const OCDevAddr *destination,
+                            OCPayload* payload,
+                            OCConnectivityType connectivityType,
+                            OCQualityOfService qos,
+                            OCCallbackData *cbData,
+                            OCHeaderOption *options,
+                            uint8_t numOptions)
+{
     OIC_LOG(INFO, TAG, "Entering OCDoResource");
+    OIC_TRACE_BEGIN(%s:OCDoRequest, TAG);
 
     // Validate input parameters
     VERIFY_NON_NULL(cbData, FATAL, OC_STACK_INVALID_CALLBACK);
@@ -2675,7 +2936,6 @@ OCStackResult OCDoResource(OCDoHandle *handle,
         requestInfo.method = CA_DELETE;
         break;
     case OC_REST_DISCOVER:
-        qos = OC_LOW_QOS;
 #ifdef WITH_PRESENCE
     case OC_REST_PRESENCE:
 #endif
@@ -2689,6 +2949,7 @@ OCStackResult OCDoResource(OCDoHandle *handle,
             tmpDevAddr.flags = flags;
             destination = &tmpDevAddr;
             requestInfo.isMulticast = true;
+            qos = OC_LOW_QOS;
         }
         // OC_REST_DISCOVER: CA_DISCOVER will become GET and isMulticast.
         // OC_REST_PRESENCE: Since "presence" is a stack layer only implementation.
@@ -2716,9 +2977,20 @@ OCStackResult OCDoResource(OCDoHandle *handle,
             result = OC_STACK_NO_MEMORY;
             goto exit;
         }
+        OIC_LOG(DEBUG, TAG, "devAddr is set as destination");
         *devAddr = *destination;
     }
 
+    if (devAddr)
+    {
+        OIC_LOG_V(INFO_PRIVATE, TAG, "remoteId of devAddr : %s", devAddr->remoteId);
+        if (!requestInfo.isMulticast)
+        {
+            OIC_LOG_V(DEBUG, TAG, "remoteAddr of devAddr : [%s]:[%d]",
+                      devAddr->addr, devAddr->port);
+        }
+    }
+
     resHandle = GenerateInvocationHandle();
     if (!resHandle)
     {
@@ -2855,13 +3127,12 @@ exit:
         OICFree(resHandle);
     }
 
-    // This is the owner of the payload object, so we free it
-    OCPayloadDestroy(payload);
     OICFree(requestInfo.info.payload);
     OICFree(devAddr);
     OICFree(resourceUri);
     OICFree(resourceType);
     OICFree(requestInfo.info.options);
+    OIC_TRACE_END();
     return result;
 }
 
@@ -2955,6 +3226,14 @@ OCStackResult OCCancel(OCDoHandle handle, OCQualityOfService qos, OCHeaderOption
             FindAndDeleteClientCB(clientCB);
             break;
 #endif
+        case OC_REST_GET:
+        case OC_REST_PUT:
+        case OC_REST_POST:
+        case OC_REST_DELETE:
+            OIC_LOG_V(INFO, TAG, "Cancelling request callback for resource %s",
+                                           clientCB->requestUri);
+            FindAndDeleteClientCB(clientCB);
+            break;
 
         default:
             ret = OC_STACK_INVALID_METHOD;
@@ -3093,6 +3372,11 @@ exit:
 
 OCStackResult OCProcess()
 {
+    if (stackState == OC_STACK_UNINITIALIZED)
+    {
+        OIC_LOG(ERROR, TAG, "OCProcess has failed. ocstack is not initialized");
+        return OC_STACK_ERROR;
+    }
 #ifdef WITH_PRESENCE
     OCProcessPresence();
 #endif
@@ -3103,7 +3387,7 @@ OCStackResult OCProcess()
 #endif
 
 #ifdef TCP_ADAPTER
-    ProcessKeepAlive();
+    OCProcessKeepAlive();
 #endif
     return OC_STACK_OK;
 }
@@ -3131,7 +3415,9 @@ OCStackResult OCStartPresence(const uint32_t ttl)
     {
         presenceResource.presenceTTL = ttl;
     }
+#ifndef __TIZENRT__
     OIC_LOG_V(DEBUG, TAG, "Presence TTL is %" PRIu32 " seconds", presenceResource.presenceTTL);
+#endif
 
     if (OC_PRESENCE_UNINITIALIZED == presenceState)
     {
@@ -3467,8 +3753,11 @@ OCStackResult OCUnBindResource(
             {
                 OCChildResource *temp = tempChildResource->next;
                 OICFree(tempChildResource);
-                tempLastChildResource->next = temp;
-                temp = NULL;
+                if (tempLastChildResource)
+                {
+                    tempLastChildResource->next = temp;
+                    temp = NULL;
+                }
             }
 
             OIC_LOG(INFO, TAG, "resource unbound");
@@ -4035,6 +4324,7 @@ OCNotifyListOfObservers (OCResourceHandle handle,
 
 OCStackResult OCDoResponse(OCEntityHandlerResponse *ehResponse)
 {
+    OIC_TRACE_BEGIN(%s:OCDoResponse, TAG);
     OCStackResult result = OC_STACK_ERROR;
     OCServerRequest *serverRequest = NULL;
 
@@ -4053,6 +4343,7 @@ OCStackResult OCDoResponse(OCEntityHandlerResponse *ehResponse)
         result = serverRequest->ehResponseHandler(ehResponse);
     }
 
+    OIC_TRACE_END();
     return result;
 }
 
@@ -4310,12 +4601,12 @@ OCStackResult deleteResource(OCResource *resource)
                 headResource = temp->next;
             }
             // Deleting tail.
-            else if (temp == tailResource)
+            else if (temp == tailResource && prev)
             {
                 tailResource = prev;
                 tailResource->next = NULL;
             }
-            else
+            else if (prev)
             {
                 prev->next = temp->next;
             }
@@ -4341,37 +4632,77 @@ void deleteResourceElements(OCResource *resource)
         return;
     }
 
-    OICFree(resource->uri);
-    deleteResourceType(resource->rsrcType);
-    deleteResourceInterface(resource->rsrcInterface);
-    OCDeleteResourceAttributes(resource->rsrcAttributes);
+    if (resource->uri)
+    {
+        OICFree(resource->uri);
+        resource->uri = NULL;
+    }
+    if (resource->rsrcType)
+    {
+        deleteResourceType(resource->rsrcType);
+        resource->rsrcType = NULL;
+    }
+    if (resource->rsrcInterface)
+    {
+        deleteResourceInterface(resource->rsrcInterface);
+        resource->rsrcInterface = NULL;
+    }
+    if (resource->rsrcChildResourcesHead)
+    {
+        deleteResourceChild(resource->rsrcChildResourcesHead);
+        resource->rsrcChildResourcesHead = NULL;
+    }
+    if (resource->rsrcAttributes)
+    {
+        OCDeleteResourceAttributes(resource->rsrcAttributes);
+        resource->rsrcAttributes = NULL;
+    }
+    resource = NULL;
 }
 
 void deleteResourceType(OCResourceType *resourceType)
 {
-    OCResourceType *pointer = resourceType;
     OCResourceType *next = NULL;
 
-    while (pointer)
+    for (OCResourceType *pointer = resourceType; pointer; pointer = next)
     {
-        next = pointer->next;
-        OICFree(pointer->resourcetypename);
+        next = pointer->next ? pointer->next : NULL;
+        if (pointer->resourcetypename)
+        {
+            OICFree(pointer->resourcetypename);
+            pointer->resourcetypename = NULL;
+        }
         OICFree(pointer);
-        pointer = next;
     }
 }
 
 void deleteResourceInterface(OCResourceInterface *resourceInterface)
 {
-    OCResourceInterface *pointer = resourceInterface;
     OCResourceInterface *next = NULL;
+    for (OCResourceInterface *pointer = resourceInterface; pointer; pointer = next)
+    {
+        next = pointer->next ? pointer->next : NULL;
+        if (pointer->name)
+        {
+            OICFree(pointer->name);
+            pointer->name = NULL;
+        }
+        OICFree(pointer);
+    }
+}
 
-    while (pointer)
+void deleteResourceChild(OCChildResource *resourceChild)
+{
+    OCChildResource *next = NULL;
+    for (OCChildResource *pointer = resourceChild; pointer; pointer = next)
     {
-        next = pointer->next;
-        OICFree(pointer->name);
+        next = pointer->next ? pointer->next : NULL;
+        if (pointer->rsrcResource)
+        {
+            deleteResourceElements(pointer->rsrcResource);
+            pointer->rsrcResource = NULL;
+        }
         OICFree(pointer);
-        pointer = next;
     }
 }
 
@@ -4380,16 +4711,22 @@ void OCDeleteResourceAttributes(OCAttribute *rsrcAttributes)
     OCAttribute *next = NULL;
     for (OCAttribute *pointer = rsrcAttributes; pointer; pointer = next)
     {
-        next = pointer->next;
+        next = pointer->next ? pointer->next : NULL;
         if (pointer->attrName && 0 == strcmp(OC_RSRVD_DATA_MODEL_VERSION, pointer->attrName))
         {
             OCFreeOCStringLL((OCStringLL *)pointer->attrValue);
+            pointer->attrValue = NULL;
         }
-        else
+        else if (pointer->attrValue)
         {
             OICFree(pointer->attrValue);
+            pointer->attrValue = NULL;
+        }
+        if (pointer->attrName)
+        {
+            OICFree(pointer->attrName);
+            pointer->attrName = NULL;
         }
-        OICFree(pointer->attrName);
         OICFree(pointer);
     }
 }
@@ -4649,47 +4986,28 @@ OCStackResult getQueryFromUri(const char * uri, char** query, char ** uriWithout
         return OC_STACK_NO_MEMORY;
 }
 
-static const OicUuid_t* OCGetServerInstanceID(void)
-{
-    static bool generated = false;
-    static OicUuid_t sid;
-    if (generated)
-    {
-        return &sid;
-    }
-
-    if (OC_STACK_OK != GetDoxmDeviceID(&sid))
-    {
-        OIC_LOG(FATAL, TAG, "Generate UUID for Server Instance failed!");
-        return NULL;
-    }
-    generated = true;
-    return &sid;
-}
-
 const char* OCGetServerInstanceIDString(void)
 {
-    static bool generated = false;
     static char sidStr[UUID_STRING_SIZE];
-
-    if (generated)
+    OicUuid_t sid;
+    if (OC_STACK_OK != GetDoxmDeviceID(&sid))
     {
-        return sidStr;
+        OIC_LOG(FATAL, TAG, "GetDoxmDeviceID failed!");
+        return NULL;
     }
 
-    const OicUuid_t *sid = OCGetServerInstanceID();
-    if (sid && OCConvertUuidToString(sid->id, sidStr) != RAND_UUID_OK)
+    if (OCConvertUuidToString(sid.id, sidStr) != RAND_UUID_OK)
     {
         OIC_LOG(FATAL, TAG, "Generate UUID String for Server Instance failed!");
         return NULL;
     }
 
-    generated = true;
     return sidStr;
 }
 
-CAResult_t OCSelectNetwork()
+CAResult_t OCSelectNetwork(OCTransportAdapter transportType)
 {
+    OIC_LOG_V(DEBUG, TAG, "OCSelectNetwork [%d]", transportType);
     CAResult_t retResult = CA_STATUS_FAILED;
     CAResult_t caResult = CA_STATUS_OK;
 
@@ -4713,11 +5031,19 @@ CAResult_t OCSelectNetwork()
         // If CA status is not initialized, CASelectNetwork() will not be called.
         if (caResult != CA_STATUS_NOT_INITIALIZED)
         {
-           caResult = CASelectNetwork(connTypes[i]);
-           if (caResult == CA_STATUS_OK)
-           {
-               retResult = CA_STATUS_OK;
-           }
+            if ((connTypes[i] & transportType) || (OC_DEFAULT_ADAPTER == transportType))
+            {
+                OIC_LOG_V(DEBUG, TAG, "call CASelectNetwork [%d]", connTypes[i]);
+                caResult = CASelectNetwork(connTypes[i]);
+                if (caResult == CA_STATUS_OK)
+                {
+                    retResult = CA_STATUS_OK;
+                }
+            }
+            else
+            {
+                OIC_LOG_V(DEBUG, TAG, "there is no transport type [%d]", connTypes[i]);
+            }
         }
     }
 
@@ -4790,7 +5116,7 @@ OCStackResult OCSetProxyURI(const char *uri)
 #endif
 
 #if defined(RD_CLIENT) || defined(RD_SERVER)
-OCStackResult OCBindResourceInsToResource(OCResourceHandle handle, uint8_t ins)
+OCStackResult OCBindResourceInsToResource(OCResourceHandle handle, int64_t ins)
 {
     VERIFY_NON_NULL(handle, ERROR, OC_STACK_INVALID_PARAM);
 
@@ -4894,13 +5220,13 @@ OCStackResult OCUpdateResourceInsWithResponse(const char *requestUri,
                  query = strstr(query, OC_RSRVD_INS);
                  if (query)
                  {
-                     uint8_t queryIns = atoi(query + 4);
+                     int64_t queryIns = atoi(query + 4);
                      for (uint8_t i = 0; i < numResources; i++)
                      {
                          OCResourceHandle resHandle = OCGetResourceHandle(i);
                          if (resHandle)
                          {
-                             uint8_t resIns = 0;
+                             int64_t resIns = 0;
                              OCGetResourceIns(resHandle, &resIns);
                              if (queryIns && queryIns == resIns)
                              {
@@ -4941,7 +5267,7 @@ OCResourceHandle OCGetResourceHandleAtUri(const char *uri)
     return NULL;
 }
 
-OCStackResult OCGetResourceIns(OCResourceHandle handle, uint8_t *ins)
+OCStackResult OCGetResourceIns(OCResourceHandle handle, int64_t *ins)
 {
     OCResource *resource = NULL;
 
@@ -5109,3 +5435,137 @@ OCStackResult OCSetDeviceId(const OCUUIdentity *deviceId)
     ret = SetDoxmDeviceID(&oicUuid);
     return ret;
 }
+
+OCStackResult OCGetDeviceOwnedState(bool *isOwned)
+{
+    bool isDeviceOwned = true;
+    OCStackResult ret = OC_STACK_ERROR;
+
+    ret = GetDoxmIsOwned(&isDeviceOwned);
+    if (OC_STACK_OK == ret)
+    {
+        *isOwned = isDeviceOwned;
+    }
+    else
+    {
+        OIC_LOG(ERROR, TAG, "Device Owned State Get error");
+    }
+    return ret;
+}
+
+void OCClearCallBackList()
+{
+    DeleteClientCBList();
+}
+
+void OCClearObserverlist()
+{
+    DeleteObserverList();
+}
+
+int OCEncrypt(const unsigned char *pt, size_t pt_len,
+        unsigned char **ct, size_t *ct_len)
+{
+#ifndef __SECURE_PSI__
+    OIC_LOG_V(DEBUG, TAG, "Not Supported : %s", __func__);
+    return 0;
+#else
+    OIC_LOG_V(DEBUG, TAG, "%s", __func__);
+
+    return psiEncrypt(pt, pt_len, ct, ct_len);
+#endif // __SECURE_PSI__
+}
+
+int OCDecrypt(const unsigned char *ct, size_t ct_len,
+        unsigned char **pt, size_t *pt_len)
+{
+#ifndef __SECURE_PSI__
+    OIC_LOG_V(DEBUG, TAG, "Not Supported : %s", __func__);
+    return 0;
+#else
+    OIC_LOG_V(DEBUG, TAG, "%s", __func__);
+
+    return psiDecrypt(ct, ct_len, pt, pt_len);
+#endif // __SECURE_PSI__
+}
+
+OCStackResult OCSetKey(const unsigned char* key)
+{
+#ifndef __SECURE_PSI__
+    OIC_LOG_V(DEBUG, TAG, "Not Supported : %s", __func__);
+    return OC_STACK_OK;
+#else
+    OIC_LOG_V(DEBUG, TAG, "%s", __func__);
+
+    return psiSetKey(key);
+#endif // __SECURE_PSI__
+}
+
+OCStackResult OCGetKey(unsigned char* key)
+{
+#ifndef __SECURE_PSI__
+    OIC_LOG_V(DEBUG, TAG, "Not Supported : %s", __func__);
+    return OC_STACK_OK;
+#else
+    OIC_LOG_V(DEBUG, TAG, "%s", __func__);
+
+    return psiGetKey(key);
+#endif // __SECURE_PSI__
+}
+
+OCStackResult OCSetSecurePSI(const unsigned char *key, const OCPersistentStorage *psPlain,
+        const OCPersistentStorage *psEnc, const OCPersistentStorage *psRescue)
+{
+#ifndef __SECURE_PSI__
+    OIC_LOG_V(DEBUG, TAG, "Not Supported : %s", __func__);
+    return OC_STACK_OK;
+#else
+    OIC_LOG_V(DEBUG, TAG, "%s", __func__);
+
+    return setSecurePSI(key, psPlain, psEnc, psRescue);
+#endif // __SECURE_PSI__
+}
+
+#if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
+static void OtmEventHandler(const char *addr, uint16_t port, const char *uuid, int event)
+{
+    if (g_otmEventHandler.cb)
+    {
+        g_otmEventHandler.cb(g_otmEventHandler.ctx, addr, port, uuid, event);
+    }
+}
+
+/* TODO Work-around
+ * It is already declared in srmutility.h.
+ * We can't include the header file, because of "redefined VERIFY_NON_NULL"
+ */
+typedef void (*OicSecOtmEventHandler_t)(const char* addr, uint16_t port,
+        const char* uuid, int event);
+void SetOtmEventHandler(OicSecOtmEventHandler_t otmEventHandler);
+#endif
+
+OCStackResult OCSetOtmEventHandler(void *ctx, OCOtmEventHandler cb)
+{
+#if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
+    OIC_LOG_V(DEBUG, TAG, "%s", __func__);
+
+    g_otmEventHandler.cb = cb;
+    g_otmEventHandler.ctx = ctx;
+
+    if (g_otmEventHandler.cb)
+    {
+        OIC_LOG(DEBUG, TAG, "SET OCOtmEventHandler");
+        SetOtmEventHandler(OtmEventHandler);
+    }
+    else
+    {
+        OIC_LOG(DEBUG, TAG, "UNSET OCOtmEventHandler");
+        SetOtmEventHandler(NULL);
+    }
+#else
+    OIC_LOG_V(DEBUG, TAG, "Not Supported : %s", __func__);
+    OC_UNUSED(ctx);
+    OC_UNUSED(cb);
+#endif
+    return OC_STACK_OK;
+}
index 9c6bc1f..5114f41 100755 (executable)
 #include <string.h>
 
 #include "oicgroup.h"
+#if defined (__TIZENRT__)
+#include <apps/netutils/cJSON.h>
+#else
 #include "cJSON.h"
+#endif
 #include "cbor.h"
 #include "ocpayload.h"
 #include "oic_malloc.h"
@@ -775,6 +779,7 @@ exit:
     OCFREE(desc)
     OCFREE(capa)
     OCFREE(action)
+    OCFREE((*set)->actionsetName)
     OCFREE(*set)
     OCFREE(key)
     OCFREE(value)
@@ -1273,6 +1278,7 @@ OCStackResult BuildCollectionGroupActionCBORResponse(
                 stackRet = OC_STACK_ERROR;
             }
         }
+        OCRepPayloadDestroy(payload);
     }
     else if (method == OC_REST_POST)
     {
@@ -1455,6 +1461,7 @@ OCStackResult BuildCollectionGroupActionCBORResponse(
                 stackRet = OC_STACK_ERROR;
             }
         }
+        OCRepPayloadDestroy(payload);
     }
 
 exit:
index 52dae89..1340b70 100644 (file)
@@ -19,6 +19,7 @@
  ******************************************************************/
 
 #include "oickeepalive.h"
+#include "oickeepaliveinternal.h"
 
 #include <stdio.h>
 #include <string.h>
 #include "oic_string.h"
 #include "oic_time.h"
 #include "ocrandom.h"
+#include "octhread.h"
 #include "uarraylist.h"
 #include "ocstackinternal.h"
 #include "ocpayloadcbor.h"
 #include "ocpayload.h"
 #include "ocresourcehandler.h"
 #include "logger.h"
+#include "cautilinterface.h"
+#include <coap/utlist.h>
 
 /**
  * Logging tag for module name.
@@ -62,22 +66,6 @@ static const uint64_t USECS_PER_SEC = 1000000;
 #define KEEPALIVE_RESPONSE_TIMEOUT_SEC 60
 
 /**
- * The Min time interval value. (2 minutes)
- * start from 2 minutes and increases in multiples of 2 up to a maximum of 64minutes.
- */
-#define KEEPALIVE_MIN_INTERVAL 2
-
-/**
- * The Max time interval value. (64 minutes)
- */
-#define KEEPALIVE_MAX_INTERVAL 64
-
-/**
- * Default counts of interval value.
- */
-#define DEFAULT_INTERVAL_COUNT  6
-
-/**
  * KeepAlive key to parser Payload Table.
  */
 static const char INTERVAL[] = "in";
@@ -88,11 +76,6 @@ static const char INTERVAL[] = "in";
 static const char INTERVAL_ARRAY[] = "inarray";
 
 /**
- * To check if KeepAlive is initialized.
- */
-static bool g_isKeepAliveInitialized = false;
-
-/**
  * Pointer to handle of the newly created KeepAlive resource.
  */
 static OCResourceHandle g_keepAliveHandle = NULL;
@@ -100,55 +83,44 @@ static OCResourceHandle g_keepAliveHandle = NULL;
 /**
  * KeepAlive table which holds connection interval.
  */
-static u_arraylist_t *g_keepAliveConnectionTable = NULL;
+static struct KeepAliveEntry_t *g_keepAliveConnectionTable = NULL;
+
+/**
+ * Mutex to synchronize device object list.
+ */
+static oc_mutex g_mutexObjectList = NULL;
 
 /**
  * KeepAlive table entries.
  */
-typedef struct
+typedef struct KeepAliveEntry_t
 {
     OCMode mode;                    /**< host Mode of Operation. */
     CAEndpoint_t remoteAddr;        /**< destination Address. */
-    int64_t interval;              /**< time interval for KeepAlive. in seconds.*/
+    int64_t interval;               /**< time interval for KeepAlive. in seconds.*/
     int32_t currIndex;              /**< current interval value index. */
-    size_t intervalSize;            /**< total interval counts. */
-    int64_t *intervalInfo;          /**< interval values for KeepAlive. */
     bool sentPingMsg;               /**< if oic client already sent ping message. */
     uint64_t timeStamp;             /**< last sent or received ping message. in microseconds. */
+    OCDoHandle handle;              /**< Invocation handle tied to original call to OCDoResource().*/
+    struct KeepAliveEntry_t *next;  /**< Linked list; for multiple keepalive info list.*/
 } KeepAliveEntry_t;
 
 /**
  * Send disconnect message to remove connection.
  */
-static OCStackResult SendDisconnectMessage(const KeepAliveEntry_t *entry);
-
-/**
- * Send ping message to remote endpoint.
- */
-static OCStackResult SendPingMessage(KeepAliveEntry_t *entry);
-
-/**
- * Increase interval value to send next ping message.
- */
-static void IncreaseInterval(KeepAliveEntry_t *entry);
-
-/**
- * Ping Message callback registered with RI for KeepAlive Request.
- */
-static OCStackApplicationResult PingRequestCallback(void* ctx, OCDoHandle handle,
-                                             OCClientResponse * clientResponse);
+static OCStackResult OCSendDisconnectMessage(const KeepAliveEntry_t *entry);
 
 /**
  * This function creates KeepAlive resource.
  * @return  ::OC_STACK_OK or Appropriate error code.
  */
-static OCStackResult CreateKeepAliveResource();
+static OCStackResult OCCreateKeepAliveResource();
 
 /**
  * This function deletes KeepAlive resource.
  * @return  ::OC_STACK_OK or Appropriate error code.
  */
-static OCStackResult DeleteKeepAliveResource();
+static OCStackResult OCDeleteKeepAliveResource();
 
 /**
  * API to handle the GET request received for a KeepAlive resource.
@@ -156,8 +128,8 @@ static OCStackResult DeleteKeepAliveResource();
  * @param[in]   resource    Resource handle used for sending the response.
  * @return  ::OC_STACK_OK or Appropriate error code.
  */
-static OCEntityHandlerResult HandleKeepAliveGETRequest(OCServerRequest *request,
-                                                       const OCResource *resource);
+static OCEntityHandlerResult OCHandleKeepAliveGETRequest(OCServerRequest *request,
+                                                         const OCResource *resource);
 
 /**
  * API to handle the PUT request received for a KeepAlive resource.
@@ -165,39 +137,28 @@ static OCEntityHandlerResult HandleKeepAliveGETRequest(OCServerRequest *request,
  * @param[in]   resource    Resource handle used for sending the response.
  * @return  ::OC_STACK_OK or Appropriate error code.
  */
-static OCEntityHandlerResult HandleKeepAlivePOSTRequest(OCServerRequest *request,
-                                                        const OCResource *resource);
+static OCEntityHandlerResult OCHandleKeepAlivePOSTRequest(OCServerRequest *request,
+                                                          const OCResource *resource);
 
 /**
- * API to handle the Response payload.
- * @param[in]   endpoint        RemoteEndpoint which sent the packet.
- * @param[in]   responseCode    Received reseponse code.
- * @param[in]   respPayload     Response payload.
- * @return  ::OC_STACK_OK or Appropriate error code.
- */
-OCStackResult HandleKeepAliveResponse(const CAEndpoint_t *endPoint,
-                                      OCStackResult responseCode,
-                                      const OCRepPayload *respPayload);
-/**
  * Gets keepalive entry.
  * @param[in]   endpoint    Remote Endpoint information (like ipaddress,
  *                          port, reference uri and transport type) to
  *                          which the ping message has to be sent.
- * @param[out]  index       index of array list.
  * @return  KeepAlive entry to send ping message.
  */
-static KeepAliveEntry_t *GetEntryFromEndpoint(const CAEndpoint_t *endpoint, uint32_t *index);
+static KeepAliveEntry_t *OCGetEntryFromEndpoint(const CAEndpoint_t *endpoint);
 
 /**
  * Add keepalive entry.
  * @param[in]   endpoint    Remote Endpoint information (like ipaddress,
  *                          port, reference uri and transport type).
  * @param[in]   mode        Whether it is OIC Server or OIC Client.
- * @param[in]   intervalArray   Received interval values from cloud server.
+ * @param[in]   interval    Sent interval value to remote device.
  * @return  The KeepAlive entry added in KeepAlive Table.
  */
-KeepAliveEntry_t *AddKeepAliveEntry(const CAEndpoint_t *endpoint, OCMode mode,
-                                    int64_t *intervalArray);
+KeepAliveEntry_t *OCAddKeepAliveEntry(const CAEndpoint_t *endpoint, OCMode mode,
+                                      int64_t interval);
 
 /**
  * Remove keepalive entry.
@@ -205,14 +166,14 @@ KeepAliveEntry_t *AddKeepAliveEntry(const CAEndpoint_t *endpoint, OCMode mode,
  *                          port, reference uri and transport type).
  * @return  The KeepAlive entry removed in KeepAlive Table.
  */
-static OCStackResult RemoveKeepAliveEntry(const CAEndpoint_t *endpoint);
+static OCStackResult OCRemoveKeepAliveEntry(const CAEndpoint_t *endpoint);
 
 /**
  * Create KeepAlive paylaod to send message.
  * @param[in]   interval   The interval value to be sent.
  * @return  Created representation payload.
  */
-static OCRepPayload *CreateKeepAlivePayload(int64_t interval);
+static OCRepPayload *OCCreateKeepAlivePayload(int64_t interval);
 
 /**
  * Send response to remote device.
@@ -220,7 +181,7 @@ static OCRepPayload *CreateKeepAlivePayload(int64_t interval);
  * @param[in]   result      Result to be sent.
  * @return  ::OC_STACK_OK or Appropriate error code.
  */
-static OCStackResult SendKeepAliveResponse(OCServerRequest *request,
+static OCStackResult OCSendKeepAliveResponse(OCServerRequest *request,
                                            OCEntityHandlerResult result);
 
 /**
@@ -228,87 +189,228 @@ static OCStackResult SendKeepAliveResponse(OCServerRequest *request,
  * @param[in]   payload     Pointer to the payload to which byte string needs to be added.
  * @return  ::OC_STACK_OK or Appropriate error code.
  */
-static OCStackResult AddResourceTypeNameToPayload(OCRepPayload *payload);
+static OCStackResult OCAddResourceTypeNameToPayload(OCRepPayload *payload);
 
 /**
  * Add resource interface name to payload for GET request.
  * @param[in]   payload     Pointer to the payload to which byte string needs to be added.
  * @return  ::OC_STACK_OK or Appropriate error code.
  */
-static OCStackResult AddResourceInterfaceNameToPayload(OCRepPayload *payload);
+static OCStackResult OCAddResourceInterfaceNameToPayload(OCRepPayload *payload);
 
-OCStackResult InitializeKeepAlive(OCMode mode)
+OCStackResult OCInitializeKeepAlive(OCMode mode)
 {
-    OIC_LOG(DEBUG, TAG, "InitializeKeepAlive IN");
-    if (g_isKeepAliveInitialized)
+    OIC_LOG(DEBUG, TAG, "OCInitializeKeepAlive IN");
+
+    if (!g_mutexObjectList)
     {
-        OIC_LOG(DEBUG, TAG, "KeepAlive already initialized");
-        return OC_STACK_OK;
+        g_mutexObjectList = oc_mutex_new();
+        if (!g_mutexObjectList)
+        {
+            OIC_LOG(ERROR, TAG, "Failed to create mutex!");
+            return OC_STACK_ERROR;
+        }
     }
 
     if (OC_CLIENT != mode)
     {
         // Create the KeepAlive Resource[/oic/ping].
-        OCStackResult result = CreateKeepAliveResource();
+        OCStackResult result = OCCreateKeepAliveResource();
         if (OC_STACK_OK != result)
         {
-            OIC_LOG_V(ERROR, TAG, "CreateKeepAliveResource failed[%d]", result);
+            OIC_LOG_V(ERROR, TAG, "OCCreateKeepAliveResource failed[%d]", result);
             return result;
         }
     }
 
-    if (!g_keepAliveConnectionTable)
+    OIC_LOG(DEBUG, TAG, "OCInitializeKeepAlive OUT");
+    return OC_STACK_OK;
+}
+
+OCStackResult OCTerminateKeepAlive(OCMode mode)
+{
+    OIC_LOG(DEBUG, TAG, "OCTerminateKeepAlive IN");
+
+    if (g_mutexObjectList)
+    {
+        oc_mutex_free(g_mutexObjectList);
+        g_mutexObjectList = NULL;
+    }
+
+    if (OC_CLIENT != mode)
     {
-        g_keepAliveConnectionTable = u_arraylist_create();
-        if (NULL == g_keepAliveConnectionTable)
+        // Delete the KeepAlive Resource[/oic/ping].
+        OCStackResult result = OCDeleteKeepAliveResource();
+        if (OC_STACK_OK != result)
         {
-            OIC_LOG(ERROR, TAG, "Creating KeepAlive Table failed");
-            TerminateKeepAlive(mode);
-            return OC_STACK_ERROR;
+            OIC_LOG_V(ERROR, TAG, "OCDeleteKeepAliveResource failed[%d]", result);
+            return result;
         }
     }
 
-    g_isKeepAliveInitialized = true;
-
-    OIC_LOG(DEBUG, TAG, "InitializeKeepAlive OUT");
+    OIC_LOG(DEBUG, TAG, "OCTerminateKeepAlive OUT");
     return OC_STACK_OK;
 }
 
-OCStackResult TerminateKeepAlive(OCMode mode)
+OCStackResult OCFindKeepAliveResource(OCDoHandle *handle, const char *remoteAddr,
+                                      OCCallbackData *cbData)
+{
+    // Validate input parameters
+    VERIFY_NON_NULL(remoteAddr, FATAL, OC_STACK_INVALID_CALLBACK);
+    VERIFY_NON_NULL(cbData, FATAL, OC_STACK_INVALID_CALLBACK);
+    VERIFY_NON_NULL(cbData->cb, FATAL, OC_STACK_INVALID_CALLBACK);
+
+    // Send discover message to find ping resource
+    char requestUri[MAX_QUERY_LENGTH] = { 0 };
+    snprintf(requestUri, MAX_QUERY_LENGTH, "%s%s", remoteAddr, KEEPALIVE_RESOURCE_URI);
+    OCStackResult result = OCDoResource(handle, OC_REST_DISCOVER, requestUri,
+                                        NULL, NULL, CT_ADAPTER_TCP, OC_HIGH_QOS,
+                                        cbData, NULL, 0);
+    if (OC_STACK_OK != result)
+    {
+        OIC_LOG(ERROR, TAG, "OCDoResource has failed");
+    }
+    return result;
+}
+
+OCStackResult OCSendKeepAliveRequest(OCDoHandle *handle, const char *remoteAddr,
+                                     OCPayload *payload, OCCallbackData *cbData)
 {
-    OIC_LOG(DEBUG, TAG, "TerminateKeepAlive IN");
-    if (!g_isKeepAliveInitialized)
+    VERIFY_NON_NULL(remoteAddr, FATAL, OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL(cbData, FATAL, OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL(cbData->cb, FATAL, OC_STACK_INVALID_CALLBACK);
+    VERIFY_NON_NULL(payload, FATAL, OC_STACK_INVALID_CALLBACK);
+
+    OIC_LOG(DEBUG, TAG, "SendKeepAliveRequest IN");
+
+    // Parse the remote device address to send ping message.
+    OCDevAddr *devAddr = NULL;
+    char requestUri[MAX_QUERY_LENGTH] = { 0 };
+    snprintf(requestUri, MAX_QUERY_LENGTH, "%s%s", remoteAddr, KEEPALIVE_RESOURCE_URI);
+    OCStackResult result = ParseRequestUri(requestUri, OC_DEFAULT_ADAPTER, OC_DEFAULT_FLAGS,
+                                           &devAddr, NULL, NULL);
+    if (result != OC_STACK_OK)
     {
-        OIC_LOG(ERROR, TAG, "KeepAlive not initialized");
+        OIC_LOG_V(DEBUG, TAG, "Unable to parse uri: %s", remoteAddr);
         return OC_STACK_ERROR;
     }
 
-    if (OC_CLIENT != mode)
+    VERIFY_NON_NULL(devAddr, FATAL, OC_STACK_INVALID_PARAM);
+
+    if (!(devAddr->adapter & OC_ADAPTER_TCP))
     {
-        // Delete the KeepAlive Resource[/oic/ping].
-        OCStackResult result = DeleteKeepAliveResource();
-        if (OC_STACK_OK != result)
+        OIC_LOG_V(DEBUG, TAG, "Not supported connectivity type");
+        OICFree(devAddr);
+        return OC_STACK_ERROR;
+    }
+
+    // Get entry from KeepAlive table.
+    CAEndpoint_t endpoint = { .adapter = CA_DEFAULT_ADAPTER };
+    CopyDevAddrToEndpoint(devAddr, &endpoint);
+
+    oc_mutex_lock(g_mutexObjectList);
+    KeepAliveEntry_t *entry = OCGetEntryFromEndpoint(&endpoint);
+    if (!entry)
+    {
+        OIC_LOG(DEBUG, TAG, "There is no connection info in KeepAlive table");
+
+        entry = OCAddKeepAliveEntry(&endpoint, OC_CLIENT, 0);
+        if (!entry)
         {
-            OIC_LOG_V(ERROR, TAG, "DeleteKeepAliveResource failed[%d]", result);
-            return result;
+            oc_mutex_unlock(g_mutexObjectList);
+            OIC_LOG(ERROR, TAG, "Failed to add new KeepAlive entry");
+            OICFree(devAddr);
+            return OC_STACK_ERROR;
+        }
+    }
+
+    // Get "in" value from payload.
+    int64_t interval = 0;
+    bool findValue = OCRepPayloadGetPropInt((OCRepPayload *) payload, INTERVAL, &interval);
+    if (findValue && interval)
+    {
+        if (entry->sentPingMsg)
+        {
+            oc_mutex_unlock(g_mutexObjectList);
+            OIC_LOG(ERROR, TAG, "Already sent a ping request to remote device");
+            OICFree(devAddr);
+            return OC_STACK_ERROR;
+        }
+        entry->interval = interval;
+        OIC_LOG_V(DEBUG, TAG, "Send ping message with interval [%" PRId64 "]", entry->interval);
+    }
+
+    // Get "inarray" value from payload.
+    int64_t *inArray = NULL;
+    size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
+    OCRepPayloadGetIntArray((OCRepPayload *) payload, INTERVAL_ARRAY, &inArray, dimensions);
+    if (inArray)
+    {
+        uint8_t len = 0;
+        char newArray[MAX_URI_LENGTH] = { 0 };
+        size_t inArraySize = calcDimTotal(dimensions);
+        for (size_t i = 0; i < inArraySize; i++)
+        {
+            len += snprintf(newArray + len, MAX_URI_LENGTH, "% " PRId64, inArray[i]);
         }
+        OICFree(inArray);
+        OIC_LOG_V(DEBUG, TAG, "Send update interval message with inarray [ %s]", newArray);
+    }
+
+    // Send keepalive message.
+    result = OCDoResource(&entry->handle, OC_REST_POST, KEEPALIVE_RESOURCE_URI,
+                          devAddr, (OCPayload *) payload, CT_ADAPTER_TCP,
+                          OC_HIGH_QOS, cbData, NULL, 0);
+    if (OC_STACK_OK != result)
+    {
+        oc_mutex_unlock(g_mutexObjectList);
+        OIC_LOG(ERROR, TAG, "OCDoResource has failed");
+        OICFree(devAddr);
+        return result;
     }
 
-    if (NULL != g_keepAliveConnectionTable)
+    // Update timeStamp with time sent ping message for next ping message.
+    entry->timeStamp = OICGetCurrentTime(TIME_IN_US);
+    entry->sentPingMsg = true;
+    if (handle)
     {
-        u_arraylist_destroy(g_keepAliveConnectionTable);
-        g_keepAliveConnectionTable = NULL;
+        *handle = entry->handle;
     }
 
-    g_isKeepAliveInitialized = false;
+    oc_mutex_unlock(g_mutexObjectList);
+    OIC_LOG(DEBUG, TAG, "SendKeepAliveRequest OUT");
+    OICFree(devAddr);
+    return result;
+}
+
+OCStackResult OCHandleKeepAliveResponse(const CAEndpoint_t *endPoint, const OCPayload *payload)
+{
+    (void) payload;
+    VERIFY_NON_NULL(endPoint, FATAL, OC_STACK_INVALID_PARAM);
+
+    // Receive response message about post /oic/ping request.
+    OIC_LOG(DEBUG, TAG, "OCHandleKeepAliveResponse IN");
 
-    OIC_LOG(DEBUG, TAG, "TerminateKeepAlive OUT");
+    // Get entry from KeepAlive table.
+    oc_mutex_lock(g_mutexObjectList);
+    KeepAliveEntry_t *entry = OCGetEntryFromEndpoint(endPoint);
+    if (entry)
+    {
+        OIC_LOG_V(DEBUG, TAG, "Received response about interval [%" PRId64 "]", entry->interval);
+
+        // Set sentPingMsg values with false.
+        entry->sentPingMsg = false;
+        entry->handle = NULL;
+    }
+
+    oc_mutex_unlock(g_mutexObjectList);
+    OIC_LOG(DEBUG, TAG, "OCHandleKeepAliveResponse OUT");
     return OC_STACK_OK;
 }
 
-OCStackResult CreateKeepAliveResource()
+OCStackResult OCCreateKeepAliveResource()
 {
-    OIC_LOG(DEBUG, TAG, "InitKeepAliveResource IN");
+    OIC_LOG(DEBUG, TAG, "OCCreateKeepAliveResource IN");
 
     // Create a KeepAlive resource
     OCStackResult result = OCCreateResource(&g_keepAliveHandle,
@@ -329,13 +431,13 @@ OCStackResult CreateKeepAliveResource()
         OIC_LOG_V(ERROR, TAG, "Create resource for KeepAlive failed[%d]", result);
     }
 
-    OIC_LOG(DEBUG, TAG, "InitKeepAliveResource OUT");
+    OIC_LOG(DEBUG, TAG, "OCCreateKeepAliveResource OUT");
     return result;
 }
 
-OCStackResult DeleteKeepAliveResource()
+OCStackResult OCDeleteKeepAliveResource()
 {
-    OIC_LOG(DEBUG, TAG, "DeleteKeepAliveResource IN");
+    OIC_LOG(DEBUG, TAG, "OCDeleteKeepAliveResource IN");
 
     // Create a KeepAlive resource
     OCStackResult result = OCDeleteResource(g_keepAliveHandle);
@@ -345,17 +447,17 @@ OCStackResult DeleteKeepAliveResource()
         OIC_LOG_V(ERROR, TAG, "Delete resource for KeepAlive failed[%d]", result);
     }
 
-    OIC_LOG(DEBUG, TAG, "DeleteKeepAliveResource OUT");
+    OIC_LOG(DEBUG, TAG, "OCDeleteKeepAliveResource OUT");
     return result;
 }
 
-OCStackResult HandleKeepAliveRequest(OCServerRequest *request,
-                                     const OCResource *resource)
+OCStackResult OCHandleKeepAliveRequest(OCServerRequest *request,
+                                       const OCResource *resource)
 {
     VERIFY_NON_NULL(request, FATAL, OC_STACK_INVALID_PARAM);
     VERIFY_NON_NULL(resource, FATAL, OC_STACK_INVALID_PARAM);
 
-    OIC_LOG(DEBUG, TAG, "HandleKeepAliveRequest IN");
+    OIC_LOG(DEBUG, TAG, "OCHandleKeepAliveRequest IN");
 
     OCEntityHandlerResult result = OC_EH_ERROR;
     if (OC_REST_GET == request->method)
@@ -366,7 +468,7 @@ OCStackResult HandleKeepAliveRequest(OCServerRequest *request,
             case OC_OBSERVE_REGISTER:
             case OC_OBSERVE_DEREGISTER:
                 OIC_LOG(DEBUG, TAG, "Received GET request");
-                result = HandleKeepAliveGETRequest(request, resource);
+                result = OCHandleKeepAliveGETRequest(request, resource);
                 break;
             default:
                 OIC_LOG(DEBUG, TAG, "Not Supported by KeepAlive");
@@ -376,7 +478,7 @@ OCStackResult HandleKeepAliveRequest(OCServerRequest *request,
     else if (OC_REST_PUT == request->method || OC_REST_POST == request->method)
     {
         OIC_LOG(DEBUG, TAG, "Received PUT/POST request");
-        result = HandleKeepAlivePOSTRequest(request, resource);
+        result = OCHandleKeepAlivePOSTRequest(request, resource);
     }
     else
     {
@@ -384,18 +486,18 @@ OCStackResult HandleKeepAliveRequest(OCServerRequest *request,
         result = OC_EH_UNAUTHORIZED_REQ;
     }
 
-    OCStackResult ret = SendKeepAliveResponse(request, result);
+    OCStackResult ret = OCSendKeepAliveResponse(request, result);
     if (OC_STACK_OK != ret)
     {
         OIC_LOG_V(ERROR, TAG, "SendKeepAliveResponse failed with result %u", ret);
     }
 
-    OIC_LOG(DEBUG, TAG, "HandleKeepAliveRequest OUT");
+    OIC_LOG(DEBUG, TAG, "OCHandleKeepAliveRequest OUT");
     return ret;
 }
 
-OCStackResult SendKeepAliveResponse(OCServerRequest *request,
-                                    OCEntityHandlerResult result)
+OCStackResult OCSendKeepAliveResponse(OCServerRequest *request,
+                                      OCEntityHandlerResult result)
 {
     VERIFY_NON_NULL(request, FATAL, OC_STACK_INVALID_PARAM);
 
@@ -405,18 +507,19 @@ OCStackResult SendKeepAliveResponse(OCServerRequest *request,
     CAEndpoint_t endpoint = {.adapter = CA_DEFAULT_ADAPTER};
     CopyDevAddrToEndpoint(&request->devAddr, &endpoint);
 
-    uint32_t index = 0;
-    KeepAliveEntry_t *entry = GetEntryFromEndpoint(&endpoint, &index);
+    oc_mutex_lock(g_mutexObjectList);
+    KeepAliveEntry_t *entry = OCGetEntryFromEndpoint(&endpoint);
     int64_t interval = (entry) ? entry->interval : 0;
+    oc_mutex_unlock(g_mutexObjectList);
 
     // Create KeepAlive payload to send response message.
-    OCRepPayload *payload = CreateKeepAlivePayload(interval);
+    OCRepPayload *payload = OCCreateKeepAlivePayload(interval);
 
     // Add resource type/interface name to payload for GET request.
     if (OC_REST_GET == request->method && OC_EH_OK == result)
     {
-        AddResourceTypeNameToPayload(payload);
-        AddResourceInterfaceNameToPayload(payload);
+        OCAddResourceTypeNameToPayload(payload);
+        OCAddResourceInterfaceNameToPayload(payload);
     }
 
     OCEntityHandlerResponse ehResponse = { .ehResult = result,
@@ -429,11 +532,11 @@ OCStackResult SendKeepAliveResponse(OCServerRequest *request,
     return OCDoResponse(&ehResponse);
 }
 
-OCEntityHandlerResult HandleKeepAliveGETRequest(OCServerRequest *request,
-                                                const OCResource *resource)
+OCEntityHandlerResult OCHandleKeepAliveGETRequest(OCServerRequest *request,
+                                                  const OCResource *resource)
 {
-    VERIFY_NON_NULL(request, FATAL, OC_STACK_INVALID_PARAM);
-    VERIFY_NON_NULL(resource, FATAL, OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL(request, FATAL, OC_EH_ERROR);
+    VERIFY_NON_NULL(resource, FATAL, OC_EH_ERROR);
 
     OIC_LOG_V(DEBUG, TAG, "Find Ping resource [%s]", request->resourceUrl);
 
@@ -448,290 +551,163 @@ OCEntityHandlerResult HandleKeepAliveGETRequest(OCServerRequest *request,
     return OC_EH_OK;
 }
 
-OCEntityHandlerResult HandleKeepAlivePOSTRequest(OCServerRequest *request,
-                                                 const OCResource *resource)
+OCEntityHandlerResult OCHandleKeepAlivePOSTRequest(OCServerRequest *request,
+                                                   const OCResource *resource)
 {
-    VERIFY_NON_NULL(request, FATAL, OC_STACK_INVALID_PARAM);
-    VERIFY_NON_NULL(resource, FATAL, OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL(request, FATAL, OC_EH_ERROR);
+    VERIFY_NON_NULL(resource, FATAL, OC_EH_ERROR);
+
+    int64_t interval = 0;
+    OCPayload *ocPayload = NULL;
+    OCStackResult result = OCParsePayload(&ocPayload, PAYLOAD_TYPE_REPRESENTATION,
+                                          request->payload, request->payloadSize);
+    if (OC_STACK_OK != result)
+    {
+        OIC_LOG(ERROR, TAG, "Representation parse failed");
+        return OC_EH_ERROR;
+    }
+    bool findValue = OCRepPayloadGetPropInt((OCRepPayload *) ocPayload, INTERVAL, &interval);
+    if (!findValue)
+    {
+        OIC_LOG(ERROR, TAG, "Can't find the time interval property");
+        OCPayloadDestroy(ocPayload);
+        return OC_EH_BAD_REQ;
+    }
 
     // Get entry from KeepAlive table.
-    CAEndpoint_t endpoint = { .adapter = CA_DEFAULT_ADAPTER };
+    CAEndpoint_t endpoint = { .adapter = OC_ADAPTER_TCP };
     CopyDevAddrToEndpoint(&request->devAddr, &endpoint);
 
-    uint32_t index = 0;
-    KeepAliveEntry_t *entry = GetEntryFromEndpoint(&endpoint, &index);
+    oc_mutex_lock(g_mutexObjectList);
+    KeepAliveEntry_t *entry = OCGetEntryFromEndpoint(&endpoint);
     if (!entry)
     {
         OIC_LOG(ERROR, TAG, "Received the first keepalive message from client");
-        entry = AddKeepAliveEntry(&endpoint, OC_SERVER, NULL);
+        entry = OCAddKeepAliveEntry(&endpoint, OC_SERVER, 0);
         if (!entry)
         {
+            oc_mutex_unlock(g_mutexObjectList);
             OIC_LOG(ERROR, TAG, "Failed to add new keepalive entry");
+            OCPayloadDestroy(ocPayload);
             return OC_EH_INTERNAL_SERVER_ERROR;
         }
     }
 
-    OCPayload *ocPayload = NULL;
-    OCParsePayload(&ocPayload, PAYLOAD_TYPE_REPRESENTATION,
-                   request->payload, request->payloadSize);
-    OCRepPayload *repPayload = (OCRepPayload *)ocPayload;
-
-    int64_t interval = 0;
-    OCRepPayloadGetPropInt(repPayload, INTERVAL, &interval);
     entry->interval = interval;
     OIC_LOG_V(DEBUG, TAG, "Received interval is [%" PRId64 "]", entry->interval);
     entry->timeStamp = OICGetCurrentTime(TIME_IN_US);
+    oc_mutex_unlock(g_mutexObjectList);
 
     OCPayloadDestroy(ocPayload);
-
     return OC_EH_OK;
 }
 
-OCStackResult HandleKeepAliveResponse(const CAEndpoint_t *endPoint,
-                                      OCStackResult responseCode,
-                                      const OCRepPayload *respPayload)
+void OCProcessKeepAlive()
 {
-    VERIFY_NON_NULL(endPoint, FATAL, OC_STACK_INVALID_PARAM);
-
-    OIC_LOG(DEBUG, TAG, "HandleKeepAliveResponse IN");
-
-    // Get entry from KeepAlive table.
-    uint32_t index = 0;
-    KeepAliveEntry_t *entry = GetEntryFromEndpoint(endPoint, &index);
-    if (!entry)
+    oc_mutex_lock(g_mutexObjectList);
+    KeepAliveEntry_t *entry = NULL;
+    KeepAliveEntry_t *tmp = NULL;
+    LL_FOREACH_SAFE(g_keepAliveConnectionTable, entry, tmp)
     {
-        // Receive response message about find /oic/ping request.
-        OIC_LOG(ERROR, TAG, "There is no connection info in KeepAlive table");
-
-        if (OC_STACK_NO_RESOURCE == responseCode)
+        if (entry)
         {
-            OIC_LOG(ERROR, TAG, "Server doesn't have a ping resource");
-            return OC_STACK_ERROR;
-        }
-        else if (OC_STACK_OK == responseCode)
-        {
-            int64_t *recvInterval = NULL;
-            size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
-            OCRepPayloadGetIntArray(respPayload, INTERVAL_ARRAY, &recvInterval, dimensions);
-            size_t serverIntervalSize = calcDimTotal(dimensions);
-
-            entry = AddKeepAliveEntry(endPoint, OC_CLIENT, recvInterval);
-            if (!entry)
-            {
-                OIC_LOG(ERROR, TAG, "Failed to add new KeepAlive entry");
-                return OC_STACK_ERROR;
-            }
-
-            if (serverIntervalSize)
-            {
-                // update interval size with received size of server.
-                entry->intervalSize = serverIntervalSize;
-            }
-
-            // Send first ping message
-            return SendPingMessage(entry);
-        }
-    }
-    else
-    {
-        // Set sentPingMsg values with false.
-        entry->sentPingMsg = false;
-
-        // Check the received interval value.
-        int64_t interval = 0;
-        OCRepPayloadGetPropInt(respPayload, INTERVAL, &interval);
-        OIC_LOG_V(DEBUG, TAG, "Received interval is [%" PRId64 "]", entry->interval);
-    }
-
-    OIC_LOG(DEBUG, TAG, "HandleKeepAliveResponse OUT");
-    return OC_STACK_OK;
-}
-
-void ProcessKeepAlive()
-{
-    if (!g_isKeepAliveInitialized)
-    {
-        OIC_LOG(ERROR, TAG, "KeepAlive not initialized");
-        return;
-    }
-
-    uint32_t len = u_arraylist_length(g_keepAliveConnectionTable);
-
-    for (uint32_t i = 0; i < len; i++)
-    {
-        KeepAliveEntry_t *entry = (KeepAliveEntry_t *)u_arraylist_get(g_keepAliveConnectionTable,
-                                                                      i);
-        if (NULL == entry)
-        {
-            continue;
-        }
-
-        uint64_t currentTime = OICGetCurrentTime(TIME_IN_US);
-        if (OC_CLIENT == entry->mode)
-        {
-            if (entry->sentPingMsg)
+            uint64_t currentTime = OICGetCurrentTime(TIME_IN_US);
+            if (OC_CLIENT == entry->mode)
             {
-                /*
-                 * If an OIC Client does not receive the response within 1 minutes,
-                 * terminate the connection.
-                 * In this case the timeStamp means last time sent ping message.
-                 */
-                if ((KEEPALIVE_RESPONSE_TIMEOUT_SEC * USECS_PER_SEC) <= currentTime - entry->timeStamp)
+                if (entry->sentPingMsg)
                 {
-                    OIC_LOG(DEBUG, TAG, "Client does not receive the response within 1 minutes.");
+                    /*
+                     * If an OIC Client does not receive the response within 1 minutes,
+                     * terminate the connection.
+                     * In this case the timeStamp means last time sent ping message.
+                     */
+                    if ((KEEPALIVE_RESPONSE_TIMEOUT_SEC * USECS_PER_SEC) <= currentTime - entry->timeStamp)
+                    {
+                        OIC_LOG(DEBUG, TAG, "Client does not receive the response within 1 minutes.");
 
-                    // Send message to disconnect session.
-                    SendDisconnectMessage(entry);
+                        // Send message to disconnect session.
+                        OCSendDisconnectMessage(entry);
+                    }
                 }
             }
-            else
+            else if (OC_SERVER == entry->mode)
             {
+                /*
+                 * If an OIC Server does not receive a PUT/POST request to ping resource
+                 * within the specified interval time, terminate the connection.
+                 * In this case the timeStamp means last time received ping message.
+                 */
                 if ((entry->interval * KEEPALIVE_RESPONSE_TIMEOUT_SEC * USECS_PER_SEC)
                         <= currentTime - entry->timeStamp)
                 {
-                    // Increase interval value.
-                    IncreaseInterval(entry);
-
-                    OCStackResult result = SendPingMessage(entry);
-                    if (OC_STACK_OK != result)
-                    {
-                        OIC_LOG(ERROR, TAG, "Failed to send ping request");
-                        continue;
-                    }
+                    OIC_LOG(DEBUG, TAG, "Server does not receive a PUT/POST request.");
+                    OCSendDisconnectMessage(entry);
                 }
             }
         }
-        else if (OC_SERVER == entry->mode)
-        {
-            /*
-             * If an OIC Server does not receive a PUT request to ping resource
-             * within the specified interval time, terminate the connection.
-             * In this case the timeStamp means last time received ping message.
-             */
-            if ((entry->interval * KEEPALIVE_RESPONSE_TIMEOUT_SEC * USECS_PER_SEC)
-                    <= currentTime - entry->timeStamp)
-            {
-                OIC_LOG(DEBUG, TAG, "Server does not receive a PUT request.");
-                SendDisconnectMessage(entry);
-            }
-        }
     }
+    oc_mutex_unlock(g_mutexObjectList);
 }
 
-void IncreaseInterval(KeepAliveEntry_t *entry)
+OCStackResult OCSendDisconnectMessage(const KeepAliveEntry_t *entry)
 {
-    VERIFY_NON_NULL_NR(entry, FATAL);
+    VERIFY_NON_NULL(entry, FATAL, OC_STACK_INVALID_PARAM);
 
-    OIC_LOG_V(DEBUG, TAG, "Total interval counts: %zu", entry->intervalSize);
-    if (entry->intervalSize > (size_t)entry->currIndex + 1)
+    // notify application that a client does not receive a response.
+    ClientCB *cbNode = GetClientCB(NULL, 0, entry->handle, NULL);
+    if (cbNode)
     {
-        entry->currIndex++;
-        entry->interval = entry->intervalInfo[entry->currIndex];
-        OIC_LOG_V(DEBUG, TAG, "increase interval value [%" PRId64 "]", entry->interval);
+        OCClientResponse response = { .devAddr = { .adapter = OC_DEFAULT_ADAPTER } };
+        CopyEndpointToDevAddr(&entry->remoteAddr, &response.devAddr);
+        FixUpClientResponse(&response);
+        response.resourceUri = cbNode->requestUri;
+        response.result = OC_STACK_TIMEOUT;
+
+        cbNode->callBack(cbNode->context, cbNode->handle, &response);
+        FindAndDeleteClientCB(cbNode);
     }
-}
 
-OCStackResult SendDisconnectMessage(const KeepAliveEntry_t *entry)
-{
-    VERIFY_NON_NULL(entry, FATAL, OC_STACK_INVALID_PARAM);
+    CAEndpoint_t endpoint = entry->remoteAddr;
+    if (OC_STACK_OK != OCRemoveKeepAliveEntry(&endpoint))
+    {
+        OIC_LOG(ERROR, TAG, "OCRemoveKeepAliveEntry is failed");
+        return OC_STACK_ERROR;
+    }
 
     /*
      * Send empty message to disconnect a connection.
      * If CA get the empty message from RI, CA will disconnect a connection.
      */
-
-    OCStackResult result = RemoveKeepAliveEntry(&entry->remoteAddr);
-    if (result != OC_STACK_OK)
+    CAResult_t result = CAUtilTCPDisconnectSession(endpoint.addr, endpoint.port, endpoint.flags);
+    if (OC_STACK_OK != CAResultToOCResult(result))
     {
-        return result;
+        OIC_LOG(ERROR, TAG, "Failed to disconnect session");
     }
 
-    CARequestInfo_t requestInfo = { .method = CA_POST };
-    result = CASendRequest(&entry->remoteAddr, &requestInfo);
     return CAResultToOCResult(result);
 }
 
-OCStackResult SendPingMessage(KeepAliveEntry_t *entry)
-{
-    VERIFY_NON_NULL(entry, FATAL, OC_STACK_INVALID_PARAM);
-
-    // Send ping message.
-    OCCallbackData pingData = { .context = NULL, .cb = PingRequestCallback };
-    OCDevAddr devAddr = { .adapter = OC_ADAPTER_TCP };
-    CopyEndpointToDevAddr(&(entry->remoteAddr), &devAddr);
-
-    OCRepPayload *payload = CreateKeepAlivePayload(entry->interval);
-    OCStackResult result = OCDoResource(NULL, OC_REST_POST, KEEPALIVE_RESOURCE_URI, &devAddr,
-                                        (OCPayload *) payload, CT_ADAPTER_TCP, OC_LOW_QOS,
-                                        &pingData, NULL, 0);
-    if (OC_STACK_OK != result)
-    {
-        OIC_LOG(ERROR, TAG, "OCDoResource has failed");
-        return result;
-    }
-
-    // Update timeStamp with time sent ping message for next ping message.
-    entry->timeStamp = OICGetCurrentTime(TIME_IN_US);
-    entry->sentPingMsg = true;
-
-    OIC_LOG_V(DEBUG, TAG, "Client sent ping message, interval [%" PRId64 "]", entry->interval);
-
-    return OC_STACK_OK;
-}
-
-OCStackApplicationResult PingRequestCallback(void* ctx, OCDoHandle handle,
-                                             OCClientResponse *clientResponse)
-{
-    (void) ctx;
-    (void) handle;
-    if (NULL == clientResponse)
-    {
-        OIC_LOG(ERROR, TAG, "clientResponse is NULL");
-        return OC_STACK_DELETE_TRANSACTION;
-    }
-
-    CAEndpoint_t endpoint = { .adapter = CA_ADAPTER_TCP };
-    CopyDevAddrToEndpoint(&(clientResponse->devAddr), &endpoint);
-
-    HandleKeepAliveResponse(&endpoint, clientResponse->result,
-                            (OCRepPayload *)clientResponse->payload);
-
-    return OC_STACK_DELETE_TRANSACTION;
-}
-
-KeepAliveEntry_t *GetEntryFromEndpoint(const CAEndpoint_t *endpoint, uint32_t *index)
+KeepAliveEntry_t *OCGetEntryFromEndpoint(const CAEndpoint_t *endpoint)
 {
-    if (!g_keepAliveConnectionTable)
+    KeepAliveEntry_t *entry = NULL;
+    LL_FOREACH(g_keepAliveConnectionTable, entry)
     {
-        OIC_LOG(ERROR, TAG, "KeepAlive Table was not Created.");
-        return NULL;
-    }
-
-    uint32_t len = u_arraylist_length(g_keepAliveConnectionTable);
-
-    for (uint32_t i = 0; i < len; i++)
-    {
-        KeepAliveEntry_t *entry = (KeepAliveEntry_t *)u_arraylist_get(g_keepAliveConnectionTable,
-                                                                      i);
-        if (NULL == entry)
-        {
-            continue;
-        }
-
-        if (!strncmp(entry->remoteAddr.addr, endpoint->addr, sizeof(entry->remoteAddr.addr))
-                && (entry->remoteAddr.port == endpoint->port))
+        if (entry)
         {
-            OIC_LOG(DEBUG, TAG, "Connection Info found in KeepAlive table");
-            *index = i;
-            return entry;
+            if (!strncmp(entry->remoteAddr.addr, endpoint->addr, sizeof(entry->remoteAddr.addr))
+                    && (entry->remoteAddr.port == endpoint->port))
+            {
+                OIC_LOG(DEBUG, TAG, "Connection Info found in KeepAlive table");
+                return entry;
+            }
         }
     }
 
     return NULL;
 }
 
-KeepAliveEntry_t *AddKeepAliveEntry(const CAEndpoint_t *endpoint, OCMode mode,
-                                    int64_t *intervalInfo)
+KeepAliveEntry_t *OCAddKeepAliveEntry(const CAEndpoint_t *endpoint, OCMode mode,
+                                      int64_t interval)
 {
     if (!endpoint)
     {
@@ -739,12 +715,6 @@ KeepAliveEntry_t *AddKeepAliveEntry(const CAEndpoint_t *endpoint, OCMode mode,
         return NULL;
     }
 
-    if (!g_keepAliveConnectionTable)
-    {
-        OIC_LOG(ERROR, TAG, "KeepAlive Table was not Created.");
-        return NULL;
-    }
-
     KeepAliveEntry_t *entry = (KeepAliveEntry_t *) OICCalloc(1, sizeof(KeepAliveEntry_t));
     if (NULL == entry)
     {
@@ -759,96 +729,81 @@ KeepAliveEntry_t *AddKeepAliveEntry(const CAEndpoint_t *endpoint, OCMode mode,
     entry->remoteAddr.ifindex = endpoint->ifindex;
     entry->remoteAddr.port = endpoint->port;
     strncpy(entry->remoteAddr.addr, endpoint->addr, sizeof(entry->remoteAddr.addr));
+    entry->interval = interval;
 
-    entry->intervalSize = DEFAULT_INTERVAL_COUNT;
-    entry->intervalInfo = intervalInfo;
-    if (!entry->intervalInfo)
-    {
-        entry->intervalInfo = (int64_t*) OICMalloc(entry->intervalSize * sizeof(int64_t));
-        for (size_t i = 0; i < entry->intervalSize; i++)
-        {
-            entry->intervalInfo[i] = KEEPALIVE_MIN_INTERVAL << i;
-        }
-    }
-    entry->interval = entry->intervalInfo[0];
-
-    bool result = u_arraylist_add(g_keepAliveConnectionTable, (void *)entry);
-    if (!result)
-    {
-        OIC_LOG(ERROR, TAG, "Adding node to head failed");
-        OICFree(entry->intervalInfo);
-        OICFree(entry);
-        return NULL;
-    }
-
+    LL_APPEND(g_keepAliveConnectionTable, entry);
     return entry;
 }
 
-OCStackResult RemoveKeepAliveEntry(const CAEndpoint_t *endpoint)
+OCStackResult OCRemoveKeepAliveEntry(const CAEndpoint_t *endpoint)
 {
+    OIC_LOG(DEBUG, TAG, "OCRemoveKeepAliveEntry IN");
+
     VERIFY_NON_NULL(endpoint, FATAL, OC_STACK_INVALID_PARAM);
 
-    uint32_t index = 0;
-    KeepAliveEntry_t *entry = GetEntryFromEndpoint(endpoint, &index);
-    if (!entry)
+    KeepAliveEntry_t *entry = NULL;
+    KeepAliveEntry_t *tmp = NULL;
+    LL_FOREACH_SAFE(g_keepAliveConnectionTable, entry, tmp)
     {
-        OIC_LOG(ERROR, TAG, "There is no entry in keepalive table.");
-        return OC_STACK_ERROR;
-    }
+        if (entry)
+        {
+            if (!strncmp(entry->remoteAddr.addr, endpoint->addr, sizeof(entry->remoteAddr.addr))
+                    && (entry->remoteAddr.port == endpoint->port))
+            {
+                OIC_LOG_V(DEBUG, TAG, "Remove Connection Info from KeepAlive table, "
+                          "remote addr=%s port:%d", entry->remoteAddr.addr,
+                          entry->remoteAddr.port);
 
-    KeepAliveEntry_t *removedEntry = (KeepAliveEntry_t *)
-                                        u_arraylist_remove(g_keepAliveConnectionTable, index);
-    if (NULL == removedEntry)
-    {
-        OIC_LOG(ERROR, TAG, "Removed Entry is NULL");
-        return OC_STACK_ERROR;
+                LL_DELETE(g_keepAliveConnectionTable, entry);
+                OICFree(entry);
+            }
+        }
     }
 
-    OIC_LOG_V(DEBUG, TAG, "Remove Connection Info from KeepAlive table, "
-             "remote addr=%s port:%d", removedEntry->remoteAddr.addr,
-             removedEntry->remoteAddr.port);
-
-    OICFree(entry->intervalInfo);
-    OICFree(removedEntry);
-
+    OIC_LOG(DEBUG, TAG, "OCRemoveKeepAliveEntry OUT");
     return OC_STACK_OK;
 }
 
-void HandleKeepAliveConnCB(const CAEndpoint_t *endpoint, bool isConnected)
+void OCHandleKeepAliveConnCB(const CAEndpoint_t *endpoint, bool isConnected, bool isClient)
 {
+    (void) isClient;
     VERIFY_NON_NULL_NR(endpoint, FATAL);
 
     if (isConnected)
     {
         OIC_LOG(DEBUG, TAG, "Received the connected device information from CA");
-
-        // Send discover message to find ping resource
-        OCCallbackData pingData = {.context = NULL, .cb = PingRequestCallback };
-        OCDevAddr devAddr = { .adapter = OC_ADAPTER_TCP };
-        CopyEndpointToDevAddr(endpoint, &devAddr);
-
-        OCStackResult result = OCDoResource(NULL, OC_REST_DISCOVER, KEEPALIVE_RESOURCE_URI,
-                                            &devAddr, NULL, CT_ADAPTER_TCP, OC_HIGH_QOS,
-                                            &pingData, NULL, 0);
-        if (OC_STACK_OK != result)
-        {
-            OIC_LOG(ERROR, TAG, "OCDoResource has failed");
-            return;
-        }
     }
     else
     {
         OIC_LOG(DEBUG, TAG, "Received the disconnected device information from CA");
 
-        OCStackResult result = RemoveKeepAliveEntry(endpoint);
-        if(result != OC_STACK_OK)
+        // Do nothing because callback will be removed after one min.
+        /*
+        // notify application that the session is disconnected.
+        oc_mutex_lock(g_mutexObjectList);
+        KeepAliveEntry_t *entry = OCGetEntryFromEndpoint(endpoint);
+        if (entry)
         {
-            return;
+            ClientCB *cbNode = GetClientCB(NULL, 0, entry->handle, NULL);
+            if (cbNode)
+            {
+                OCClientResponse response = { .devAddr = { .adapter = OC_ADAPTER_TCP } };
+                CopyEndpointToDevAddr(&entry->remoteAddr, &response.devAddr);
+                FixUpClientResponse(&response);
+                response.resourceUri = cbNode->requestUri;
+                response.result = OC_STACK_COMM_ERROR;
+
+                cbNode->callBack(cbNode->context, cbNode->handle, &response);
+                FindAndDeleteClientCB(cbNode);
+            }
+            OCRemoveKeepAliveEntry(endpoint);
         }
+        oc_mutex_unlock(g_mutexObjectList);
+        */
     }
 }
 
-OCRepPayload *CreateKeepAlivePayload(int64_t interval)
+OCRepPayload *OCCreateKeepAlivePayload(int64_t interval)
 {
     OIC_LOG_V(DEBUG, TAG, "Create KeepAlive Payload, interval is [%" PRId64 "]", interval);
 
@@ -864,7 +819,7 @@ OCRepPayload *CreateKeepAlivePayload(int64_t interval)
     return payload;
 }
 
-OCStackResult AddResourceTypeNameToPayload(OCRepPayload *payload)
+OCStackResult OCAddResourceTypeNameToPayload(OCRepPayload *payload)
 {
     uint8_t numElement = 0;
     OCStackResult res = OCGetNumberOfResourceTypes(g_keepAliveHandle, &numElement);
@@ -872,6 +827,11 @@ OCStackResult AddResourceTypeNameToPayload(OCRepPayload *payload)
     {
         size_t rtDim[MAX_REP_ARRAY_DEPTH] = {numElement, 0, 0};
         char **rt = (char **)OICMalloc(sizeof(char *) * numElement);
+        if (!rt)
+        {
+            OIC_LOG(ERROR, TAG, "Could not allocate memory for rf");
+            return OC_STACK_NO_MEMORY;
+        }
         for (uint8_t i = 0; i < numElement; ++i)
         {
             const char *value = OCGetResourceTypeName(g_keepAliveHandle, i);
@@ -899,7 +859,7 @@ OCStackResult AddResourceTypeNameToPayload(OCRepPayload *payload)
     return res;
 }
 
-OCStackResult AddResourceInterfaceNameToPayload(OCRepPayload *payload)
+OCStackResult OCAddResourceInterfaceNameToPayload(OCRepPayload *payload)
 {
     uint8_t numElement = 0;
     OCStackResult res = OCGetNumberOfResourceInterfaces(g_keepAliveHandle, &numElement);
@@ -907,6 +867,12 @@ OCStackResult AddResourceInterfaceNameToPayload(OCRepPayload *payload)
     {
         size_t ifDim[MAX_REP_ARRAY_DEPTH] = {numElement, 0, 0};
         char **itf = (char **)OICMalloc(sizeof(char *) * numElement);
+        if (!itf)
+        {
+            OIC_LOG(ERROR, TAG, "Could not allocate memory for itf");
+            return OC_STACK_NO_MEMORY;
+        }
+
         for (uint8_t i = 0; i < numElement; ++i)
         {
             const char *value = OCGetResourceInterfaceName(g_keepAliveHandle, i);
index 158bda0..35d2959 100644 (file)
@@ -32,8 +32,7 @@ csdktest_env.PrependUnique(LIBS = [
     'octbstack', 'connectivity_abstraction'
 ])
 if env.get('SECURED') == '1':
-       if env.get('WITH_TCP') == True:
-               csdktest_env.AppendUnique(LIBS = ['mbedtls', 'mbedx509','mbedcrypto'])
+    csdktest_env.AppendUnique(LIBS = ['mbedtls', 'mbedx509','mbedcrypto'])
 
 csdktest_env.AppendUnique(LIBPATH = [
     csdktest_env.get('BUILD_DIR'),
index 0de8db5..ecab7c7 100644 (file)
@@ -31,6 +31,7 @@
 #endif
 #include <ocstack.h>
 #include <logger.h>
+#include "oic_string.h"
 
 #define TAG ("occlient")
 
@@ -67,8 +68,8 @@ int main() {
 
     /* Start a discovery query*/
     char szQueryUri[MAX_QUERY_LENGTH] = { 0 };
-    strcpy(szQueryUri, OC_MULTICAST_DISCOVERY_URI);
-    if (OCDoResource(NULL, OC_REST_GET, szQueryUri, 0, 0, 
+    OICStrcpy(szQueryUri, MAX_QUERY_LENGTH, OC_MULTICAST_DISCOVERY_URI);
+    if (OCDoResource(NULL, OC_REST_GET, szQueryUri, 0, 0,
             CT_DEFAULT, OC_LOW_QOS, 0, 0, 0) != OC_STACK_OK) {
         OIC_LOG(ERROR, TAG, "OCStack resource error");
         return 0;
index d48e5b3..3e145ad 100644 (file)
@@ -27,6 +27,7 @@ extern "C"
     #include "logger.h"
     #include "oic_malloc.h"
     #include "oic_string.h"
+    #include "oic_time.h"
 }
 
 #include "gtest/gtest.h"
@@ -68,6 +69,7 @@ static char pinNumber;
 static OCDPDev_t peer;
 
 std::chrono::seconds const SHORT_TEST_TIMEOUT = std::chrono::seconds(5);
+std::chrono::seconds const LONG_TEST_TIMEOUT = std::chrono::seconds(300);
 
 //-----------------------------------------------------------------------------
 // Callback functions
@@ -174,6 +176,60 @@ uint8_t InitResourceIndex()
     return 0;
 #endif
 }
+
+class Callback
+{
+    public:
+        Callback(OCClientResponseHandler cb) : m_cb(cb), m_called(false)
+        {
+            m_cbData.cb = &Callback::handler;
+            m_cbData.cd = NULL;
+            m_cbData.context = this;
+        }
+        void Wait(long waitTime)
+        {
+            uint64_t startTime = OICGetCurrentTime(TIME_IN_MS);
+            while (!m_called)
+            {
+                uint64_t currTime = OICGetCurrentTime(TIME_IN_MS);
+                long elapsed = (long)((currTime - startTime) / MS_PER_SEC);
+                if (elapsed > waitTime)
+                {
+                    m_called = true;
+                }
+                OCProcess();
+            }
+        }
+        operator OCCallbackData *()
+        {
+            return &m_cbData;
+        }
+    private:
+        OCCallbackData m_cbData;
+        OCClientResponseHandler m_cb;
+        bool m_called;
+        static OCStackApplicationResult handler(void *ctx, OCDoHandle handle, OCClientResponse *clientResponse)
+        {
+            Callback *callback = (Callback *) ctx;
+            OCStackApplicationResult result = callback->m_cb(NULL, handle, clientResponse);
+            callback->m_called = true;
+            return result;
+        }
+};
+
+class OCDiscoverTests : public testing::Test
+{
+    protected:
+        virtual void SetUp()
+        {
+            EXPECT_EQ(OC_STACK_OK, OCInit("127.0.0.1", 5683, OC_CLIENT_SERVER));
+        }
+
+        virtual void TearDown()
+        {
+            OCStop();
+        }
+};
 //-----------------------------------------------------------------------------
 //  Tests
 //-----------------------------------------------------------------------------
@@ -564,7 +620,7 @@ TEST(StackDiscovery, DISABLED_DoResourceDeviceDiscovery)
 
     /* Start a discovery query*/
     char szQueryUri[MAX_QUERY_LENGTH] = { 0 };
-    strcpy(szQueryUri, OC_RSRVD_WELL_KNOWN_URI);
+    OICStrcpy(szQueryUri, MAX_QUERY_LENGTH, OC_RSRVD_WELL_KNOWN_URI);
     cbData.cb = asyncDoResourcesCallback;
     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
     cbData.cd = NULL;
@@ -606,7 +662,7 @@ TEST(StackResource, DISABLED_UpdateResourceNullURI)
 
     /* Start a discovery query*/
     char szQueryUri[MAX_QUERY_LENGTH] = { 0 };
-    strcpy(szQueryUri, OC_RSRVD_WELL_KNOWN_URI);
+    OICStrcpy(szQueryUri, MAX_QUERY_LENGTH, OC_RSRVD_WELL_KNOWN_URI);
     cbData.cb = asyncDoResourcesCallback;
     cbData.context = (void*)DEFAULT_CONTEXT_VALUE;
     cbData.cd = NULL;
@@ -2141,3 +2197,339 @@ TEST(StackHeaderOption, getHeaderOption)
     EXPECT_EQ(optionData[0], 1);
     EXPECT_EQ(actualDataSize, 8);
 }
+
+static OCStackApplicationResult DiscoverBaslineResource(void *ctx, OCDoHandle handle,
+    OCClientResponse *response)
+{
+    OC_UNUSED(ctx);
+    OC_UNUSED(handle);
+    EXPECT_EQ(OC_STACK_OK, response->result);
+    EXPECT_TRUE(NULL != response->payload);
+    if (NULL != response->payload)
+    {
+        EXPECT_EQ(PAYLOAD_TYPE_DISCOVERY, response->payload->type);
+
+        OCDiscoveryPayload *payload = (OCDiscoveryPayload *)response->payload;
+        EXPECT_TRUE(NULL != payload->sid);
+        if (payload->name)
+        {
+            EXPECT_STREQ("StackTest", payload->name);
+        }
+        EXPECT_STREQ(OC_RSRVD_RESOURCE_TYPE_RES, payload->type->value);
+        EXPECT_STREQ(OC_RSRVD_INTERFACE_LL, payload->iface->value);
+        EXPECT_STREQ(OC_RSRVD_INTERFACE_DEFAULT, payload->iface->next->value);
+
+        for (OCResourcePayload *resource = payload->resources; resource; resource = resource->next)
+        {
+            if (0 == strcmp("/a/light", resource->uri))
+            {
+                EXPECT_STREQ("/a/light", resource->uri);
+                EXPECT_STREQ("core.light", resource->types->value);
+                EXPECT_EQ(NULL, resource->types->next);
+                EXPECT_STREQ("oic.if.baseline", resource->interfaces->value);
+                EXPECT_EQ(NULL, resource->interfaces->next);
+                EXPECT_TRUE(resource->bitmap & OC_DISCOVERABLE);
+                EXPECT_TRUE(resource->bitmap & OC_OBSERVABLE);
+                EXPECT_FALSE(resource->secure);
+                EXPECT_EQ(0, resource->port);
+                EXPECT_EQ(NULL, resource->next);
+            }
+        }
+    }
+
+    return OC_STACK_DELETE_TRANSACTION;
+}
+
+static OCStackApplicationResult DiscoverLinkedListResource(void *ctx, OCDoHandle handle,
+    OCClientResponse *response)
+{
+    OC_UNUSED(ctx);
+    OC_UNUSED(handle);
+    EXPECT_EQ(OC_STACK_OK, response->result);
+    EXPECT_TRUE(NULL != response->payload);
+    if (NULL != response->payload)
+    {
+        EXPECT_EQ(PAYLOAD_TYPE_DISCOVERY, response->payload->type);
+
+        OCDiscoveryPayload *payload = (OCDiscoveryPayload *)response->payload;
+        EXPECT_NE((char *)NULL, payload->sid);
+        EXPECT_EQ(NULL, payload->name);
+        EXPECT_EQ(NULL, payload->type);
+        EXPECT_EQ(NULL, payload->iface);
+
+        for (OCResourcePayload *resource = payload->resources; resource; resource = resource->next)
+        {
+            if (0 == strcmp("/a/light", resource->uri))
+            {
+                EXPECT_STREQ("/a/light", resource->uri);
+                EXPECT_STREQ("core.light", resource->types->value);
+                EXPECT_EQ(NULL, resource->types->next);
+                EXPECT_STREQ("oic.if.baseline", resource->interfaces->value);
+                EXPECT_EQ(NULL, resource->interfaces->next);
+                EXPECT_TRUE(resource->bitmap & OC_DISCOVERABLE);
+                EXPECT_TRUE(resource->bitmap & OC_OBSERVABLE);
+                EXPECT_FALSE(resource->secure);
+                EXPECT_EQ(0, resource->port);
+                EXPECT_EQ(NULL, resource->next);
+            }
+        }
+    }
+    return OC_STACK_DELETE_TRANSACTION;
+}
+
+
+static OCStackApplicationResult DiscoverResourceTypeResponse(void *ctx, OCDoHandle handle,
+    OCClientResponse *response)
+{
+    OC_UNUSED(ctx);
+    OC_UNUSED(handle);
+    EXPECT_EQ(OC_STACK_OK, response->result);
+    EXPECT_TRUE(NULL != response->payload);
+    if (NULL != response->payload)
+    {
+        EXPECT_EQ(PAYLOAD_TYPE_DISCOVERY, response->payload->type);
+
+        OCDiscoveryPayload *payload = (OCDiscoveryPayload *)response->payload;
+        EXPECT_NE((char *)NULL, payload->sid);
+        EXPECT_EQ(NULL, payload->name);
+        EXPECT_EQ(NULL, payload->type);
+        EXPECT_EQ(NULL, payload->iface);
+        EXPECT_TRUE(NULL != payload->resources);
+
+        OCResourcePayload *resource = payload->resources;
+
+        if (0 == strcmp("/a/light", resource->uri))
+        {
+            EXPECT_STREQ("/a/light", resource->uri);
+            EXPECT_STREQ("core.light", resource->types->value);
+            EXPECT_EQ(NULL, resource->types->next);
+            EXPECT_STREQ("oic.if.baseline", resource->interfaces->value);
+            EXPECT_EQ(NULL, resource->interfaces->next);
+            EXPECT_TRUE(resource->bitmap & OC_DISCOVERABLE);
+            EXPECT_TRUE(resource->bitmap & OC_OBSERVABLE);
+            EXPECT_FALSE(resource->secure);
+            EXPECT_EQ(0, resource->port);
+            EXPECT_EQ(NULL, resource->next);
+        }
+    }
+
+    return OC_STACK_DELETE_TRANSACTION;
+}
+
+static OCStackApplicationResult DiscoverNoResource(void *ctx, OCDoHandle handle,
+    OCClientResponse *response)
+{
+    OC_UNUSED(ctx);
+    OC_UNUSED(handle);
+    EXPECT_EQ(OC_STACK_OK, response->result);
+    EXPECT_TRUE(NULL != response->payload);
+    if (NULL != response->payload)
+    {
+        EXPECT_EQ(PAYLOAD_TYPE_DISCOVERY, response->payload->type);
+
+        OCDiscoveryPayload *payload = (OCDiscoveryPayload *)response->payload;
+        EXPECT_EQ(NULL, payload->sid);
+        EXPECT_EQ(NULL, payload->name);
+        EXPECT_EQ(NULL, payload->type);
+        EXPECT_EQ(NULL, payload->iface);
+
+        bool resourceFound = false;
+        for (OCResourcePayload *resource = payload->resources; resource; resource = resource->next)
+        {
+            if (0 == strcmp("/a/light", resource->uri))
+            {
+                resourceFound = true;
+            }
+        }
+
+        EXPECT_FALSE(resourceFound);
+    }
+    return OC_STACK_DELETE_TRANSACTION;
+}
+
+static OCStackApplicationResult DiscoverUnicastErrorResponse(void *ctx, OCDoHandle handle,
+    OCClientResponse *response)
+{
+    OC_UNUSED(ctx);
+    OC_UNUSED(handle);
+    EXPECT_NE(OC_STACK_OK, response->result);
+    EXPECT_TRUE(NULL == response->payload);
+
+    return OC_STACK_DELETE_TRANSACTION;
+}
+
+TEST_F(OCDiscoverTests, DiscoverResourceWithInterfaceBaselineQuery)
+{
+   itst::DeadmanTimer killSwitch(LONG_TEST_TIMEOUT);
+
+    OCResourceHandle handles;
+    EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handles, "core.light", "oic.if.baseline", "/a/light",
+        entityHandler, NULL, (OC_DISCOVERABLE | OC_OBSERVABLE)));
+    OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DEVICE_NAME, "StackTest");
+    Callback discoverCB(&DiscoverBaslineResource);
+    EXPECT_EQ(OC_STACK_OK, OCDoResource(NULL, OC_REST_DISCOVER, "/oic/res?if=oic.if.baseline", NULL,
+        0, CT_DEFAULT, OC_HIGH_QOS, discoverCB, NULL, 0));
+    discoverCB.Wait(100);
+}
+
+TEST_F(OCDiscoverTests, DiscoverResourceWithoutAnyQuery)
+{
+   itst::DeadmanTimer killSwitch(LONG_TEST_TIMEOUT);
+
+    OCResourceHandle handles;
+    EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handles, "core.light", "oic.if.baseline", "/a/light",
+        entityHandler, NULL, (OC_DISCOVERABLE | OC_OBSERVABLE)));
+    OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, "deviceName", "StackTest");
+    Callback discoverCB(&DiscoverLinkedListResource);
+    EXPECT_EQ(OC_STACK_OK, OCDoResource(NULL, OC_REST_DISCOVER, "/oic/res", NULL, 0, CT_DEFAULT,
+        OC_HIGH_QOS, discoverCB, NULL, 0));
+    discoverCB.Wait(100);
+}
+
+TEST_F(OCDiscoverTests, DiscoverResourceWithInterfaceLinkedListQuery)
+{
+    itst::DeadmanTimer killSwitch(LONG_TEST_TIMEOUT);
+
+    OCResourceHandle handles;
+    EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handles, "core.light", "oic.if.baseline", "/a/light",
+        entityHandler, NULL, (OC_DISCOVERABLE | OC_OBSERVABLE)));
+    OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, "deviceName", "StackTest");
+    Callback discoverCB(&DiscoverLinkedListResource);
+    EXPECT_EQ(OC_STACK_OK, OCDoResource(NULL, OC_REST_DISCOVER, "/oic/res?if=oic.if.ll", NULL, 0,
+        CT_DEFAULT, OC_HIGH_QOS, discoverCB, NULL, 0));
+    discoverCB.Wait(100);
+}
+
+TEST_F(OCDiscoverTests, DiscoverResourceWithResourceTypeQuery)
+{
+    itst::DeadmanTimer killSwitch(LONG_TEST_TIMEOUT);
+
+    OCResourceHandle handles;
+    EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handles, "core.light", "oic.if.baseline", "/a/light",
+        entityHandler, NULL, (OC_DISCOVERABLE | OC_OBSERVABLE)));
+    OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, "deviceName", "StackTest");
+    Callback discoverCB(&DiscoverResourceTypeResponse);
+    EXPECT_EQ(OC_STACK_OK, OCDoResource(NULL, OC_REST_DISCOVER, "/oic/res?rt=core.light", NULL, 0,
+        CT_DEFAULT, OC_HIGH_QOS, discoverCB, NULL, 0));
+    discoverCB.Wait(100);
+}
+
+TEST_F(OCDiscoverTests, DiscoverResourceWithInvalidInterfaceQuery_Unicast)
+{
+    itst::DeadmanTimer killSwitch(LONG_TEST_TIMEOUT);
+
+    OCResourceHandle handles;
+    EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handles, "core.light", "oic.if.baseline", "/a/light",
+        entityHandler, NULL, (OC_DISCOVERABLE | OC_OBSERVABLE)));
+    OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, "deviceName", "StackTest");
+    Callback discoverCB(&DiscoverUnicastErrorResponse);
+    char targetUri[MAX_URI_LENGTH * 2] ={ 0, };
+    snprintf(targetUri, MAX_URI_LENGTH * 2, "127.0.0.1/oic/res?if=invalid");
+    EXPECT_EQ(OC_STACK_OK, OCDoResource(NULL, OC_REST_DISCOVER, targetUri, NULL, 0,
+    CT_DEFAULT, OC_HIGH_QOS, discoverCB, NULL, 0));
+    discoverCB.Wait(100);
+}
+
+TEST_F(OCDiscoverTests, DiscoverResourceWithoutInterfaceQuery_Unicast)
+{
+    itst::DeadmanTimer killSwitch(LONG_TEST_TIMEOUT);
+
+    OCResourceHandle handles;
+    EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handles, "core.light", "oic.if.baseline", "/a/light",
+        entityHandler, NULL, (OC_DISCOVERABLE | OC_OBSERVABLE)));
+    OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, "deviceName", "StackTest");
+    Callback discoverCB(&DiscoverUnicastErrorResponse);
+    char targetUri[MAX_URI_LENGTH * 2] ={ 0, };
+    snprintf(targetUri, MAX_URI_LENGTH * 2, "127.0.0.1/oic/res?if=");
+    EXPECT_EQ(OC_STACK_OK, OCDoResource(NULL, OC_REST_DISCOVER, targetUri, NULL, 0, CT_DEFAULT,
+    OC_HIGH_QOS, discoverCB, NULL, 0));
+    discoverCB.Wait(10);
+}
+
+TEST_F(OCDiscoverTests, DiscoverResourceWithInvalidResourceTypeQuery_Unicast)
+{
+    itst::DeadmanTimer killSwitch(LONG_TEST_TIMEOUT);
+
+    OCResourceHandle handles;
+    EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handles, "core.light", "oic.if.baseline", "/a/light",
+        entityHandler, NULL, (OC_DISCOVERABLE | OC_OBSERVABLE)));
+    OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, "deviceName", "StackTest");
+    Callback discoverCB(&DiscoverUnicastErrorResponse);
+    char targetUri[MAX_URI_LENGTH * 2] ={ 0, };
+    snprintf(targetUri, MAX_URI_LENGTH * 2, "127.0.0.1/oic/res?rt=invalid");
+    EXPECT_EQ(OC_STACK_OK, OCDoResource(NULL, OC_REST_DISCOVER, targetUri, NULL, 0,
+    CT_DEFAULT, OC_HIGH_QOS, discoverCB, NULL, 0));
+    discoverCB.Wait(10);
+}
+
+TEST_F(OCDiscoverTests, DiscoverResourceWithoutResourceTypeQuery_Unicast)
+{
+    itst::DeadmanTimer killSwitch(LONG_TEST_TIMEOUT);
+
+    OCResourceHandle handles;
+    EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handles, "core.light", "oic.if.baseline", "/a/light",
+        entityHandler, NULL, (OC_DISCOVERABLE | OC_OBSERVABLE)));
+    OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, "deviceName", "StackTest");
+    Callback discoverCB(&DiscoverUnicastErrorResponse);
+    char targetUri[MAX_URI_LENGTH * 2] ={ 0, };
+    snprintf(targetUri, MAX_URI_LENGTH * 2, "127.0.0.1/oic/res?rt=");
+    EXPECT_EQ(OC_STACK_OK, OCDoResource(NULL, OC_REST_DISCOVER, targetUri, NULL, 0, CT_DEFAULT,
+    OC_HIGH_QOS, discoverCB, NULL, 0));
+    discoverCB.Wait(10);
+}
+
+TEST_F(OCDiscoverTests, DiscoverResourceWithInvalidResourceTypeQuery)
+{
+    itst::DeadmanTimer killSwitch(LONG_TEST_TIMEOUT);
+
+    OCResourceHandle handles;
+    EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handles, "core.light", "oic.if.baseline", "/a/light",
+        entityHandler, NULL, (OC_DISCOVERABLE | OC_OBSERVABLE)));
+    OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, "deviceName", "StackTest");
+    Callback discoverCB(&DiscoverUnicastErrorResponse);
+    EXPECT_EQ(OC_STACK_OK, OCDoResource(NULL, OC_REST_DISCOVER, "/oic/res?rt=invalid", NULL, 0,
+    CT_DEFAULT, OC_HIGH_QOS, discoverCB, NULL, 0));
+    discoverCB.Wait(5);
+}
+
+TEST_F(OCDiscoverTests, DiscoverResourceWithoutResourceTypeQuery)
+{
+    itst::DeadmanTimer killSwitch(LONG_TEST_TIMEOUT);
+
+    OCResourceHandle handles;
+    EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handles, "core.light", "oic.if.baseline", "/a/light",
+        entityHandler, NULL, (OC_DISCOVERABLE | OC_OBSERVABLE)));
+    OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, "deviceName", "StackTest");
+    Callback discoverCB(&DiscoverUnicastErrorResponse);
+    EXPECT_EQ(OC_STACK_OK, OCDoResource(NULL, OC_REST_DISCOVER, "/oic/res?rt=", NULL, 0, CT_DEFAULT,
+    OC_HIGH_QOS, discoverCB, NULL, 0));
+    discoverCB.Wait(5);
+}
+
+TEST_F(OCDiscoverTests, DiscoverResourceWithInvalidInterfaceQuery)
+{
+    itst::DeadmanTimer killSwitch(LONG_TEST_TIMEOUT);
+
+    OCResourceHandle handles;
+    EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handles, "core.light", "oic.if.baseline", "/a/light",
+        entityHandler, NULL, (OC_DISCOVERABLE | OC_OBSERVABLE)));
+    OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, "deviceName", "StackTest");
+    Callback discoverCB(&DiscoverNoResource);
+    EXPECT_EQ(OC_STACK_OK, OCDoResource(NULL, OC_REST_DISCOVER, "/oic/res?if=invalid", NULL, 0,
+        CT_DEFAULT, OC_HIGH_QOS, discoverCB, NULL, 0));
+    discoverCB.Wait(5);
+}
+
+TEST_F(OCDiscoverTests, DiscoverResourceWithoutInterfaceQuery)
+{
+    itst::DeadmanTimer killSwitch(LONG_TEST_TIMEOUT);
+
+    OCResourceHandle handles;
+    EXPECT_EQ(OC_STACK_OK, OCCreateResource(&handles, "core.light", "oic.if.baseline", "/a/light",
+        entityHandler, NULL, (OC_DISCOVERABLE | OC_OBSERVABLE)));
+    OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, "deviceName", "StackTest");
+    Callback discoverCB(&DiscoverNoResource);
+    EXPECT_EQ(OC_STACK_OK, OCDoResource(NULL, OC_REST_DISCOVER, "/oic/res?if=", NULL, 0, CT_DEFAULT,
+        OC_HIGH_QOS, discoverCB, NULL, 0));
+    discoverCB.Wait(5);
+}
index afb0eb2..4896179 100644 (file)
@@ -29,6 +29,7 @@ SConscript('#resource/third_party_libs.scons', 'lib_env')
 examples_env = lib_env.Clone()
 target_os = examples_env.get('TARGET_OS')
 rd_mode = examples_env.get('RD_MODE')
+ble_custom_adv = examples_env.get('BLE_CUSTOM_ADV')
 
 ######################################################################
 # Build flags
@@ -75,6 +76,9 @@ if target_os in ['darwin', 'ios']:
 if examples_env.get('WITH_CLOUD'):
        examples_env.AppendUnique(CPPDEFINES = ['WITH_CLOUD'])
 
+if ble_custom_adv == True:
+               env.AppendUnique(CPPDEFINES = ['BLE_CUSTOM_ADVERTISE'])
+
 if target_os in ['msys_nt', 'windows']:
        examples_env.AppendUnique(LIBS = ['Comctl32', 'Gdi32', 'User32'])
 
index 46b36a6..8f032e7 100644 (file)
@@ -236,7 +236,7 @@ static bool InputPIN(std::string& pin)
 
 int main(void)
 {
-    OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
+    OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink , NULL, NULL};
 
     // Create PlatformConfig object
     PlatformConfig cfg {
index c11105b..9aa6bcc 100644 (file)
Binary files a/resource/examples/oic_svr_db_client_directpairing.dat and b/resource/examples/oic_svr_db_client_directpairing.dat differ
index aebe93d..577582f 100644 (file)
                             "if": ["oic.if.baseline"]\r
                         },\r
                         {\r
-                            "href": "/oic/sec/acl",\r
-                            "rel": "",\r
-                            "rt": ["oic.r.acl"],\r
-                            "if": ["oic.if.baseline"]\r
-                        },\r
-                        {\r
                             "href": "/oic/sec/cred",\r
                             "rel": "",\r
                             "rt": ["oic.r.cred"],\r
@@ -66,8 +60,8 @@
         "rowneruuid": "64706169-7269-6e67-4465-765555494430",\r
         "cm": 2,\r
         "tm": 0,\r
-        "om": 3,\r
-        "sm": 3\r
+        "om": 4,\r
+        "sm": 4\r
         },\r
     "doxm": {\r
         "oxms": [0],\r
index d35ad18..138b960 100644 (file)
Binary files a/resource/examples/oic_svr_db_server.dat and b/resource/examples/oic_svr_db_server.dat differ
index b425999..f6d3dca 100644 (file)
@@ -60,7 +60,7 @@
                             "if": ["oic.if.baseline"]\r
                         }\r
                     ],\r
-                    "permission": 6\r
+                    "permission": 7\r
                 }\r
             ]\r
         },\r
index 0b9eeb5..7e20559 100644 (file)
@@ -62,10 +62,18 @@ public:
 
         m_resourceUri = resourceURI;
 
-        OCPlatform::registerResource(m_resourceHandle, resourceURI, resourceTypeName,
-                                     resourceInterface,
-                                     nullptr,
-                                     OC_DISCOVERABLE);
+        OCStackResult ret = OCPlatform::registerResource(m_resourceHandle,
+                                                         resourceURI,
+                                                         resourceTypeName,
+                                                         resourceInterface,
+                                                         nullptr,
+                                                         OC_DISCOVERABLE);
+
+        if (OC_STACK_OK != ret)
+        {
+            cout << "Resource creation was unsuccessful\n";
+            return;
+        }
 
         m_publishedResourceHandles.push_back(m_resourceHandle);
         cout << "registerResource is called." << endl;
@@ -229,7 +237,7 @@ int main(int argc, char* argv[])
         return -1;
     }
 
-    OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
+    OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink, NULL, NULL};
     PlatformConfig config
     { OC::ServiceType::InProc, ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::LowQos, &ps};
 
index 924e88c..5667b07 100644 (file)
@@ -476,7 +476,7 @@ static FILE* client_open(const char* /*path*/, const char *mode)
 int main(int argc, char* argv[]) {
 
     std::ostringstream requestURI;
-    OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
+    OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink, NULL, NULL};
     try
     {
         printUsage();
@@ -509,8 +509,9 @@ int main(int argc, char* argv[]) {
     PlatformConfig cfg {
         OC::ServiceType::InProc,
         OC::ModeType::Both,
-        "0.0.0.0",
-        0,
+        OCConnectivityType::CT_ADAPTER_IP,
+        OCConnectivityType::CT_ADAPTER_IP,
+        (OCTransportAdapter)(OCTransportAdapter::OC_ADAPTER_IP|OCTransportAdapter::OC_ADAPTER_TCP),
         OC::QualityOfService::HighQos,
         &ps
     };
index 898bca9..e610629 100644 (file)
@@ -600,7 +600,7 @@ static FILE* client_open(const char* /*path*/, const char *mode)
 int main(int argc, char* argv[])
 {
     PrintUsage();
-    OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
+    OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink, NULL, NULL};
 
     if (argc == 1)
     {
@@ -640,8 +640,7 @@ int main(int argc, char* argv[])
     PlatformConfig cfg {
         OC::ServiceType::InProc,
         OC::ModeType::Server,
-        "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
-        0,         // Uses randomly available port
+        (OCTransportAdapter)(OCTransportAdapter::OC_ADAPTER_IP|OCTransportAdapter::OC_ADAPTER_TCP),
         OC::QualityOfService::LowQos,
         &ps
     };
index 3a19a07..1ac687f 100644 (file)
@@ -32,6 +32,23 @@ namespace OC
     */
     namespace CAManager
     {
+        /**
+         *  Data structure to provide the configuration for cautil.
+         */
+        struct CAUtilConfig
+        {
+            /** the flag for ble advertising. */
+            OCTransportBTFlags_t       bleFlag;
+
+            public:
+                CAUtilConfig()
+                    : bleFlag(OC_DEFAULT_BT_FLAGS)
+            {}
+                CAUtilConfig(OCTransportBTFlags_t bleFlag_)
+                    : bleFlag(bleFlag_)
+            {}
+        };
+
         // typedef to get adapter status changes from CA.
         typedef std::function<void(const std::string&, OCConnectivityType,
                                    bool)> ConnectionChangedCallback;
@@ -68,14 +85,94 @@ namespace OC
         */
         uint16_t getAssignedPortNumber(OCTransportAdapter adapter, OCTransportFlags flag);
 
+        /**
+        * Set multicast time to live to control the scope of the multicasts.
+        * @param ttl To be set to any value from 0 to 255.
+        *            Example:
+        *            0: Are restricted to the same host.
+        *            1: Are restricted to the same subnet.
+        *            32: Are restricted to the same site.
+        *            64: Are restricted to the same region.
+        *            128: Are restricted to the same continent.
+        *            255: Are unrestricted in scope.
+        *            We cannot support region, continent and unrestricted in scope.
+        * @return Returns ::OC_STACK_OK if success.
+        */
+        OCStackResult setMulticastTTL(size_t ttl);
+
+        /**
+        * Get multicast time to live.
+        * @param ttl TTL pointer to get the stored multicast time to live.
+        * @return Returns ::OC_STACK_OK if success.
+        */
+        OCStackResult getMulticastTTL(size_t *ttl);
+
+        /**
+         * set BT configure.
+         * @param[in]  config       ::CAUtilConfig data
+         * @return Returns ::OC_STACK_OK if success.
+         */
+        OCStackResult setBTConfigure(const CAUtilConfig& config);
+
+        /**
+         * set CAUtil log preference.
+         * @param[in]  level                     ::OCLogLevel value.
+         * @param[in]  hidePrivateLogEntries     Private Log Entries.
+         *                                       Example:
+         *                                       true : hide private log.
+         *                                       false : show private log.
+         *                                       (privacy : uid, did, access token, etc)
+         */
+        void setLogLevel(OCLogLevel level, bool hidePrivateLogEntries);
+
+        //Custom advertise
+#if defined(__TIZEN__) && defined(LE_ADAPTER) && defined(BLE_CUSTOM_ADVERTISE)
+        OCStackResult setAdvertisementData(const char* data, int length);
+        OCStackResult setScanResponseData(const char* data, int length);
+#endif
+
+        /**
+         * start BLE advertising.
+         * @return Returns ::OC_STACK_OK if success.
+         */
+        OCStackResult startLEAdvertising();
+
+        /**
+         * stop BLE advertising.
+         * @return Returns ::OC_STACK_OK if success.
+         */
+        OCStackResult stopLEAdvertising();
+
+        /**
+         * Disconnect TCP session.
+         * When there is no transmission for a long time.
+         * Some carrier Vendor is blocking data.
+         * Thur, TCP Session is cleaned through this function.
+         * @param[in]   address        Address.
+         * @param[in]   port           Port.
+         * @param[in]   flags          Transport flag.
+         * @return Returns ::OC_STACK_OK if success.
+         */
+        OCStackResult disconnectTCPSession(const char *address,
+                                           uint16_t port,
+                                           OCTransportFlags flags);
+
+        OCStackResult startCAGattServer();
+        OCStackResult stopCAGattServer();
 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
         /**
          * Select the cipher suite for TLS/DTLS handshake.
          * @param cipher  cipher suite (Note : Make sure endianness).
-         *                    0x35   : TLS_RSA_WITH_AES_256_CBC_SHA
-         *                    0xC018 : TLS_ECDH_anon_WITH_AES_128_CBC_SHA
-         *                    0xC037 : TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
-         *                    0xC0AE : TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
+         *                        TLS_RSA_WITH_AES_256_CBC_SHA256          0x3D
+         *                        TLS_RSA_WITH_AES_128_GCM_SHA256          0x009C
+         *                        TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256  0xC02B
+         *                        TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8       0xC0AE
+         *                        TLS_ECDHE_ECDSA_WITH_AES_128_CCM         0xC0AC
+         *                        TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256  0xC023
+         *                        TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384  0xC024
+         *                        TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384  0xC02C
+         *                        TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256    0xC037
+         *                        TLS_ECDH_anon_WITH_AES_128_CBC_SHA       0xC018
          * @param adapter transport adapter type.
          * @return Returns ::OC_STACK_OK if success.
          */
index b453068..63cbe78 100644 (file)
@@ -45,12 +45,19 @@ namespace OC
                         FindCallback& callback,
                         QualityOfService QoS) = 0;
 
-        virtual OCStackResult ListenForResource2(const std::string& serviceUrl,
+        virtual OCStackResult ListenForResourceList(const std::string& serviceUrl,
                         const std::string& resourceType,
                         OCConnectivityType connectivityType,
                         FindResListCallback& callback,
                         QualityOfService QoS) = 0;
 
+        virtual OCStackResult ListenForResourceListWithError(const std::string& serviceUrl,
+                        const std::string& resourceType,
+                        OCConnectivityType connectivityType,
+                        FindResListCallback& callback,
+                        FindErrorCallback& errorCallback,
+                        QualityOfService QoS) = 0;
+
         virtual OCStackResult ListenErrorForResource(const std::string& serviceUrl,
                         const std::string& resourceType,
                         OCConnectivityType connectivityType,
@@ -150,6 +157,16 @@ namespace OC
             const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
             MQTopicCallback& callback, QualityOfService QoS) = 0;
 #endif
+#ifdef TCP_ADAPTER
+        virtual OCStackResult findKeepAliveResource(std::string host,
+                                                    KeepAliveCallback resultCallback) = 0;
+        virtual OCStackResult sendKeepAliveRequest(std::string host, const OCRepresentation& rep,
+                                                   KeepAliveCallback resultCallback) = 0;
+#endif
+        virtual OCStackResult stop() = 0;
+
+        virtual OCStackResult start() = 0;
+
         virtual ~IClientWrapper(){}
     };
 }
index d49dc1b..de5f019 100644 (file)
@@ -71,12 +71,26 @@ namespace OC
 
         virtual OCStackResult stopPresence() = 0;
 
+        virtual OCStackResult notifyAllObservers(
+                    OCResourceHandle resourceHandle,
+                    QualityOfService QoS) = 0;
+
+        virtual OCStackResult notifyListOfObservers(
+                    OCResourceHandle resourceHandle,
+                    ObservationIds& observationIds,
+                    const std::shared_ptr<OCResourceResponse> pResponse,
+                    QualityOfService QoS) = 0;
+
         virtual OCStackResult setDefaultDeviceEntityHandler(EntityHandler entityHandler) = 0;
 
         virtual OCStackResult sendResponse(const std::shared_ptr<OCResourceResponse> pResponse) = 0;
 
         virtual OCStackResult setPropertyValue(OCPayloadType type, const std::string& tag, const std::string& value) = 0;
         virtual OCStackResult getPropertyValue(OCPayloadType type, const std::string& tag, std::string& value) = 0;
+
+        virtual OCStackResult stop() = 0;
+
+        virtual OCStackResult start() = 0;
     };
 }
 
index bbf6a38..ff62d7b 100644 (file)
@@ -56,22 +56,33 @@ namespace OC
                 : callback(cb), clientWrapper(cw){}
         };
 
-        struct ListenContext2
+        struct ListenErrorContext
+        {
+            FindCallback callback;
+            FindErrorCallback errorCallback;
+            std::weak_ptr<IClientWrapper> clientWrapper;
+
+            ListenErrorContext(FindCallback cb1, FindErrorCallback cb2,
+                               std::weak_ptr<IClientWrapper> cw)
+                : callback(cb1), errorCallback(cb2), clientWrapper(cw){}
+        };
+
+        struct ListenResListContext
         {
             FindResListCallback callback;
             std::weak_ptr<IClientWrapper> clientWrapper;
 
-            ListenContext2(FindResListCallback cb, std::weak_ptr<IClientWrapper> cw)
+            ListenResListContext(FindResListCallback cb, std::weak_ptr<IClientWrapper> cw)
                 : callback(cb), clientWrapper(cw){}
         };
 
-        struct ListenErrorContext
+        struct ListenResListWithErrorContext
         {
-            FindCallback callback;
+            FindResListCallback callback;
             FindErrorCallback errorCallback;
             std::weak_ptr<IClientWrapper> clientWrapper;
 
-            ListenErrorContext(FindCallback cb1, FindErrorCallback cb2,
+            ListenResListWithErrorContext(FindResListCallback cb1, FindErrorCallback cb2,
                                std::weak_ptr<IClientWrapper> cw)
                 : callback(cb1), errorCallback(cb2), clientWrapper(cw){}
         };
@@ -108,6 +119,13 @@ namespace OC
             DirectPairingContext(DirectPairingCallback cb) : callback(cb){}
 
         };
+#ifdef TCP_ADAPTER
+        struct KeepAliveContext
+        {
+            KeepAliveCallback callback;
+            KeepAliveContext(KeepAliveCallback cb) : callback(cb){}
+        };
+#endif
 
 #ifdef WITH_MQ
         struct MQTopicContext
@@ -133,10 +151,15 @@ namespace OC
             const std::string& resourceType, OCConnectivityType transportFlags,
             FindCallback& callback, QualityOfService QoS);
 
-        virtual OCStackResult ListenForResource2(const std::string& serviceUrl,
+        virtual OCStackResult ListenForResourceList(const std::string& serviceUrl,
             const std::string& resourceType, OCConnectivityType transportFlags,
             FindResListCallback& callback, QualityOfService QoS);
 
+        virtual OCStackResult ListenForResourceListWithError(const std::string& serviceUrl,
+            const std::string& resourceType, OCConnectivityType connectivityType,
+            FindResListCallback& callback, FindErrorCallback& errorCallback,
+            QualityOfService QoS);
+
         virtual OCStackResult ListenErrorForResource(const std::string& serviceUrl,
             const std::string& resourceType, OCConnectivityType transportFlags,
             FindCallback& callback, FindErrorCallback& errorCallback, QualityOfService QoS);
@@ -227,6 +250,16 @@ namespace OC
             MQTopicCallback& callback, QualityOfService QoS);
 #endif
 
+        virtual OCStackResult stop();
+        virtual OCStackResult start();
+
+#ifdef TCP_ADAPTER
+        virtual OCStackResult findKeepAliveResource(std::string host,
+                                                    KeepAliveCallback resultCallback);
+        virtual OCStackResult sendKeepAliveRequest(std::string host, const OCRepresentation& rep,
+                                                             KeepAliveCallback resultCallback);
+#endif
+
     private:
         void listeningFunc();
         std::string assembleSetResourceUri(std::string uri, const QueryParamsMap& queryParams);
index 0ea25e8..6d54e40 100644 (file)
@@ -65,6 +65,16 @@ namespace OC
 
         virtual OCStackResult stopPresence();
 
+        virtual OCStackResult notifyAllObservers(
+                    OCResourceHandle resourceHandle,
+                    QualityOfService QoS);
+
+        virtual OCStackResult notifyListOfObservers(
+                    OCResourceHandle resourceHandle,
+                    ObservationIds& observationIds,
+                    const std::shared_ptr<OCResourceResponse> pResponse,
+                    QualityOfService QoS);
+
         virtual OCStackResult setDefaultDeviceEntityHandler(EntityHandler entityHandler);
 
         virtual OCStackResult sendResponse(const std::shared_ptr<OCResourceResponse> pResponse);
@@ -72,11 +82,15 @@ namespace OC
         virtual OCStackResult setPropertyValue(OCPayloadType type, const std::string& tag, const std::string& value);
         virtual OCStackResult getPropertyValue(OCPayloadType type, const std::string& tag, std::string& value);
 
+        virtual OCStackResult stop();
+
+        virtual OCStackResult start();
     private:
         void processFunc();
         std::thread m_processThread;
         bool m_threadRun;
         std::weak_ptr<std::recursive_mutex> m_csdkLock;
+        PlatformConfig  m_cfg;
     };
 }
 
index ff2d212..5fb2b92 100644 (file)
@@ -146,6 +146,9 @@ namespace OC
         /** default flags for client. */
         OCConnectivityType         clientConnectivity;
 
+        /** transport type to initialize. */
+        OCTransportAdapter         transportType;
+
         /** not used. */
         std::string                ipAddress;
 
@@ -158,31 +161,52 @@ namespace OC
         /** persistant storage Handler structure (open/read/write/close/unlink). */
         OCPersistentStorage        *ps;
 
+        /** persistant storage Handler structure (open/read/write/close/unlink). */
+        OCPersistentStorage        *psEnc;
+
+        /** persistant storage Handler structure (open/read/write/close/unlink). */
+        OCPersistentStorage        *psRescue;
+
+        /** pointer to save key. */
+        unsigned char*              key;
+
         public:
             PlatformConfig()
                 : serviceType(ServiceType::InProc),
                 mode(ModeType::Both),
                 serverConnectivity(CT_DEFAULT),
                 clientConnectivity(CT_DEFAULT),
+                transportType(OC_DEFAULT_ADAPTER),
                 ipAddress("0.0.0.0"),
                 port(0),
-                QoS(QualityOfService::NaQos),
-                ps(nullptr)
+                QoS(QualityOfService::NaQos),                
+                ps(nullptr),
+                psEnc(nullptr),
+                psRescue(nullptr),
+                key(nullptr)
         {}
             PlatformConfig(const ServiceType serviceType_,
             const ModeType mode_,
             OCConnectivityType serverConnectivity_,
             OCConnectivityType clientConnectivity_,
             const QualityOfService QoS_,
-            OCPersistentStorage *ps_ = nullptr)
+            OCPersistentStorage *ps_ = nullptr,
+            OCPersistentStorage *psEnc_ = nullptr,
+            OCPersistentStorage *psRescue_ = nullptr,
+            unsigned char *key_ = nullptr)
                 : serviceType(serviceType_),
                 mode(mode_),
                 serverConnectivity(serverConnectivity_),
                 clientConnectivity(clientConnectivity_),
+                transportType(OC_DEFAULT_ADAPTER),
                 ipAddress(""),
                 port(0),
-                QoS(QoS_),
-                ps(ps_)
+                QoS(QoS_),                
+                ps(ps_),
+                psEnc(psEnc_),
+                psRescue(psRescue_),
+                key(key_)
+
         {}
             // for backward compatibility
             PlatformConfig(const ServiceType serviceType_,
@@ -190,16 +214,92 @@ namespace OC
             const std::string& ipAddress_,
             const uint16_t port_,
             const QualityOfService QoS_,
-            OCPersistentStorage *ps_ = nullptr)
+            OCPersistentStorage *ps_ = nullptr,
+            OCPersistentStorage *psEnc_ = nullptr,
+            OCPersistentStorage *psRescue_ = nullptr,
+            unsigned char *key_ = nullptr)
                 : serviceType(serviceType_),
                 mode(mode_),
                 serverConnectivity(CT_DEFAULT),
                 clientConnectivity(CT_DEFAULT),
+                transportType(OC_DEFAULT_ADAPTER),
+                ipAddress(ipAddress_),
+                port(port_),
+                QoS(QoS_),                
+                ps(ps_),
+                psEnc(psEnc_),
+                psRescue(psRescue_),
+                key(key_)
+        {}
+
+            PlatformConfig(const ServiceType serviceType_,
+            const ModeType mode_,
+            const std::string& ipAddress_,
+            const uint16_t port_,
+            const OCTransportAdapter transportType_,
+            const QualityOfService QoS_,
+            unsigned char *key_,
+            OCPersistentStorage *ps_ = nullptr,
+            OCPersistentStorage *psEnc_ = nullptr,
+            OCPersistentStorage *psRescue_ = nullptr)
+                : serviceType(serviceType_),
+                mode(mode_),
+                transportType(transportType_),
                 ipAddress(ipAddress_),
                 port(port_),
+                QoS(QoS_),                
+                ps(ps_),
+                psEnc(psEnc_),
+                psRescue(psRescue_),
+                key(key_)
+        {}
+
+           PlatformConfig(const ServiceType serviceType_,
+            const ModeType mode_,
+            OCTransportAdapter transportType_,
+            const QualityOfService QoS_,
+            OCPersistentStorage *ps_ = nullptr,
+            OCPersistentStorage *psEnc_ = nullptr,
+            OCPersistentStorage *psRescue_ = nullptr,
+            unsigned char *key_ = nullptr)
+                : serviceType(serviceType_),
+                mode(mode_),
+                serverConnectivity(CT_DEFAULT),
+                clientConnectivity(CT_DEFAULT),
+                transportType(transportType_),
+                ipAddress(""),
+                port(0),
+                QoS(QoS_),
+                ps(ps_),
+                psEnc(psEnc_),
+                psRescue(psRescue_),
+                key(key_)
+        {}
+            PlatformConfig(const ServiceType serviceType_,
+            const ModeType mode_,
+            OCConnectivityType serverConnectivity_,
+            OCConnectivityType clientConnectivity_,
+            OCTransportAdapter transportType_,
+            const QualityOfService QoS_,
+            OCPersistentStorage *ps_ = nullptr,
+            OCPersistentStorage *psEnc_ = nullptr,
+            OCPersistentStorage *psRescue_ = nullptr,
+            unsigned char *key_ = nullptr)
+                : serviceType(serviceType_),
+                mode(mode_),
+                serverConnectivity(serverConnectivity_),
+                clientConnectivity(clientConnectivity_),
+                transportType(transportType_),
+                ipAddress(""),
+                port(0),
                 QoS(QoS_),
-                ps(ps_)
+                ps(ps_),
+                psEnc(psEnc_),
+                psRescue(psRescue_),
+                key(key_)
         {}
+
     };
 
     enum RequestHandlerFlag
@@ -301,6 +401,9 @@ namespace OC
 
     typedef std::function<void(const int, const std::string&,
                                std::shared_ptr<OCResource>)> MQTopicCallback;
+#ifdef TCP_ADAPTER
+    typedef std::function<void(const int, const OCRepresentation&)> KeepAliveCallback;
+#endif
 } // namespace OC
 
 #endif
index 491f68a..c24d18a 100755 (executable)
 \r
 #include <thread>\r
 \r
+#ifndef __APPLE__\r
 #include "occloudprovisioning.h"\r
+#else\r
+#include "../csdk/security/provisioning/include/cloud/occloudprovisioning.h"\r
+#endif\r
 #include "OCApi.h"\r
 #include "OCPlatform_impl.h"\r
 #include "CAManager.h"\r
index 9903611..84e7163 100644 (file)
@@ -44,12 +44,27 @@ namespace OC
         * @note Any calls made to this AFTER the first call to OCPlatform::Instance
         * will have no affect
         */
-        void Configure(const PlatformConfig& config);
+        OCStackResult Configure(const PlatformConfig& config);
 
         // typedef for handle to cancel presence info with
         typedef OCDoHandle OCPresenceHandle;
 
         /**
+         * API for stop Base layer including resource and connectivity abstraction.
+         *
+         * @return Returns ::OC_STACK_OK if success.
+         */
+        OCStackResult stop();
+
+        /**
+         * API for start Base layer including resource and connectivity abstraction.
+         * OCInit will be invoked.
+         *
+         * @return Returns ::OC_STACK_OK if success.
+         */
+        OCStackResult start();
+
+        /**
          * API for notifying base that resource's attributes have changed.
          *
          * @param resourceHandle resource handle of the resource
@@ -177,6 +192,10 @@ namespace OC
                     OCConnectivityType connectivityType, FindResListCallback resourceHandler,
                     QualityOfService QoS = QualityOfService::LowQos);
 
+        OCStackResult findResourceList(const std::string& host, const std::string& resourceURI,
+                    OCConnectivityType connectivityType, FindResListCallback resourceHandler,
+                    FindErrorCallback errorHandler, QualityOfService QoS = QualityOfService::LowQos);
+
         OCStackResult setPropertyValue(OCPayloadType type, const std::string& tag, const std::string& value);
         OCStackResult setPropertyValue(OCPayloadType type, const std::string& tag, const std::vector<std::string>& value);
         OCStackResult getPropertyValue(OCPayloadType type, const std::string& tag, std::string& value);
@@ -686,6 +705,28 @@ namespace OC
                                                             OCConnectivityType connectivityType);
 #endif // WITH_CLOUD
 
+#ifdef TCP_ADAPTER
+        /**
+         * gets OCRepresentation of KeepAlive resource from given host.
+         *
+         * @param host         Host IP Address of KeepAlive resource
+         * @param resultCallback Function to callback with result code and OCRepresentation.
+         * @return Returns ::OC_STACK_OK if success.
+         */
+        OCStackResult findKeepAliveResource(std::string host, KeepAliveCallback resultCallback);
+
+        /**
+        * send KeepAlive request to given host.
+        *
+        * @param rep            include interval time of expected pong response
+        * @param resultCallback handles callback
+        *
+        * @return Returns  ::OC_STACK_OK on success, some other value upon failure.
+        *
+        */
+        OCStackResult sendKeepAliveRequest(std::string host, const OCRepresentation& rep,
+                                                             KeepAliveCallback resultCallback);
+#endif
         /**
          * gets the deviceId of the client
          *
index 6adefc7..1c3a276 100644 (file)
@@ -52,7 +52,7 @@ namespace OC
     private:
         static PlatformConfig& globalConfig();
     public:
-        static void Configure(const PlatformConfig& config);
+        static OCStackResult Configure(const PlatformConfig& config);
 
         static OCPlatform_impl& Instance();
 
@@ -96,6 +96,10 @@ namespace OC
                     OCConnectivityType connectivityType, FindResListCallback resourceHandler,
                     QualityOfService QoS);
 
+        OCStackResult findResourceList(const std::string& host, const std::string& resourceURI,
+                    OCConnectivityType connectivityType, FindResListCallback resourceHandler,
+                    FindErrorCallback errorHandler, QualityOfService Qos);
+
         OCStackResult getDeviceInfo(const std::string& host, const std::string& deviceURI,
                     OCConnectivityType connectivityType, FindDeviceCallback deviceInfoHandler);
 
@@ -265,12 +269,20 @@ namespace OC
                                                             OCConnectivityType connectivityType);
 #endif // WITH_CLOUD
 
+#ifdef TCP_ADAPTER
+        OCStackResult findKeepAliveResource(std::string host, KeepAliveCallback resultCallback);
+        OCStackResult sendKeepAliveRequest(std::string host, const OCRepresentation& rep,
+                                                             KeepAliveCallback resultCallback);
+#endif
         OCStackResult getDeviceId(OCUUIdentity *myUuid);
 
         OCStackResult setDeviceId(const OCUUIdentity *myUuid);
 
+        OCStackResult stop();
+        OCStackResult start();
     private:
         PlatformConfig m_cfg;
+        OCMode m_modeType;
 
     private:
         std::unique_ptr<WrapperFactory> m_WrapperInstance;
index dd60ced..8db912b 100644 (file)
 #include <thread>
 
 #include "pinoxmcommon.h"
+#ifdef __APPLE__
+#include "../csdk/security/provisioning/include/ocprovisioningmanager.h"
+#else
 #include "ocprovisioningmanager.h"
+#endif
 #include "OCApi.h"
 #include "OCPlatform_impl.h"
+#include "oxmverifycommon.h"
+#include "casecurityinterface.h"
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+#include "mbedtls/x509_crt.h"
+#endif
 
 namespace OC
 {
@@ -38,6 +47,12 @@ namespace OC
     typedef std::function<void(PMResultList_t *result, int hasError)> ResultCallBack;
     typedef std::function<void(uint16_t credId, uint8_t *trustCertChain,
             size_t chainSize)>CertChainCallBack;
+    typedef std::function<OCStackResult(uint8_t verifNum[])> DisplayNumCB;
+    typedef std::function<OCStackResult()> UserConfirmNumCB;
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+    typedef std::function<OCStackResult(const mbedtls_x509_crt *peerCert,
+            int depth)> PeerCertCB;
+#endif
 
     struct ProvisionContext
     {
@@ -50,6 +65,27 @@ namespace OC
         CertChainCallBack callback;
         TrustCertChainContext(CertChainCallBack cb) : callback(cb){}
     };
+
+    struct DisplayNumContext
+    {
+        DisplayNumCB callback;
+        DisplayNumContext(DisplayNumCB cb) : callback(cb){}
+    };
+
+    struct UserConfirmNumContext
+    {
+        UserConfirmNumCB callback;
+        UserConfirmNumContext(UserConfirmNumCB cb) : callback(cb){}
+    };
+
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+    struct PeerCertContext
+    {
+        PeerCertCB callback;
+        PeerCertContext(PeerCertCB cb) : callback(cb){}
+    };
+#endif
+
     /**
      * This class is for credential's to be set to devices.
      * The types supported are
@@ -127,6 +163,13 @@ namespace OC
             static OCStackResult provisionInit(const std::string& dbPath);
 
             /**
+             * API to terminate the OTM process
+             *
+             * @return ::OC_STACK_OK in case of success and other value otherwise.
+             */
+            static OCStackResult terminatePM();
+
+            /**
              * API is responsible for discovery of devices in it's subnet. It will list
              * all the device in subnet which are not yet owned.
              *
@@ -167,15 +210,75 @@ namespace OC
                     std::shared_ptr<OCSecureResource> &foundDevice);
 
             /**
-             * API for registering Ownership transfer methods for a particular transfer Type.
+             * API is responsible for discovery of devices in specified endpoint/deviceID.
+             * And this function will only return the specified device's response.
+             *
+             * @param timeout Timeout in seconds, time until which function will listen to
+             *                    responses from server before returning the specified device.
+             * @param deviceID  deviceID of target device.
+             * @param hostAddress  MAC address of target device.
+             * @param connType  ConnectivityType for discovery.
+             * @param foundDevice OCSecureResource object of found device.
+             * @return ::OC_STACK_OK in case of success and other value otherwise.
+             *         ::OC_STACK_INVALID_PARAM when deviceID is NULL or ppFoundDevice is not
+             *                                  initailized.
+             */
+            static OCStackResult discoverSingleDeviceInUnicast(unsigned short timeout,
+                    const OicUuid_t* deviceID,
+                    const std::string& hostAddress,
+                    OCConnectivityType connType,
+                    std::shared_ptr<OCSecureResource> &foundDevice);
+
+#ifdef MULTIPLE_OWNER
+             /**
+             * API is responsible for discovery of MOT(Mutilple Owner Transfer)
+             * devices in current subnet.
+             *
+             * @param timeout Timeout in seconds, time until which function will listen to
+             *                    responses from server before returning the list of devices.
+             * @param list List of MOT enabled devices.
+             * @return ::OC_STACK_OK in case of success and other value otherwise.
+             */
+            static OCStackResult discoverMultipleOwnerEnabledDevices(unsigned short timeout,
+                    DeviceList_t &list);
+
+             /**
+             * API is responsible for discovery of Multiple owned device in
+             * current subnet.
+             *
+             * @param timeout Timeout in seconds, time until which function will listen to
+             *                    responses from server before returning the list of devices.
+             * @param list List of Multiple Owned devices.
+             * @return ::OC_STACK_OK in case of success and other value otherwise.
+             */
+            static OCStackResult discoverMultipleOwnedDevices(unsigned short timeout,
+                    DeviceList_t &list);
+
+#endif
+
+            /**
+             * API for registering Pin Callback.
              *
-             * @param oxm Ownership transfer method.
-             * @param callbackData CallbackData Methods for ownership transfer.
-             * @param inputPin Callback method to input pin for verification.
+             * @param InputPinCallback inputPin callback function.
              * @return ::OC_STACK_OK in case of success and other value otherwise.
              */
-            static OCStackResult setOwnerTransferCallbackData(OicSecOxm_t oxm,
-                    OTMCallbackData_t* callbackData, InputPinCallback inputPin);
+            static OCStackResult setInputPinCallback(InputPinCallback inputPin);
+
+           /**
+             * API for de-registering Pin Callback.
+             *
+             * @return ::OC_STACK_OK in case of success and other value otherwise.
+             */
+            static OCStackResult unsetInputPinCallback();
+
+            /**
+             * API to set Pin Type policy.
+             *
+             * @param  pinSize pin Size
+             * @param  pinType Type of the pin.
+             * @return OC_STACK_OK in case of success and other value otherwise.
+             */
+            static OCStackResult setRandomPinPolicy(size_t pinSize, OicSecPinType_t pinType);
 
             /**
              * API to get status of all the devices in current subnet. The status include endpoint
@@ -223,6 +326,67 @@ namespace OC
              */
             static OCStackResult saveACL(const OicSecAcl_t* acl);
 
+            /**
+             *  api to register Callback for displaying verifNum in verification Just-Works
+             *
+             * @param displayNumCB Callback which is to be registered.
+             * @return  OC_STACK_OK in case of success and other value otherwise.
+             */
+            static OCStackResult registerDisplayNumCallback(DisplayNumCB displayNumCB);
+
+             /**
+             * API to De-register Callback for displaying verifNum in verification Just-Works
+             *
+             * @return  OC_STACK_OK in case of success and other value otherwise.
+             */
+            static OCStackResult deregisterDisplayNumCallback();
+
+            /**
+             * API to reister Callback for getting user confirmation in verification Just-Works
+             *@param userConfirmCB Callback which is to be registered.
+             * @return  OC_STACK_OK in case of success and other value otherwise.
+             */
+            static OCStackResult registerUserConfirmCallback(UserConfirmNumCB userConfirmCB);
+
+             /**
+             * API to De-register Callback for getting user confirmation in verification Just-Works
+             *
+             * @return  OC_STACK_OK in case of success and other value otherwise.
+             */
+            static OCStackResult deregisterUserConfirmCallback();
+
+             /*
+             * Set option for Mutual Verified Just-Works
+             * The default is both display PIN and get user confirmation.
+             */
+            static OCStackResult setVerifyOptionMask(VerifyOptionBitmask_t optionMask);
+
+            /**
+             * Callback function to display Verification Number.
+             *
+             * @param[in] ctx  User context returned in callback
+             * @param[in] verifNum  Array of MUTUAL_VERIF_NUM_LEN size bytes
+             *
+             * @return OC_STACK_OK in case of success and other value otherwise.
+             */
+            static OCStackResult displayNumCallbackWrapper(void* ctx,
+                    uint8_t verifNum[MUTUAL_VERIF_NUM_LEN]);
+
+             /**
+             * Callback function to get 'Num' verification result.
+             *
+             * @return OC_STACK_OK in case of success and other value otherwise.
+             */
+            static OCStackResult confirmUserCallbackWrapper(void* ctx);
+
+            /**
+             * API to cleanup PDM in case of timeout.
+             * It will remove the PDM_DEVICE_INIT state devices from PDM.
+             *
+             * @return OC_STACK_OK in case of success and other value otherwise.
+             */
+             static OCStackResult pdmCleanupForTimeout();
+
 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
             /**
              * API to save Trust certificate chain into Cred of SVR.
@@ -274,8 +438,38 @@ namespace OC
              */
             static void certCallbackWrapper(void* ctx, uint16_t credId, uint8_t *trustCertChain,
                                 size_t chainSize);
+
+            /**
+             * Wrapper to save the seed value to generate device UUID
+             *
+             * @param[in] seed  buffer of seed value
+             * @param[in] seedSize byte length of seed
+             */
+            static OCStackResult setDeviceIdSeed(const uint8_t* seed, size_t seedSize);
+
+            /**
+             * Callback wrapper for getting peer certificate.
+             *
+             * @param[in] ctx User context returned in callback
+             * @param[in] cert certificate
+             * @param[in] depth depth of chain
+             */
+            static int peerCertCallbackWrapper(void *ctx, const mbedtls_x509_crt *cert,
+                    int depth);
+
+            /**
+             * API to set the function for getting peer certificate.
+             */
+            static OCStackResult setPeerCertCallback(PeerCertCB cb);
 #endif // __WITH_DTLS__ || __WITH_TLS__
 
+            /**
+             * This function configures SVR DB as self-ownership.
+             *
+             *@return OC_STACK_OK in case of successful configue and other value otherwise.
+             */
+            static OCStackResult configSelfOwnership();
+
     };
 
     /**
@@ -430,6 +624,14 @@ namespace OC
              */
             bool getOwnedStatus();
 
+            /**
+             * API to get the proper OxM for OT.
+             *
+             * @param oxm Address to save the selected OxM.
+             *
+             * @return ::OC_STACK_OK in case of success and other value otherwise.
+             */
+            OCStackResult getOTMethod(OicSecOxm_t* oxm);
 
             /**
              * Common callback wrapper, which will be called from OC-APIs.
@@ -437,6 +639,113 @@ namespace OC
             static void callbackWrapper(void* ctx, int nOfRes,
                     OCProvisionResult_t *arr, bool hasError);
 
+#ifdef MULTIPLE_OWNER
+            /**
+             * API to update 'doxm.oxmsel' to resource server.
+             *
+             * @param resultCallback Callback provided by API user, callback will be
+             *            called when credential revocation is finished.
+             * @param oxmSelVal Method of multiple ownership transfer (ref. oic.sec.oxm)
+             * @return  ::OC_STACK_OK in case of success and other value otherwise.
+             */
+            OCStackResult selectMOTMethod( const OicSecOxm_t oxmSelVal,
+                    ResultCallBack resultCallback);
+
+            /**
+             * API to update 'doxm.mom' to resource server.
+             *
+             * @param resultCallback Callback provided by API user, callback will be
+             *            called when credential revocation is finished.
+             * @param momType Mode of multiple ownership transfer (ref. oic.sec.mom)
+             * @return  ::OC_STACK_OK in case of success and other value otherwise.
+             */
+             OCStackResult changeMOTMode( const OicSecMomType_t momType,
+                    ResultCallBack resultCallback);
+
+            /**
+             * API to add preconfigured PIN to local SVR DB.
+             *
+             * @param preconfPIN Preconfig PIN which is used while multiple owner authentication
+             * @param preconfPINLength Byte length of preconfig PIN
+             * @return  ::OC_STACK_OK in case of success and other value otherwise.
+             */
+             OCStackResult addPreconfigPIN(const char* preconfPIN,
+                    size_t preconfPINLength);
+
+            /**
+             * API to provision preconfigured PIN.
+             *
+             * @param resultCallback Callback provided by API user, callback will be called when
+             *            credential revocation is finished.
+             * @param preconfPin Preconfig PIN which is used while multiple owner authentication
+             * @param preconfPinLength Byte length of preconfig PIN
+             * @return  ::OC_STACK_OK in case of success and other value otherwise.
+             */
+             OCStackResult provisionPreconfPin(const char * preconfPin,
+                    size_t preconfPinLength, ResultCallBack resultCallback);
+
+             /**
+             * API to do multiple ownership transfer for MOT enabled device.
+             *
+             * @param resultCallback Result callback function to be invoked when
+             *                           multiple ownership transfer finished.
+             * @return ::OC_STACK_OK in case of success and other value otherwise.
+             */
+            OCStackResult doMultipleOwnershipTransfer(ResultCallBack resultCallback);
+
+            /**
+             * API to remove sub-owner from resource server
+             *
+             * @param[in] subOwner sub-owner UUID to be removed
+             * @param[in] resultCallback callback provided by API user, callback will be invoked when
+             *            DELETE 'subowneruuid' request recieves a response from resource server.
+             * @return ::OC_STACK_OK in case of success and other value otherwise.
+             */
+            OCStackResult removeSubOwner(const OicUuid_t* subOwnerId, ResultCallBack resultCallback);
+
+            /**
+             * API to remove all sub-owner from resource server
+             *
+             * @param[in] resultCallback callback provided by API user, callback will be invoked when
+             *            DELETE 'subowneruuid' request recieves a response from resource server.
+             * @return ::OC_STACK_OK in case of success and other value otherwise.
+             */
+            OCStackResult removeAllSubOwner(ResultCallBack resultCallback);
+
+            /**
+             * API to get a sub-owner list
+             *
+             * @param[out] Sub-owner list of resource server
+             * @return ::OC_STACK_OK in case of success and other value otherwise.
+             */
+            OCStackResult getSubOwnerList(UuidList_t &uuidList);
+
+            /**
+             * API to get the proper OxM for MOT.
+             *
+             * @param oxm Address to save the selected OxM.
+             *
+             * @return ::OC_STACK_OK in case of success and other value otherwise.
+             */
+            OCStackResult getMOTMethod( OicSecOxm_t* oxm);
+
+            /**
+             * API to check whether MOT is supported.
+             *
+             * @return ::true in case of MOT supported.
+             */
+            bool isMOTSupported();
+
+            /**
+             * API to check whether MOT is enabled.
+             *
+             * @return ::true in case of MOT enabled.
+             */
+            bool isMOTEnabled();
+
+
+#endif // MULTIPLE_OWNER
+
         private:
             void validateSecureResource();
     };
index 309b3e5..f37ea45 100644 (file)
@@ -119,7 +119,7 @@ namespace OC
 
             virtual ~OCRepresentation(){}
 
-            void setDevAddr(const OCDevAddr addr);
+            void setDevAddr(const OCDevAddr&);
 
             const std::string getHost() const;
 
@@ -195,8 +195,16 @@ namespace OC
                 {
                     try
                     {
-                        val = boost::get<T>(x->second);
-                        return true;
+                        if (x->second.type() == typeid(T))
+                        {
+                            val = boost::get<T>(x->second);
+                            return true;
+                        }
+                        else
+                        {
+                            val = T();
+                            return false;
+                        }
                     }
                     catch (boost::bad_get& e)
                     {
@@ -228,7 +236,14 @@ namespace OC
                 {
                     try
                     {
-                        val = boost::get<T>(x->second);
+                        if (x->second.type() == typeid(T))
+                        {
+                            val = boost::get<T>(x->second);
+                        }
+                        else
+                        {
+                            return val;
+                        }
                     }
                     catch (boost::bad_get& e)
                     {
@@ -290,15 +305,23 @@ namespace OC
                     template<typename T>
                     T getValue() const
                     {
+                        T val = T();
                         try
                         {
-                            return boost::get<T>(m_values[m_attrName]);
+                            if (m_values[m_attrName].type() == typeid(T))
+                            {
+                                val = boost::get<T>(m_values[m_attrName]);
+                            }
+                            else
+                            {
+                                return val;
+                            }
                         }
                         catch (boost::bad_get& e)
                         {
-                            T val = T();
                             return val;
                         }
+                        return val;
                     }
 
                     std::string getValueToString() const;
index 2167ba6..e1f7bc6 100644 (file)
@@ -117,6 +117,7 @@ namespace OC
             m_uri(std::move(o.m_uri)),
             m_resourceId(std::move(o.m_resourceId)),
             m_devAddr(std::move(o.m_devAddr)),
+            m_deviceName(std::move(o.m_deviceName)),
             m_useHostString(o.m_useHostString),
             m_property(o.m_property),
             m_isCollection(o.m_isCollection),
@@ -485,6 +486,29 @@ namespace OC
         std::string host() const;
 
         /**
+        * Function to set host address information.
+        *
+        * @param host std::string host address
+        *             optionally one of
+        *                   CoAP over UDP prefix    "coap://"
+        *                   CoAP over TCP prefix    "coap+tcp://"
+        *                   CoAP over DTLS prefix   "coaps://"
+        *                   CoAP over TLS prefix    "coaps+tcp://"
+        *                   CoAP over RFCOMM prefix "coap+rfcomm://"
+        *                   CoAP over GATT prefix   "coap+gatt://"
+        *             optionally one of
+        *                   IPv6 address            "[1234::5678]"
+        *                   IPv4 address            "192.168.1.1"
+        *             optional port               ":5683"
+        *
+        * @note This should be in the format coap://address:port.
+        *       If host has different connectivity type with a given OCResource object
+        *       which was discovered after calling findResource API, raise an exception on failure.
+        *
+        */
+        void setHost(const std::string& host);
+
+        /**
         * Function to get the URI for this resource
         * @return std::string resource URI
         */
@@ -502,6 +526,8 @@ namespace OC
         *         not observable.
         */
         bool isObservable() const;
+        
+        OCDevAddr getDevAddr() const;
 
 #ifdef WITH_MQ
         /**
@@ -543,6 +569,13 @@ namespace OC
         */
         std::string sid() const;
 
+        /**
+        * Function to get a string representation of the human friendly name defined by the vendor.
+        * @note The format of the return value is subject to change and will
+        * likely change both in size and contents in the future.
+        */
+        std::string deviceName() const;
+
 #ifdef WITH_MQ
         /**
         * Function to discovery Topics from MQ Broker.
@@ -656,7 +689,6 @@ namespace OC
         bool operator>=(const OCResource &other) const;
 
     private:
-        void setHost(const std::string& host);
         std::weak_ptr<IClientWrapper> m_clientWrapper;
         std::string m_uri;
         OCResourceIdentifier m_resourceId;
@@ -668,6 +700,7 @@ namespace OC
         std::vector<std::string> m_interfaces;
         std::vector<std::string> m_children;
         OCDoHandle m_observeHandle;
+        std::string m_deviceName;
         HeaderOptions m_headerOptions;
 
     private:
@@ -675,14 +708,16 @@ namespace OC
                     const OCDevAddr& devAddr, const std::string& uri,
                     const std::string& serverId, uint8_t property,
                     const std::vector<std::string>& resourceTypes,
-                    const std::vector<std::string>& interfaces);
+                    const std::vector<std::string>& interfaces,
+                    const std::string& deviceName);
 
         OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
                     const std::string& host, const std::string& uri,
                     const std::string& serverId,
                     OCConnectivityType connectivityType, uint8_t property,
                     const std::vector<std::string>& resourceTypes,
-                    const std::vector<std::string>& interfaces);
+                    const std::vector<std::string>& interfaces,
+                    const std::string& deviceName);
     };
 
 } // namespace OC
index b7ba781..e440ab0 100644 (file)
@@ -42,27 +42,30 @@ namespace OC
         public:
             ListenOCContainer(std::weak_ptr<IClientWrapper> cw,
                     OCDevAddr& devAddr, OCDiscoveryPayload* payload)
-                    : m_clientWrapper(cw), m_devAddr(devAddr)
             {
+                OCDevAddr currentDevAddr = devAddr;
+
                 while (payload)
                 {
+                    std::string deviceName;
+                    if (payload->name)
+                    {
+                        deviceName = payload->name;
+                    }
+
                     OCResourcePayload* res = payload->resources;
                     while (res)
                     {
-                        if (res->secure)
-                        {
-                            m_devAddr.flags =
-                                  (OCTransportFlags)(OC_FLAG_SECURE | m_devAddr.flags);
-                        }
 
-                        if (res->port != 0)
-                        {
-                            m_devAddr.port = res->port;
-                        }
+                        currentDevAddr.flags = res->secure ?
+                                (OCTransportFlags)(OC_FLAG_SECURE | devAddr.flags) :
+                                devAddr.flags;
+
+                        currentDevAddr.port = (res->port != 0) ? res->port : devAddr.port;
 
                         if (payload->baseURI)
                         {
-                            OCDevAddr rdPubAddr = m_devAddr;
+                            OCDevAddr rdPubAddr = currentDevAddr;
 
                             std::string baseURI = std::string(payload->baseURI);
                             size_t len = baseURI.length();
@@ -72,38 +75,41 @@ namespace OC
                             OICStrcpy(rdPubAddr.addr, addressLen + 1, ipaddress.c_str());
                             rdPubAddr.port = port;
                             m_resources.push_back(std::shared_ptr<OC::OCResource>(
-                                        new OC::OCResource(m_clientWrapper, rdPubAddr,
+                                        new OC::OCResource(cw, rdPubAddr,
                                             std::string(res->uri),
                                             std::string(payload->sid),
                                             res->bitmap,
                                             StringLLToVector(res->types),
-                                            StringLLToVector(res->interfaces)
+                                            StringLLToVector(res->interfaces),
+                                            deviceName
                                             )));
                         }
                         else
                         {
                             m_resources.push_back(std::shared_ptr<OC::OCResource>(
-                                    new OC::OCResource(m_clientWrapper, m_devAddr,
+                                    new OC::OCResource(cw, currentDevAddr,
                                         std::string(res->uri),
                                         std::string(payload->sid),
                                         res->bitmap,
                                         StringLLToVector(res->types),
-                                        StringLLToVector(res->interfaces)
+                                        StringLLToVector(res->interfaces),
+                                        deviceName
                                         )));
 
 #ifdef TCP_ADAPTER
                             if (res->tcpPort != 0)
                             {
-                                OCDevAddr tcpDevAddr = m_devAddr;
+                                OCDevAddr tcpDevAddr = currentDevAddr;
                                 tcpDevAddr.port = res->tcpPort;
                                 tcpDevAddr.adapter = OC_ADAPTER_TCP;
                                 m_resources.push_back(std::shared_ptr<OC::OCResource>(
-                                            new OC::OCResource(m_clientWrapper, tcpDevAddr,
+                                            new OC::OCResource(cw, tcpDevAddr,
                                                 std::string(res->uri),
                                                 std::string(payload->sid),
                                                 res->bitmap,
                                                 StringLLToVector(res->types),
-                                                StringLLToVector(res->interfaces)
+                                                StringLLToVector(res->interfaces),
+                                                deviceName
                                                 )));
                             }
 #endif
@@ -117,7 +123,6 @@ namespace OC
 #ifdef WITH_MQ
             ListenOCContainer(std::weak_ptr<IClientWrapper> cw,
                                 OCDevAddr& devAddr, OCRepPayload* payload)
-                                : m_clientWrapper(cw), m_devAddr(devAddr)
             {
                 if (payload)
                 {
@@ -128,27 +133,30 @@ namespace OC
                     for(size_t idx = 0; idx < dimensions[0]; idx++)
                     {
                         m_resources.push_back(std::shared_ptr<OC::OCResource>(
-                                new OC::OCResource(m_clientWrapper, m_devAddr,
+                                new OC::OCResource(cw, devAddr,
                                                    std::string(topicList[idx]),
                                                    "",
                                                    OC_OBSERVABLE,
                                                    {OC_RSRVD_RESOURCE_TYPE_MQ_TOPIC},
-                                                   {DEFAULT_INTERFACE})));
+                                                   {DEFAULT_INTERFACE},
+                                                   deviceName
+                                                    )));
                     }
                 }
             }
 
             ListenOCContainer(std::weak_ptr<IClientWrapper> cw,
                               OCDevAddr& devAddr, const std::string& topicUri)
-                              : m_clientWrapper(cw), m_devAddr(devAddr)
             {
                     m_resources.push_back(std::shared_ptr<OC::OCResource>(
-                            new OC::OCResource(m_clientWrapper, m_devAddr,
+                            new OC::OCResource(cw, devAddr,
                                                topicUri,
                                                "",
                                                OC_OBSERVABLE,
                                                {OC_RSRVD_RESOURCE_TYPE_MQ_TOPIC},
-                                               {DEFAULT_INTERFACE})));
+                                               {DEFAULT_INTERFACE},
+                                               deviceName
+                                                )));
             }
 #endif
 
@@ -158,7 +166,5 @@ namespace OC
             }
         private:
             std::vector<std::shared_ptr<OC::OCResource>> m_resources;
-            std::weak_ptr<IClientWrapper> m_clientWrapper;
-            OCDevAddr& m_devAddr;
     };
 }
index c32656c..6ac5a6b 100644 (file)
@@ -32,6 +32,16 @@ namespace OC
                                PlatformConfig /*cfg*/)
         {}
 
+        virtual OCStackResult stop()
+        {
+            return OC_STACK_NOTIMPL;
+        }
+
+        virtual OCStackResult start()
+        {
+            return OC_STACK_NOTIMPL;
+        }
+
         virtual OCStackResult ListenForResource(const std::string& /*servUrl*/,
                                                 const std::string& /*rsrcType*/,
                                                 OCConnectivityType /*connType*/,
@@ -39,13 +49,21 @@ namespace OC
                                                 QualityOfService /*QoS*/)
             {return OC_STACK_NOTIMPL;}
 
-        virtual OCStackResult ListenForResource2(const std::string& /*servUrl*/,
+        virtual OCStackResult ListenForResourceList(const std::string& /*servUrl*/,
                                                 const std::string& /*rsrcType*/,
                                                 OCConnectivityType /*connType*/,
                                                 FindResListCallback& /*callback*/,
                                                 QualityOfService /*QoS*/)
             {return OC_STACK_NOTIMPL;}
 
+        virtual OCStackResult ListenForResourceListWithError(const std::string& /*servUrl*/,
+                                                const std::string&  /*rsrcType*/,
+                                                OCConnectivityType /*connType*/,
+                                                FindResListCallback& /*callback*/,
+                                                FindErrorCallback&  /*errorCallback*/,
+                                                QualityOfService /*QoS*/)
+            {return OC_STACK_NOTIMPL;}
+
         virtual OCStackResult ListenErrorForResource(const std::string& /*servUrl*/,
                                                      const std::string& /*rsrcType*/,
                                                      OCConnectivityType /*connType*/,
@@ -173,6 +191,14 @@ namespace OC
                                                        QualityOfService /*QoS*/)
             {return OC_STACK_NOTIMPL;}
 #endif
+#ifdef TCP_ADAPTER
+        virtual OCStackResult findKeepAliveResource(std::string host,
+                                                    KeepAliveCallback resultCallback)
+            {return OC_STACK_NOTIMPL;}
+        virtual OCStackResult sendKeepAliveRequest(std::string host, const OCRepresentation& rep,
+                                                   KeepAliveCallback resultCallback)
+            {return OC_STACK_NOTIMPL;}
+#endif
     };
 }
 
index 05d79e4..9f5b21c 100644 (file)
@@ -31,6 +31,16 @@ namespace OC
         OutOfProcServerWrapper(PlatformConfig /*cfg*/)
         {}
 
+        virtual OCStackResult stop()
+        {
+            return OC_STACK_NOTIMPL;
+        }
+
+        virtual OCStackResult start()
+        {
+            return OC_STACK_NOTIMPL;
+        }
+
         virtual OCStackResult registerResource(
             OCResourceHandle& /*resourceHandle*/,
             std::string& /*resourceURI*/,
index b15134a..6767a44 100644 (file)
@@ -31,52 +31,24 @@ namespace OC
     public:
         ResourceInitException(
                 bool missingUri,
+                bool invalidUri,
                 bool missingType,
                 bool missingInterface,
                 bool missingClientWrapper,
                 bool invalidPort,
-                bool invalidIp)
-        : m_whatMessage(),
-          m_missingUri(missingUri),
+                bool invalidIp,
+                bool invalidHost)
+        : m_missingUri(missingUri),
+          m_invalidUri(invalidUri),
           m_missingType(missingType),
           m_missingInterface(missingInterface),
           m_missingClientWrapper(missingClientWrapper),
           m_invalidPort(invalidPort),
-          m_invalidIp(invalidIp)
+          m_invalidIp(invalidIp),
+          m_invalidHost(invalidHost)
         {
-            if(isUriMissing())
-            {
-                m_whatMessage += OC::InitException::MISSING_URI;
-            }
-
-            if(isTypeMissing())
-            {
-                m_whatMessage += OC::InitException::MISSING_TYPE;
-            }
-
-            if(isInterfaceMissing())
-            {
-                m_whatMessage += OC::InitException::MISSING_INTERFACE;
-            }
-
-            if(isClientWrapperMissing())
-            {
-                m_whatMessage += OC::InitException::MISSING_CLIENT_WRAPPER;
-            }
-
-            if(isInvalidPort())
-            {
-                m_whatMessage += OC::InitException::INVALID_PORT;
-            }
-
-            if(isInvalidIp())
-            {
-                m_whatMessage += OC::InitException::INVALID_IP;
-            }
         }
 
-        virtual ~ResourceInitException() throw() {}
-
         bool isInvalidPort() const
         {
             return m_invalidPort;
@@ -87,6 +59,11 @@ namespace OC
             return m_invalidIp;
         }
 
+        bool isInvalidHost() const
+        {
+            return m_invalidHost;
+        }
+
         bool isClientWrapperMissing() const
         {
             return m_missingClientWrapper;
@@ -97,6 +74,11 @@ namespace OC
             return m_missingUri;
         }
 
+        bool isInvalidUri() const
+        {
+            return m_invalidUri;
+        }
+
         bool isTypeMissing() const
         {
             return m_missingType;
@@ -109,17 +91,60 @@ namespace OC
 
         virtual const char* what() const BOOST_NOEXCEPT
         {
-            return m_whatMessage.c_str();
+            std::string ret;
+
+            if(isUriMissing())
+            {
+                ret += OC::InitException::MISSING_URI;
+            }
+            else if(isInvalidUri())
+            {
+                ret += OC::InitException::INVALID_URI;
+            }
+
+            if(isTypeMissing())
+            {
+                ret += OC::InitException::MISSING_TYPE;
+            }
+
+            if(isInterfaceMissing())
+            {
+                ret += OC::InitException::MISSING_INTERFACE;
+            }
+
+            if(isClientWrapperMissing())
+            {
+                ret += OC::InitException::MISSING_CLIENT_WRAPPER;
+            }
+
+            if(isInvalidPort())
+            {
+                ret += OC::InitException::INVALID_PORT;
+            }
+
+            if(isInvalidIp())
+            {
+                ret += OC::InitException::INVALID_IP;
+            }
+
+            if(isInvalidHost())
+            {
+                ret += OC::InitException::INVALID_HOST;
+            }
+
+            return ret.c_str();
         }
 
     private:
-        std::string m_whatMessage;
+
         bool m_missingUri;
+        bool m_invalidUri;
         bool m_missingType;
         bool m_missingInterface;
         bool m_missingClientWrapper;
         bool m_invalidPort;
         bool m_invalidIp;
+        bool m_invalidHost;
     };
 }
 
index 4f856c2..3e366a3 100644 (file)
@@ -39,6 +39,7 @@ namespace OC
     namespace InitException
     {
         static const char NO_ERROR[]                   = "No Error";
+        static const char INVALID_HOST[]                = "Invalid Host";
         static const char INVALID_URI[]                = "Invalid URI";
         static const char INVALID_PORT[]               = "Invalid Port";
         static const char INVALID_IP[]                 = "Invalid IP";
@@ -48,6 +49,7 @@ namespace OC
         static const char UNKNOWN_ERROR[]              = "Unknown Error";
 
         static const char STACK_INIT_ERROR[]           = "Error Initializing Stack";
+        static const char STACK_TERMINATE_ERROR[]      = "Error Terminating Stack";
         static const char NOT_CONFIGURED_AS_SERVER[]   =
                           "Cannot static construct a Server when configured as a client";
         static const char INVALID_PARAM[]              = "Invalid Param";
@@ -123,11 +125,22 @@ namespace OC
         static const char PDM_DB_NOT_INITIALIZED[]     = "Provisioning DB is not initialized";
         static const char DUPLICATE_UUID[]             = "Duplicate UUID in DB";
         static const char INCONSISTENT_DB[]            = "Data in provisioning DB is inconsistent";
+        static const char SVR_DB_NOT_EXIST[]           = "SVR DB file is not exist.";
         static const char AUTHENTICATION_FAILURE[]     = "Authentication failure";
         static const char NOT_ALLOWED_OXM[]            = "Not allowed ownership transfer method";
+        static const char USER_DENIED_REQ[]            = "Request denied by User";
+        static const char NOT_ACCEPTABLE[]             = "Request not acceptable";
         static const char PUBLISH_RESOURCE_FAILED[]    = "Publish Resource failure";
         static const char FORBIDDEN_REQ[]              = "Forbidden request";
         static const char INTERNAL_SERVER_ERROR[]      = "Internal server error";
+        static const char NOTIFY_ALL_OBSERVERS_FAILED[]  = "notifyAllObservers failed";
+        static const char NOTIFY_LIST_OBSERVERS_FAILED[] = "notifyListOfObservers failed";
+        static const char METHOD_NOT_ALLOWED[]         = "method not allowed";
+        static const char NOT_IMPLEMENTED[]            = "not implemented";
+        static const char BAD_GATEWAY[]                = "bad gateway";
+        static const char SERVICE_UNAVAILABLE[]        = "service not available";
+        static const char GATEWAY_TIMEOUT[]            = "gateway timeout";
+        static const char PROXY_NOT_SUPPORTED[]        = "proxy not supported";
     }
 
     namespace Error
index af8aedb..25d067c 100644 (file)
@@ -49,7 +49,8 @@ ocprovision_env.AppendUnique(CPPPATH = [
                '../csdk/security/provisioning/include/internal',
                '../csdk/security/provisioning/include/cloud',
         '../csdk/connectivity/lib/libcoap-4.1.1/',
-        '../../extlibs/cjson/'
+        '../../extlibs/cjson/',
+        '../../extlibs/mbedtls/mbedtls/include'
                ])
 
 target_os = ocprovision_env.get('TARGET_OS')
@@ -60,6 +61,7 @@ if target_os == 'android':
        ocprovision_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions'])
        ocprovision_env.AppendUnique(LIBPATH = [ocprovision_env.get('BUILD_DIR')])
        ocprovision_env.AppendUnique(LIBS = ['oc', 'octbstack', 'ocpmapi', 'oc_logger', 'boost_thread', 'gnustl_shared', 'log'])
+       ocprovision_env.AppendUnique(LINKFLAGS = ['-Wl,-soname,libocprovision.so'])
 
 if target_os in ['linux', 'tizen']:
        ocprovision_env.AppendUnique(LIBPATH = [ocprovision_env.get('BUILD_DIR')])
@@ -82,7 +84,7 @@ if ocprovision_env.get('WITH_TCP') == True:
        ]
         ocprovision_env.UserInstallTargetHeader('../include/OCCloudProvisioning.hpp', 'resource', 'OCCloudProvisioning.hpp')
 
-if target_os not in ['ios']:
+if target_os not in ['darwin', 'ios']:
     ocprovision = ocprovision_env.SharedLibrary('ocprovision', ocprovision_src)
 else:
     ocprovision = ocprovision_env.StaticLibrary('ocprovision', ocprovision_src)
index ec21321..515f049 100644 (file)
@@ -40,6 +40,7 @@ examples_env.AppendUnique(CPPPATH = [
         '../../include/',
         '../../csdk/stack/include',
         '../../../extlibs/cjson',
+        '../../../extlibs/mbedtls/mbedtls/include',
         '../../csdk/logger/include',
         '../../oc_logger/include',
         '../../csdk/connectivity/api',
@@ -48,7 +49,7 @@ examples_env.AppendUnique(CPPPATH = [
         '../../csdk/connectivity/lib/libcoap-4.1.1/include',
         '../../csdk/security/include',
         '../../csdk/security/include/internal',
-       '../../csdk/security/provisioning/include/cloud',
+        '../../csdk/security/provisioning/include/cloud',
         '../../csdk/security/provisioning/include',
         '../../csdk/security/provisioning/include/oxm',
         '../../csdk/security/provisioning/include/internal'
@@ -86,12 +87,15 @@ if target_os in ['darwin', 'ios']:
 
 if target_os == 'tizen':
     examples_env.AppendUnique(CPPDEFINES = ['__TIZEN__'])
-
+if examples_env.get('MULTIPLE_OWNER') == '1':
+    examples_env.AppendUnique(CPPDEFINES = ['MULTIPLE_OWNER'])
 
 ######################################################################
 # Source files and Targets
 ######################################################################
 provisioningclient = examples_env.Program('provisioningclient', 'provisioningclient.cpp')
+if examples_env.get('MULTIPLE_OWNER') == '1':
+       subownerclient = examples_env.Program('subownerclient', 'subownerclient.cpp')
 
 if examples_env.get('WITH_TCP') == True:
        cloudClient = examples_env.Program('cloudClient',['cloudClient.cpp', 'cloudAuth.cpp', 'cloudWrapper.cpp'])
@@ -103,6 +107,12 @@ svr_db_build_dir = examples_env.get('BUILD_DIR') +'/resource/provisioning/exampl
 clientjson = examples_env.Install(svr_db_build_dir, svr_db_src_dir + 'oic_svr_db_client.json')
 clientdat = examples_env.Install(svr_db_build_dir, svr_db_src_dir + 'oic_svr_db_client.dat')
 
+if examples_env.get('MULTIPLE_OWNER') == '1':
+       subownerclientdat = examples_env.Install(svr_db_build_dir,
+               svr_db_src_dir + 'oic_svr_db_subowner_client.dat')
+       Alias("subowner", [subownerclientdat, subownerclient])
+       examples_env.AppendTarget("subowner")
+
 if examples_env.get('WITH_TCP') == True:
        clouddat = examples_env.Install(svr_db_build_dir,
                svr_db_src_dir + 'cloud.dat')
index 0d1be84..89f6905 100644 (file)
@@ -23,7 +23,7 @@
 
 #include "ocstack.h"
 #include "logger.h"
-#include "camutex.h"
+#include "octhread.h"
 #include "cathreadpool.h"
 #include "ocpayload.h"
 #include "payload_logging.h"
@@ -57,12 +57,12 @@ static bool fExit = false;
 static OCDevAddr endPoint;
 static char token[1024];
 static char authProvider[1024];
-static char *fname = DEFAULT_DB_FILE;
+static const char *fname = DEFAULT_DB_FILE;
 static uint64_t timeout;
 static uint16_t g_credId = 0;
 
-ca_cond cond;
-ca_mutex mutex;
+oc_cond cond;
+oc_mutex mutex;
 std::string ip(DEFAULT_HOST);
 OCCloudProvisioning g_cloudProv(ip, (uint16_t)DEFAULT_PORT);
 
@@ -190,9 +190,9 @@ void handleCB(void* ctx, OCStackResult result, void* data)
     OC_UNUSED(data);
 
     printf("Cloud request Result is == %d", result);
-    ca_mutex_lock(mutex);
-    ca_cond_signal(cond);
-    ca_mutex_unlock(mutex);
+    oc_mutex_lock(mutex);
+    oc_cond_signal(cond);
+    oc_mutex_unlock(mutex);
 }
 
 void handleCB1(OCStackResult result, void *data)
@@ -200,9 +200,9 @@ void handleCB1(OCStackResult result, void *data)
     OC_UNUSED(data);
 
     printf("Cloud request Result is == %d", result);
-    ca_mutex_lock(mutex);
-    ca_cond_signal(cond);
-    ca_mutex_unlock(mutex);
+    oc_mutex_lock(mutex);
+    oc_cond_signal(cond);
+    oc_mutex_unlock(mutex);
 }
 
 void handleCB2(OCStackResult result, std::string data)
@@ -210,9 +210,9 @@ void handleCB2(OCStackResult result, std::string data)
     printf("Cloud request Result is == %d", result);
     printf("ACL ID for the device is == %s", data.c_str());
 
-    ca_mutex_lock(mutex);
-    ca_cond_signal(cond);
-    ca_mutex_unlock(mutex);
+    oc_mutex_lock(mutex);
+    oc_cond_signal(cond);
+    oc_mutex_unlock(mutex);
 }
 
 static int saveTrustCert(void)
@@ -242,8 +242,8 @@ static int saveTrustCert(void)
             {
                 OIC_LOG(ERROR, TAG, "Certiface not read completely");
             }
-            fclose(fp);
         }
+        fclose(fp);
     }
     OIC_LOG_BUFFER(DEBUG, TAG, trustCertChainArray.data, trustCertChainArray.len);
 
@@ -270,8 +270,8 @@ static void userRequests(void *data)
     strncpy(endPoint.addr, DEFAULT_HOST, sizeof(endPoint.addr));
     endPoint.port = DEFAULT_PORT;
 
-    mutex = ca_mutex_new();
-    cond = ca_cond_new();
+    mutex = oc_mutex_new();
+    cond = oc_cond_new();
 
     while (false == fExit)
     {
@@ -288,8 +288,12 @@ static void userRequests(void *data)
         printMenu();
 
         int request = 0;
-        scanf("%d", &request);
-        for( ; 0x20<=getchar(); );
+
+        for (int ret = 0; 1 != ret; )
+        {
+            ret = scanf("%d", &request);
+            for( ; 0x20 <= getchar(); );
+        }
 
         switch (request)
         {
@@ -404,8 +408,8 @@ static void userRequests(void *data)
         }
             break;
         case EXIT:
-            ca_mutex_free(mutex);
-            ca_cond_free(cond);
+            oc_mutex_free(mutex);
+            oc_cond_free(cond);
             fExit = true;
             break;
         default:
@@ -416,9 +420,9 @@ static void userRequests(void *data)
         //if requests were sent then wait response
         if (res == OC_STACK_OK)
         {
-            ca_mutex_lock(mutex);
-            ca_cond_wait_for(cond, mutex, timeout);
-            ca_mutex_unlock(mutex);
+            oc_mutex_lock(mutex);
+            oc_cond_wait_for(cond, mutex, timeout);
+            oc_mutex_unlock(mutex);
         }
     }
 
@@ -478,7 +482,7 @@ int main(int argc, char *argv[])
     }
 
     //Initialize Persistent Storage for SVR database
-    OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink};
+    OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink, NULL, NULL};
 
     OCRegisterPersistentStorageHandler(&ps);
 
@@ -497,7 +501,7 @@ int main(int argc, char *argv[])
         return res;
     }
 
-    res = ca_thread_pool_add_task(g_threadPoolHandle, userRequests, NULL);
+    res = ca_thread_pool_add_task(g_threadPoolHandle, userRequests, NULL, NULL);
     if (CA_STATUS_OK != res)
     {
         OIC_LOG(ERROR, TAG, "thread pool add task error.");
index aa124dc..fefd85a 100644 (file)
@@ -1,24 +1,22 @@
-/*
- * //******************************************************************
- * //
- * // Copyright 2016 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.
- * //
- * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
+/* *****************************************************************
+ *
+ * Copyright 2016 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 "logger.h"
 #include "occloudprovisioning.h"
 
 using namespace OC;
 
+/**
+ * Skip special characters from stdin
+ * */
+static void skipSpecialCharacters()
+{
+    for( ; 0x20<=getchar(); );  // for removing overflow garbages
+                                // '0x20<=code' is character region
+}
+
 static bool readOptional(const char* description)
 {
     if (NULL == description)
@@ -60,12 +67,17 @@ static bool readOptional(const char* description)
     }
 
     printf("Do you want to Enter %s (y/n):\n", description);
-    char choice = 0;
+    char temp, choice = 0;
 
     while(1)
     {
-        scanf("%c", &choice);
-        getchar();
+        for (int ret = 0; 1 != ret; )
+        {
+            ret = scanf("%c", &temp);
+            skipSpecialCharacters();
+        }
+
+        choice = temp;
 
         switch (choice)
         {
@@ -87,11 +99,25 @@ static bool readOptional(const char* description)
  */
 void readString(char* item, int length, const char* description, const char* example)
 {
+    char *input = (char*)OICCalloc(length, sizeof(char));
+    if (NULL == input)
+    {
+        OIC_LOG(INFO, TAG, "input is NULL");
+        return;
+    }
+
     printf("Enter %s (f.e. %s):\n", description, example);
     char temp[8] = { 0 };
     snprintf(temp, sizeof(temp), "%%%ds", length - 1);
-    scanf(temp, item);
-    getchar();
+
+    for (int ret = 0; 1 != ret; )
+    {
+        ret = scanf(temp, input);
+        skipSpecialCharacters();
+    }
+
+    strncpy(item, input, length);
+    OICFree(input);
 }
 
 /**
@@ -119,9 +145,17 @@ static void readOptionalString(char* item, int length, const char* description,
  */
 void readInteger(int* item, const char* description, const char* example)
 {
+    int temp;
+
     printf("Enter %s (f.e. %s):\n", description, example);
-    scanf("%d", item);
-    getchar();
+
+    for (int ret = 0; 1 != ret; )
+    {
+        ret = scanf("%d", &temp);
+        skipSpecialCharacters();
+    }
+
+    *item = temp;
 }
 
 /**
diff --git a/resource/provisioning/examples/oic_svr_db_subowner_client.dat b/resource/provisioning/examples/oic_svr_db_subowner_client.dat
new file mode 100644 (file)
index 0000000..ae130bc
Binary files /dev/null and b/resource/provisioning/examples/oic_svr_db_subowner_client.dat differ
diff --git a/resource/provisioning/examples/oic_svr_db_subowner_client.json b/resource/provisioning/examples/oic_svr_db_subowner_client.json
new file mode 100644 (file)
index 0000000..eba0cdd
--- /dev/null
@@ -0,0 +1,85 @@
+{\r
+    "acl": {\r
+        "aclist": {\r
+            "aces": [\r
+                {\r
+                    "subjectuuid": "*",\r
+                    "resources": [\r
+                        {\r
+                            "href": "/oic/res",\r
+                            "rel": "",\r
+                            "rt": ["oic.wk.res"],\r
+                            "if": ["oic.if.ll"]\r
+                        },{\r
+                            "href": "/oic/d",\r
+                            "rel": "",\r
+                            "rt": ["oic.wk.d"],\r
+                            "if": ["oic.if.baseline", "oic.if.r"]\r
+                        },{\r
+                            "href": "/oic/p",\r
+                            "rel": "",\r
+                            "rt": ["oic.wk.p"],\r
+                            "if": ["oic.if.baseline", "oic.if.r"]\r
+                        }\r
+                    ],\r
+                    "permission": 2\r
+                },\r
+                {\r
+                    "subjectuuid": "*",\r
+                    "resources": [\r
+                        {\r
+                            "href": "/oic/sec/doxm",\r
+                            "rel": "",\r
+                            "rt": ["oic.r.doxm"],\r
+                            "if": ["oic.if.baseline"]\r
+                        },\r
+                        {\r
+                            "href": "/oic/sec/pstat",\r
+                            "rel": "",\r
+                            "rt": ["oic.r.pstat"],\r
+                            "if": ["oic.if.baseline"]\r
+                        }\r
+                    ],\r
+                    "permission": 2\r
+                },\r
+                {\r
+                    "subjectuuid": "*",\r
+                    "resources": [\r
+                        {\r
+                            "href": "/oic/sec/pconf",\r
+                            "rel": "",\r
+                            "rt": ["oic.r.pconf"],\r
+                            "if": ["oic.if.baseline"]\r
+                        },\r
+                        {\r
+                            "href": "/oic/sec/dpairing",\r
+                            "rel": "",\r
+                            "rt": ["oic.r.dpairing"],\r
+                            "if": ["oic.if.baseline"]\r
+                        }\r
+                    ],\r
+                    "permission": 2\r
+                }\r
+            ]\r
+        },\r
+        "rowneruuid" : "5375624F-776E-6572-436C-69656E743030"\r
+    },\r
+    "pstat": {\r
+        "isop": true,\r
+        "cm": 0,\r
+        "tm": 0,\r
+        "om": 3,\r
+        "sm": 3,\r
+        "deviceuuid": "5375624F-776E-6572-436C-69656E743030",\r
+        "rowneruuid": "5375624F-776E-6572-436C-69656E743030"\r
+    },\r
+    "doxm": {\r
+        "oxms": [0],\r
+        "oxmsel": 0,\r
+        "sct": 1,\r
+        "owned": true,\r
+        "deviceuuid": "5375624F-776E-6572-436C-69656E743030",\r
+        "devowneruuid": "5375624F-776E-6572-436C-69656E743030",\r
+        "rowneruuid": "5375624F-776E-6572-436C-69656E743030"\r
+    }\r
+}\r
index 9e2f1d8..9c20bdd 100644 (file)
@@ -38,6 +38,7 @@
 #include "oxmrandompin.h"
 #include "aclresource.h"
 #include "utlist.h"
+#include "mbedtls/x509_crt.h"
 
 #define MAX_PERMISSION_LENGTH (5)
 #define ACL_RESRC_ARRAY_SIZE (3)
@@ -65,7 +66,7 @@ static const OicSecPrm_t  SUPPORTED_PRMS[1] =
 
 using namespace OC;
 
-DeviceList_t pUnownedDevList, pOwnedDevList;
+DeviceList_t pUnownedDevList, pOwnedDevList, pMOTEnabledDeviceList;
 static int transferDevIdx, ask = 1;
 static OicSecPconf_t g_pconf;
 static uint16_t g_credId = 0;
@@ -96,6 +97,16 @@ void printMenu()
     std::cout << "  14. Provision the Trust Cert. Chain"<<std::endl;
     std::cout << "  15. Read trust cert chain"<<std::endl;
 #endif // __WITH_DTLS__ || __WITH_TLS__
+#ifdef MULTIPLE_OWNER
+    std::cout << "  16. Change Multiple Ownership Transfer Mode"<<std::endl;
+    std::cout << "  17. Select OxM method for Multiple Ownership Transfer"<<std::endl;
+    std::cout << "  18. Multiple Ownership Transfer Enabled Devices Discovery"<<std::endl;
+    std::cout << "  19. Provision pre configure PIN for Multiple Ownership Transfer Mode"<<std::endl;
+    std::cout << "  20. Add pre configure PIN for Multiple Ownership Transfer Mode"<<std::endl;
+    std::cout << "  21. Remove Sub-Owner from Resource Server"<<std::endl;
+    std::cout << "  22. Remove All Sub-Owner from Resource Server"<<std::endl;
+#endif
+    std::cout << "  30. Configure SVRdb as Self-OwnerShip"<<std::endl;
     std::cout << "  99. Exit loop"<<std::endl;
 }
 
@@ -126,6 +137,19 @@ void printUuid(OicUuid_t uuid)
     std::cout<<std::endl;
 }
 
+
+static OCStackResult peerCertCallback(const mbedtls_x509_crt *cert, int depth)
+{
+    OIC_LOG_V(DEBUG, TAG, "Depth : %d", depth);
+    OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
+    OIC_LOG(DEBUG, TAG, "***** Serial number of peer certificate is below *****");
+    OIC_LOG_BUFFER(DEBUG, TAG, cert->serial.p, cert->serial.len);
+    OIC_LOG(DEBUG, TAG, "***** Serial number of peer certificate is above *****");
+    OIC_LOG_V(DEBUG, TAG, "OUT%s", __func__);
+
+    return OC_STACK_OK;
+}
+
 void ownershipTransferCB(PMResultList_t *result, int hasError)
 {
     if (hasError)
@@ -433,7 +457,7 @@ static int InputACL(OicSecAcl_t *acl)
             printf("         Enter Number of resource type for [%s]: ", rsrc->href);
             for(int ret=0; 1!=ret; )
             {
-                ret = scanf("%d", &arrLen);
+                ret = scanf("%zu", &arrLen);
                 for( ; 0x20<=getchar(); );  // for removing overflow garbages
                                             // '0x20<=code' is character region
             }
@@ -452,7 +476,7 @@ static int InputACL(OicSecAcl_t *acl)
             goto error;
         }
 
-        for(int i = 0; i < arrLen; i++)
+        for(unsigned int i = 0; i < arrLen; i++)
         {
             printf("         Enter ResourceType[%d] Name (e.g. core.led): ", i+1);
             for(int ret=0; 1!=ret; )
@@ -475,7 +499,7 @@ static int InputACL(OicSecAcl_t *acl)
             printf("         Enter Number of interface name for [%s]: ", rsrc->href);
             for(int ret=0; 1!=ret; )
             {
-                ret = scanf("%d", &arrLen);
+                ret = scanf("%zu", &arrLen);
                 for( ; 0x20<=getchar(); );  // for removing overflow garbages
                                             // '0x20<=code' is character region
             }
@@ -494,7 +518,7 @@ static int InputACL(OicSecAcl_t *acl)
             goto error;
         }
 
-        for(int i = 0; i < arrLen; i++)
+        for(unsigned int i = 0; i < arrLen; i++)
         {
             printf("         Enter interfnace[%d] Name (e.g. oic.if.baseline): ", i+1);
             for(int ret=0; 1!=ret; )
@@ -801,6 +825,47 @@ PVDP_ERROR:
     ask = 1;
 }
 
+OCStackResult displayMutualVerifNumCB(uint8_t mutualVerifNum[MUTUAL_VERIF_NUM_LEN])
+{
+    OIC_LOG(INFO, TAG, "IN displayMutualVerifNumCB");
+    OIC_LOG(INFO, TAG, "############ mutualVerifNum ############");
+    OIC_LOG_BUFFER(INFO, TAG, mutualVerifNum, MUTUAL_VERIF_NUM_LEN);
+    OIC_LOG(INFO, TAG, "############ mutualVerifNum ############");
+    OIC_LOG(INFO, TAG, "OUT displayMutualVerifNumCB");
+    return OC_STACK_OK;
+}
+
+OCStackResult confirmMutualVerifNumCB(void)
+{
+    for (;;)
+    {
+        int userConfirm;
+
+        printf("   > Press 1 if the mutual verification numbers are the same\n");
+        printf("   > Press 0 if the mutual verification numbers are not the same\n");
+
+        for (int ret=0; 1!=ret; )
+        {
+            ret = scanf("%d", &userConfirm);
+            for (; 0x20<=getchar(); );  // for removing overflow garbage
+                                        // '0x20<=code' is character region
+        }
+        if (1 == userConfirm)
+        {
+            break;
+        }
+        else if (0 == userConfirm)
+        {
+            return OC_STACK_USER_DENIED_REQ;
+        }
+        printf("   Entered Wrong Number. Please Enter Again\n");
+    }
+    return OC_STACK_OK;
+}
+
+
+
+
 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
 static int saveTrustCert(void)
 {
@@ -814,7 +879,7 @@ static int saveTrustCert(void)
 
     if (fp)
     {
-        size_t fsize;
+        int fsize;
         if (fseeko(fp, 0, SEEK_END) == 0 && (fsize = ftello(fp)) >= 0)
         {
             trustCertChainArray.data = (uint8_t*)OICCalloc(1, fsize);
@@ -831,8 +896,8 @@ static int saveTrustCert(void)
             {
                 OIC_LOG(ERROR,TAG,"Read error");
             }
-            fclose(fp);
         }
+        fclose(fp);
     }
     OIC_LOG_BUFFER(DEBUG, TAG, trustCertChainArray.data, trustCertChainArray.len);
 
@@ -850,13 +915,45 @@ static int saveTrustCert(void)
 void certChainCallBack(uint16_t credId, uint8_t *trustCertChain,size_t chainSize)
 {
     OIC_LOG_V(INFO, TAG, "trustCertChain Changed for credId %u", credId);
+    OC_UNUSED(trustCertChain);
+    OC_UNUSED(chainSize);
     return;
 }
 #endif // __WITH_DTLS__ or __WITH_TLS__
 
+#ifdef MULTIPLE_OWNER
+void MOTMethodCB(PMResultList_t *result, int hasError)
+{
+    if (hasError)
+    {
+        std::cout << "Error!!! in callback"<<std::endl;
+    }
+    else
+    {
+        std::cout<< "callback successfull"<<std::endl;
+        delete result;
+    }
+}
+
+void MOTRemoveSubOwnerCB(PMResultList_t *result, int hasError)
+{
+    if (hasError)
+    {
+        std::cout << "Error!!! in callback"<<std::endl;
+    }
+    else
+    {
+        std::cout<< "callback successfull"<<std::endl;
+        delete result;
+    }
+}
+
+#endif // MULTIPLE_OWNER
+
 int main(void)
 {
-    OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
+    OCStackResult result;
+    OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink, NULL, NULL};
 
     // Create PlatformConfig object
     PlatformConfig cfg {
@@ -880,6 +977,20 @@ int main(void)
             return 1;
         }
 
+        result = OCSecure::registerDisplayNumCallback(displayMutualVerifNumCB);
+        if (result != OC_STACK_OK)
+        {
+            std::cout<< "!!Error - setDisplayVerifNumCB failed."<<std::endl;
+        }
+
+        result = OCSecure::registerUserConfirmCallback(confirmMutualVerifNumCB);
+        if (result != OC_STACK_OK)
+        {
+            std::cout<< "!!Error - setConfirmVerifNumCB failed."<<std::endl;
+        }
+
+        OCSecure::setPeerCertCallback(peerCertCallback);
+
         for (int out = 0; !out;)
         {
             while (!ask)
@@ -975,32 +1086,7 @@ int main(void)
 
                         //register callbacks for JUST WORKS and PIN methods
                         std::cout <<"Registering OTM Methods: 1. JUST WORKS and 2. PIN"<<std::endl;
-
-                        {
-                            OTMCallbackData_t justWorksCBData;
-                            justWorksCBData.loadSecretCB = LoadSecretJustWorksCallback;
-                            justWorksCBData.createSecureSessionCB =
-                                CreateSecureSessionJustWorksCallback;
-                            justWorksCBData.createSelectOxmPayloadCB =
-                                CreateJustWorksSelectOxmPayload;
-                            justWorksCBData.createOwnerTransferPayloadCB =
-                                CreateJustWorksOwnerTransferPayload;
-                            OCSecure::setOwnerTransferCallbackData(OIC_JUST_WORKS,
-                                    &justWorksCBData, NULL);
-                        }
-
-                        {
-                            OTMCallbackData_t pinBasedCBData;
-                            pinBasedCBData.loadSecretCB = InputPinCodeCallback;
-                            pinBasedCBData.createSecureSessionCB =
-                                CreateSecureSessionRandomPinCallback;
-                            pinBasedCBData.createSelectOxmPayloadCB =
-                                CreatePinBasedSelectOxmPayload;
-                            pinBasedCBData.createOwnerTransferPayloadCB =
-                                CreatePinBasedOwnerTransferPayload;
-                            OCSecure::setOwnerTransferCallbackData(OIC_RANDOM_DEVICE_PIN,
-                                    &pinBasedCBData, InputPinCB);
-                        }
+                        OCSecure::setInputPinCallback(InputPinCB);
 
                         ask = 0;
                         std::cout << "Transfering ownership for : "<<
@@ -1344,6 +1430,352 @@ int main(void)
                         break;
                     }
 #endif //__WITH_DTLS__ || __WITH_TLS__
+#ifdef MULTIPLE_OWNER
+                 case 16:
+                    {
+                        if (!pOwnedDevList.size() && !pMOTEnabledDeviceList.size())
+                        {
+                            std::cout <<"Owned device list and MOT device list both are empty."<<std::endl;
+                            break;
+                        }
+                        unsigned int dev_count = 0;
+                        if (pOwnedDevList.size())
+                        {
+                            dev_count = pOwnedDevList.size();
+                            printDevices(pOwnedDevList);
+                        }
+
+                        if (pMOTEnabledDeviceList.size())
+                        {
+                            dev_count += pMOTEnabledDeviceList.size();
+                            for (unsigned int i = 0; i < pMOTEnabledDeviceList.size(); i++ )
+                            {
+                                std::cout << "Device ";
+                                std::cout <<((dev_count - pMOTEnabledDeviceList.size())+ i + 1) ;
+                                std::cout <<" ID : ";
+                                std::cout << pMOTEnabledDeviceList[i]->getDeviceID()<<" From IP: ";
+                                std::cout << pMOTEnabledDeviceList[i]->getDevAddr() << std::endl;
+                            }
+                        }
+
+                        // select device
+                        unsigned int dev_num = 0;
+                        for( ; ; )
+                        {
+                            std::cout << "Enter Device Number, to change the mode: "<<std::endl;
+                            std::cin >> dev_num;
+                            if(0 < dev_num && dev_count >= dev_num)
+                            {
+                                break;
+                            }
+                            std::cout << "   Entered Wrong Number. Please Enter Again"<<std::endl;
+                        }
+
+                        OicSecMomType_t momType = OIC_MULTIPLE_OWNER_ENABLE;
+                        int mom = 0;
+                        for( ; ; )
+                        {
+                            std::cout <<"   0. Disable Multiple Ownership Transfer"<<std::endl;
+                            std::cout <<"   1. Enable Multiple Ownership Transfer "<<std::endl;
+                            std::cout <<"> Enter Mode of Multiple Ownership Transfer :"<<std::endl;
+                            for(int ret=0; 1!=ret; )
+                            {
+                                ret = scanf("%d", &mom);
+                                for( ; 0x20<=getchar(); );  // for removing overflow garbages
+                                                            // '0x20<=code' is character region
+                            }
+                            if(mom == 0)
+                            {
+                                momType = OIC_MULTIPLE_OWNER_DISABLE;
+                                break;
+                            }
+                            if(mom == 1)
+                            {
+                                momType = OIC_MULTIPLE_OWNER_ENABLE;
+                                break;
+                            }
+                            std::cout <<"     Entered Wrong Number. Please Enter Again"<<std::endl;
+                        }
+
+                        if (!pOwnedDevList.size())
+                        {
+                            if(OC_STACK_OK != pMOTEnabledDeviceList[dev_num-1]->changeMOTMode(
+                            (const OicSecMomType_t)momType,MOTMethodCB))
+                            {
+                                OIC_LOG(ERROR, TAG, "changeMOTMode API error");
+                            }
+                        }
+                        else
+                        {
+                            if(dev_num <= pOwnedDevList.size())
+                            {
+                                if(OC_STACK_OK != pOwnedDevList[dev_num-1]->changeMOTMode(momType,
+                                MOTMethodCB))
+                                {
+                                    OIC_LOG(ERROR, TAG, "changeMOTMode API error");
+                                }
+                            }
+                            else
+                            {
+                                if(OC_STACK_OK != pMOTEnabledDeviceList[(dev_num -
+                                pOwnedDevList.size() - 1)]->changeMOTMode(momType,
+                                MOTMethodCB))
+                                {
+                                    OIC_LOG(ERROR, TAG, "changeMOTMode API error");
+                                }
+                            }
+                        }
+                         break;
+                    }
+                case 17:
+                    {
+                        if (!pMOTEnabledDeviceList.size())
+                        {
+                            std::cout <<"Please discover the MOT device first. Use option 18"<<std::endl;
+                            break;
+                        }
+
+                        printDevices(pMOTEnabledDeviceList);
+                        // select device
+                        unsigned int dev_num = 0;
+                        for( ; ; )
+                        {
+                            std::cout << "Enter Device Number, for MOT Device: "<<std::endl;
+                            std::cin >> dev_num;
+                            if(0 < dev_num &&  pMOTEnabledDeviceList.size() >=dev_num)
+                            {
+                                break;
+                            }
+                                              std::cout << "     Entered Wrong Number. Please Enter Again"<<std::endl;
+                        }
+
+                        int oxm = 0;
+                        OicSecOxm_t secOxm = OIC_PRECONFIG_PIN;
+                        std::cout << "Select method for  Multiple Ownership Transfer: "<<std::endl;
+                        for( ; ; )
+                        {
+                            std::cout << "  0. Random PIN OxM "<<std::endl;
+                            std::cout << "  1. Pre-Configured PIN OxM "<<std::endl;
+                            std::cout << "   > Enter Number of  OxM for Multiple Ownership Transfer : "<<std::endl;
+                            std::cin >> oxm;
+                            if(0 == oxm)
+                            {
+                                secOxm = OIC_RANDOM_DEVICE_PIN;
+                                break;
+                            }
+                            if(1 == oxm)
+                            {
+                                secOxm = OIC_PRECONFIG_PIN;
+                                break;
+                            }
+                            std::cout << "     Entered Wrong Number. Please Enter Again"<<std::endl;
+                        }
+
+                        if(OC_STACK_OK != pMOTEnabledDeviceList[dev_num-1]->selectMOTMethod((const OicSecOxm_t)secOxm,
+                                              MOTMethodCB))
+                        {
+                            OIC_LOG(ERROR, TAG, "selectMOTMethod API error");
+                        }
+                         break;
+                    }
+                case 18:
+                    {
+                        pMOTEnabledDeviceList.clear();
+                        std::cout << "Started MOT Enabled device discovery..." <<std::endl;
+                        OCStackResult result = OCSecure::discoverMultipleOwnerEnabledDevices
+                            (DISCOVERY_TIMEOUT, pMOTEnabledDeviceList);
+                        if (result != OC_STACK_OK)
+                        {
+                            std::cout<< "!!Error - MOT Enabled dev Discovery failed."<<std::endl;
+                        }
+                        else if (pMOTEnabledDeviceList.size())
+                        {
+                            std::cout <<"Found MOT enabled devices, count = " <<
+                                pMOTEnabledDeviceList.size() << std::endl;
+                            printDevices(pMOTEnabledDeviceList);
+                        }
+                        else
+                        {
+                            std::cout <<"No MOT enabled Secure devices found"<<std::endl;
+                        }
+                        break;
+                    }
+                case 19:
+                    {
+                        if (!pMOTEnabledDeviceList.size())
+                        {
+                            std::cout <<"Please discover the MOT device first. Use option 16"<<std::endl;
+                            break;
+                        }
+
+                        printDevices(pMOTEnabledDeviceList);
+                        // select device
+                        unsigned int dev_num = 0;
+                        for( ; ; )
+                        {
+                            std::cout << "Enter Device Number, for MOT Device: "<<std::endl;
+                            std::cin >> dev_num;
+                            if(0 < dev_num && pMOTEnabledDeviceList.size() >=dev_num)
+                            {
+                                break;
+                            }
+                            std::cout << "     Entered Wrong Number. Please Enter Again"<<std::endl;
+                        }
+
+                        char preconfigPin[9] = {0};
+                        std::cout << "   > Input the 8 digit PreconfigPin (e.g. 12341234) :" <<std::endl;
+                        for(int ret=0; 1!=ret; )
+                        {
+                            ret = scanf("%8s", preconfigPin);
+                            for( ; 0x20<=getchar(); );  // for removing overflow garbages
+                                                        // '0x20<=code' is character region
+                        }
+                        size_t preconfPinLength = strlen(preconfigPin);
+                        if(OC_STACK_OK != pMOTEnabledDeviceList[dev_num-1]->provisionPreconfPin(preconfigPin,
+                            preconfPinLength, MOTMethodCB))
+                        {
+                            OIC_LOG(ERROR, TAG, "provisionPreconfPin API error");
+                        }
+                        break;
+                    }
+                    case 20:
+                    {
+                        if (!pMOTEnabledDeviceList.size())
+                        {
+                            std::cout <<"Please discover the MOT device first. Use option 16"<<std::endl;
+                            break;
+                        }
+
+                        printDevices(pMOTEnabledDeviceList);
+                        // select device
+                        unsigned int dev_num = 0;
+                        for( ; ; )
+                        {
+                            std::cout << "Enter Device Number, for MOT Device: "<<std::endl;
+                            std::cin >> dev_num;
+                            if(0 < dev_num && pMOTEnabledDeviceList.size() >=dev_num)
+                            {
+                                break;
+                            }
+                            std::cout << "     Entered Wrong Number. Please Enter Again"<<std::endl;
+                        }
+
+                        char preconfPIN[9] = {0};
+                        std::cout << "   > Input the 8 digit preconfPIN (e.g. 12341234) :" <<std::endl;
+                        for(int ret=0; 1!=ret; )
+                        {
+                            ret = scanf("%8s", preconfPIN);
+                            for( ; 0x20<=getchar(); );  // for removing overflow garbages
+                                                        // '0x20<=code' is character region
+                        }
+                        size_t preconfPinLength = strlen(preconfPIN);
+                        if(OC_STACK_OK != pMOTEnabledDeviceList[dev_num-1]->addPreconfigPIN(preconfPIN,
+                            preconfPinLength))
+                        {
+                            OIC_LOG(ERROR, TAG, "addPreconfigPIN API error");
+                        }
+                        break;
+                    }
+                    case 21: //Remove sub-owner
+                    {
+                        if (!pMOTEnabledDeviceList.size())
+                        {
+                            std::cout <<"Please discover the MOT device first. Use option 16"<<std::endl;
+                            break;
+                        }
+
+                        printDevices(pMOTEnabledDeviceList);
+                        // select device
+                        unsigned int dev_num = 0;
+                        for( ; ; )
+                        {
+                            std::cout << "Enter Device Number, for MOT Device: "<<std::endl;
+                            std::cin >> dev_num;
+                            if(0 < dev_num && pMOTEnabledDeviceList.size() >=dev_num)
+                            {
+                                break;
+                            }
+                            std::cout << "     Entered Wrong Number. Please Enter Again"<<std::endl;
+                        }
+
+                        UuidList_t subOwenrList;
+                        pMOTEnabledDeviceList[dev_num - 1]->getSubOwnerList(subOwenrList);
+                        if (0 == subOwenrList.size())
+                        {
+                            std::cout << "SubOwner List is empty."<<std::endl;
+                        }
+                        else
+                        {
+                            //display the Linked devices (UUIDs)
+                            for(unsigned int i = 0; i < subOwenrList.size(); i++)
+                            {
+                                printUuid(subOwenrList[i]);
+                            }
+                        }
+                        unsigned int so_num = 0;
+                        for( ; ; )
+                        {
+                            std::cout << "Enter SubOwner Number to be Removed: "<<std::endl;
+                            std::cin >> so_num;
+                            if(0 < so_num && subOwenrList.size() >=so_num)
+                            {
+                                pMOTEnabledDeviceList[dev_num - 1]->removeSubOwner(&subOwenrList[so_num], MOTRemoveSubOwnerCB);
+                                break;
+                            }
+                            std::cout << "     Entered Wrong Number. Please Enter Again"<<std::endl;
+                        }
+
+                        break;
+                    }
+                    case 22: //Remove all sub-owner
+                    {
+                        if (!pMOTEnabledDeviceList.size())
+                        {
+                            std::cout <<"Please discover the MOT device first. Use option 16"<<std::endl;
+                            break;
+                        }
+
+                        printDevices(pMOTEnabledDeviceList);
+                        // select device
+                        unsigned int dev_num = 0;
+                        for( ; ; )
+                        {
+                            std::cout << "Enter Device Number, for MOT Device: "<<std::endl;
+                            std::cin >> dev_num;
+                            if(0 < dev_num && pMOTEnabledDeviceList.size() >=dev_num)
+                            {
+                                break;
+                            }
+                            std::cout << "     Entered Wrong Number. Please Enter Again"<<std::endl;
+                        }
+
+                        UuidList_t subOwenrList;
+                        pMOTEnabledDeviceList[dev_num - 1]->getSubOwnerList(subOwenrList);
+                        if (0 == subOwenrList.size())
+                        {
+                            std::cout << "SubOwner List is empty."<<std::endl;
+                        }
+                        else
+                        {
+                            pMOTEnabledDeviceList[dev_num - 1]->removeAllSubOwner(MOTRemoveSubOwnerCB);
+                        }
+                        break;
+                    }
+#endif //MULTIPLE_OWNER
+                case 30:
+                    {
+                        OCStackResult result;
+                        result = OCSecure::configSelfOwnership();
+                        if (OC_STACK_OK != result)
+                        {
+                            std::cout<<"configSelfOwnership API error. Please check SVR DB"<<std::endl;
+                        }
+                        else
+                        {
+                            std::cout<<"Success to configures SVR DB as self-ownership"<<std::endl;
+                        }
+                        break;
+                    }
                 case 99:
                 default:
                     out = 1;
diff --git a/resource/provisioning/examples/subownerclient.cpp b/resource/provisioning/examples/subownerclient.cpp
new file mode 100644 (file)
index 0000000..e3ec97d
--- /dev/null
@@ -0,0 +1,394 @@
+/* *****************************************************************
+ *
+ * Copyright 2016 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 <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <string>
+#include <map>
+#include <cstdlib>
+#include <pthread.h>
+#include <mutex>
+#include <condition_variable>
+
+#include "logger.h"
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "OCPlatform.h"
+#include "OCApi.h"
+#include "OCProvisioningManager.hpp"
+#include "oxmjustworks.h"
+#include "oxmrandompin.h"
+#include "aclresource.h"
+#include "utlist.h"
+
+#define MAX_PERMISSION_LENGTH (5)
+#define ACL_RESRC_ARRAY_SIZE (3)
+#define CREATE (1)
+#define READ (2)
+#define UPDATE (4)
+#define DELETE (8)
+#define NOTIFY (16)
+#define DASH '-'
+#define PREDEFINED_TIMEOUT (10)
+#define MAX_OWNED_DEVICE (10)
+#define TAG  "subownerclient"
+
+#define JSON_DB_PATH "./oic_svr_db_subowner_client.json"
+#define DAT_DB_PATH "./oic_svr_db_subowner_client.dat"
+#define DEV_STATUS_ON "DEV_STATUS_ON"
+#define DEV_STATUS_OFF "DEV_STATUS_OFF"
+
+#define DISCOVERY_TIMEOUT 5
+
+using namespace OC;
+
+DeviceList_t pMOwnedDeviceList, pMOTEnabledDeviceList;
+static int transferDevIdx, ask = 1;
+
+static FILE* client_open(const char *UNUSED_PARAM, const char *mode)
+{
+    (void)UNUSED_PARAM;
+    return fopen(DAT_DB_PATH, mode);
+}
+
+void printMenu()
+{
+    std::cout << "\nChoose an option:"<<std::endl;
+    std::cout << "   1. Discover Multiple Ownership Transfer Enabled Devices"<<std::endl;
+    std::cout << "   2. Discover Multiple Owned Devices"<<std::endl;
+    std::cout << "   3. Perform the Multiple Ownership Transfer"<<std::endl;
+    std::cout << "   4. Get LED resource"<<std::endl;
+    std::cout << "   5. Get PUT resource"<<std::endl;
+    std::cout << "  99. Exit loop"<<std::endl;
+}
+
+void moveTransferredDevice()
+{
+    pMOwnedDeviceList.push_back(pMOTEnabledDeviceList[transferDevIdx]);
+    pMOTEnabledDeviceList.erase(pMOTEnabledDeviceList.begin() + transferDevIdx);
+}
+
+void InputPinCB(char* pinBuf, size_t bufSize)
+{
+    if(pinBuf)
+    {
+        std::cout <<"INPUT PIN : ";
+        std::string ptr;
+        std::cin >> ptr;
+        OICStrcpy(pinBuf, bufSize, ptr.c_str());
+        return;
+    }
+}
+
+void printUuid(OicUuid_t uuid)
+{
+    for (int i = 0; i < UUID_LENGTH; i++)
+    {
+        std::cout <<std::hex << uuid.id[i] << " ";
+    }
+    std::cout<<std::endl;
+}
+
+void multipleOwnershipTransferCB(PMResultList_t *result, int hasError)
+{
+    if (hasError)
+    {
+        std::cout << "Error!!! in MultipleOwnershipTransfer"<<std::endl;
+    }
+    else
+    {
+        std::cout<< "\nTransferred MultipleOwnership successfuly for device : ";
+        printUuid(result->at(0).deviceId);
+        delete result;
+
+        moveTransferredDevice();
+    }
+    ask = 1;
+}
+
+void printStatus(int status)
+{
+    static std::map<int, std::string> devStatus = {{1<<0, DEV_STATUS_ON}, {1<<1, DEV_STATUS_OFF}};
+
+    std::cout <<devStatus[status] <<std::endl;
+}
+
+void printDevices(DeviceList_t &list)
+{
+   for (unsigned int i = 0; i < list.size(); i++ )
+   {
+      std::cout << "Device "<< i+1 <<" ID: ";
+      std::cout << list[i]->getDeviceID() << " From IP: ";
+      std::cout << list[i]->getDevAddr() << std::endl;
+   }
+}
+
+static void getCallback(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode)
+{
+    (void)(headerOptions);
+    try
+    {
+        if (OC_STACK_OK == eCode)
+        {
+            std::cout << "Callback Context for GET query recvd successfully" << std::endl;
+            std::cout << "Resource URI: " << rep.getUri() << std::endl;
+
+            bool state = false;
+            int power = 0;
+            rep.getValue("state", state);
+            rep.getValue("power", power);
+
+            std::cout << "\tstate: " << state << std::endl;
+            std::cout << "\tpower: " << power << std::endl;
+        }
+        else
+        {
+            std::cout << "getCallback Response error: " << eCode << std::endl;
+        }
+    }
+    catch(std::exception& e)
+    {
+        std::cout << "Exception: " << e.what() << " in onGet" << std::endl;
+    }
+}
+
+void putCallback(const HeaderOptions& /*headerOptions*/, const OCRepresentation& rep, const int eCode)
+{
+    if(eCode == 0)
+    {
+        std::cout << "PUT request was successful !!!!!!" << std::endl;
+    }
+    else
+    {
+        std::cout << "onPut Response error !!!!!: " << eCode << std::endl;
+    }
+}
+
+int main(void)
+{
+    OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
+
+    // Create PlatformConfig object
+    PlatformConfig cfg {
+        OC::ServiceType::InProc,
+            OC::ModeType::Both,
+            "0.0.0.0",
+            0,
+            OC::QualityOfService::LowQos,
+            &ps
+    };
+
+    OCPlatform::Configure(cfg);
+
+    //set Input Pin callback
+    OCSecure::setInputPinCallback(InputPinCB);
+
+    try
+    {
+        int choice;
+        OicSecAcl_t *acl1 = nullptr, *acl2 = nullptr;
+        if (OCSecure::provisionInit("subowner_pdm.db") != OC_STACK_OK)
+        {
+            std::cout <<"PM Init failed"<< std::endl;
+            return 1;
+        }
+
+        for (int out = 0; !out;)
+        {
+            while (!ask)
+            {
+                sleep(1);
+            }
+
+            printMenu();
+            std::cin >> choice;
+            switch(choice) {
+                case 1:
+                    {
+                        pMOTEnabledDeviceList.clear();
+                        std::cout << "Started MOT enabled device discovery..." <<std::endl;
+                        OCStackResult result = OCSecure::discoverMultipleOwnerEnabledDevices(
+                                DISCOVERY_TIMEOUT, pMOTEnabledDeviceList);
+                        if (result != OC_STACK_OK)
+                        {
+                            std::cout<< "!!Error - MOT enabled dev Discovery failed."<<std::endl;
+                        }
+                        else if (pMOTEnabledDeviceList.size())
+                        {
+                            std::cout <<"Found MOT enabled devices, count = " <<
+                                pMOTEnabledDeviceList.size() << std::endl;
+                            printDevices(pMOTEnabledDeviceList);
+                        }
+                        else
+                        {
+                            std::cout <<"NO MOT enabled devices found"<<std::endl;
+                        }
+                        break;
+                    }
+                case 2:
+                    {
+                        pMOwnedDeviceList.clear();
+                        std::cout << "Started Multiple Owned device discovery..." <<std::endl;
+                        OCStackResult result = OCSecure::discoverMultipleOwnerEnabledDevices(
+                                DISCOVERY_TIMEOUT, pMOwnedDeviceList);
+                        if (result != OC_STACK_OK)
+                        {
+                            std::cout<< "!!Error - Multiple Owned dev Discovery failed."<<std::endl;
+                        }
+                        else if (pMOwnedDeviceList.size())
+                        {
+                            std::cout <<"Found Multiple Owned devices, count = " <<
+                                pMOwnedDeviceList.size() << std::endl;
+                            printDevices(pMOwnedDeviceList);
+                        }
+                        else
+                        {
+                            std::cout <<"NO Multiple Owned devices found"<<std::endl;
+                        }
+                        break;
+                    }
+                case 3:
+                    {  //Multiple Ownrship Trasfer
+                        unsigned int devNum;
+
+                        if (!pMOTEnabledDeviceList.size())
+                        {
+                            std::cout <<"There are no MOT enabled devices"<<std::endl;
+                            break;
+                        }
+
+                        for (unsigned int i = 0; i < pMOTEnabledDeviceList.size(); i++ )
+                        {
+                            std::cout << i+1 << ": "<< pMOTEnabledDeviceList[i]->getDeviceID();
+                            std::cout << " From IP:" << pMOTEnabledDeviceList[i]->getDevAddr() <<std::endl;
+                        }
+
+                        std::cout <<"Select device number: "<<std::endl;
+                        std::cin >> devNum;
+                        if (devNum > pMOTEnabledDeviceList.size())
+                        {
+                            std::cout <<"Invalid device number"<<std::endl;
+                            break;
+                        }
+                        transferDevIdx = devNum - 1;
+
+                        ask = 0;
+                        std::cout << "MOT for : "<<
+                            pMOTEnabledDeviceList[devNum-1]->getDeviceID()<<std::endl;
+                        if (pMOTEnabledDeviceList[devNum-1]->doMultipleOwnershipTransfer
+                                (multipleOwnershipTransferCB)
+                                != OC_STACK_OK)
+                        {
+                            std::cout<<"Multiple OwnershipTransferCallback is failed"<<std::endl;
+                            ask = 1;
+                        }
+                        break;
+                    }
+                case 4:
+                    {
+                        std::cout << "- Send data(GET Request) to device(led server) -" << std::endl;
+                        printDevices(pMOwnedDeviceList);
+                        printMenu();
+                        std::cout << "Enter device number to GET data: ";
+                        std::cin >> choice;
+                        choice--;
+
+                        std::vector<std::string> ledTypes = {"core.led"};
+                        std::vector<std::string> ifaces = {DEFAULT_INTERFACE};
+
+                        OCProvisionDev_t *selDev = pMOwnedDeviceList[choice]->getDevPtr();
+                        std::stringstream host;
+                        host << "coaps:://";
+                        host << pMOwnedDeviceList[choice]->getDevAddr();
+                        host << selDev->securePort;
+
+                        OCResource::Ptr led = OC::OCPlatform::constructResourceObject(
+                                host.str(), "/a/led", selDev->connType, false, ledTypes, ifaces);
+
+                        if(!led)
+                        {
+                            std::cout << "Error: Led Object construction returned null" << std::endl;
+                            break;
+                        }
+                        OCStackResult res = led->get(QueryParamsMap(), getCallback);
+
+                        if (OC_STACK_OK != res)
+                        {
+                            std::cout << "Error: get Failed for Led" << std::endl;
+                        }
+                        break;
+                    }
+                    break;
+                case 5:
+                    {
+                        std::cout << "- Send data(Put Request) to device(led server) -" << std::endl;
+                        printDevices(pMOwnedDeviceList);
+                        printMenu();
+                        std::cout << "Enter device number to GET data: ";
+                        std::cin >> choice;
+                        choice--;
+
+                        std::vector<std::string> ledTypes = {"core.led"};
+                        std::vector<std::string> ifaces = {DEFAULT_INTERFACE};
+
+
+                        OCProvisionDev_t *selDev = pMOwnedDeviceList[choice]->getDevPtr();
+                        std::stringstream host;
+                        host << "coaps:://";
+                        host << pMOwnedDeviceList[choice]->getDevAddr();
+                        host << selDev->securePort;
+
+                        OCResource::Ptr led = OC::OCPlatform::constructResourceObject(host.str(),
+                                "/a/led", selDev->connType, false, ledTypes, ifaces);
+
+                        if(!led)
+                        {
+                            std::cout << "Error: Led Object construction returned null" << std::endl;
+                            break;
+                        }
+                        OCRepresentation rep;
+                        bool state = true;
+                        int power = 39;
+                        rep.setValue("state", state);
+                        rep.setValue("power", power);
+                        OCStackResult res = led->put(rep, QueryParamsMap(), putCallback);
+
+                        if (OC_STACK_OK != res)
+                        {
+                            std::cout << "Error: put Failed for Led" << std::endl;
+                        }
+                        break;
+                    }
+                    break;
+                case 99:
+                default:
+                    out = 1;
+                    break;
+            }
+        }
+    }
+    catch(OCException& e)
+    {
+        oclog() << "Exception in main: "<<e.what();
+    }
+
+    return 0;
+}
index 0c82538..3c18238 100644 (file)
@@ -22,6 +22,8 @@
 #include "srmutility.h"
 #include "base64.h"
 #include "OCProvisioningManager.hpp"
+#include "mbedtls/x509_crt.h"
+
 
 namespace OC
 {
@@ -44,6 +46,23 @@ namespace OC
         return result;
     }
 
+    OCStackResult OCSecure::terminatePM()
+    {
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            OCTerminatePM();
+            return OC_STACK_OK;
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            return OC_STACK_ERROR;
+        }
+    }
+
     OCStackResult OCSecure::discoverUnownedDevices(unsigned short timeout,
             DeviceList_t &list)
     {
@@ -160,32 +179,158 @@ namespace OC
         return result;
     }
 
-    OCStackResult OCSecure::setOwnerTransferCallbackData(OicSecOxm_t oxm,
-            OTMCallbackData_t* callbackData, InputPinCallback inputPin)
+    OCStackResult OCSecure::discoverSingleDeviceInUnicast(unsigned short timeout,
+            const OicUuid_t* deviceID,
+            const std::string& hostAddress,
+            OCConnectivityType connType,
+            std::shared_ptr<OCSecureResource> &foundDevice)
     {
-        if (NULL == callbackData || oxm >= OIC_OXM_COUNT)
+        OCStackResult result = OC_STACK_ERROR;
+        OCProvisionDev_t *pDev = nullptr;
+        auto csdkLock = OCPlatform_impl::Instance().csdkLock();
+        auto cLock = csdkLock.lock();
+
+        if (cLock)
         {
-            oclog() <<"Invalid callbackData or OXM type";
-            return OC_STACK_INVALID_PARAM;
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCDiscoverSingleDeviceInUnicast(timeout, deviceID, hostAddress.c_str(),
+                            connType, &pDev);
+
+            if (result == OC_STACK_OK)
+            {
+                if (pDev)
+                {
+                    foundDevice.reset(new OCSecureResource(csdkLock, pDev));
+                }
+                else
+                {
+                    oclog() <<"Not found Secure resource!";
+                    foundDevice.reset();
+                }
+            }
+            else
+            {
+                oclog() <<"Secure resource discovery failed!";
+            }
         }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+
+        return result;
+    }
 
-        if ((OIC_RANDOM_DEVICE_PIN == oxm) && !inputPin)
+#ifdef MULTIPLE_OWNER
+    OCStackResult OCSecure::discoverMultipleOwnerEnabledDevices(unsigned short timeout,
+            DeviceList_t &list)
+    {
+        OCStackResult result;
+        OCProvisionDev_t *pDevList = nullptr, *pCurDev = nullptr, *tmp = nullptr;
+        auto csdkLock = OCPlatform_impl::Instance().csdkLock();
+        auto cLock = csdkLock.lock();
+
+        if (cLock)
         {
-            oclog() <<"for OXM type DEVICE_PIN, inputPin callback can't be null";
-            return OC_STACK_INVALID_PARAM;
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCDiscoverMultipleOwnerEnabledDevices(timeout, &pDevList);
+            if (result == OC_STACK_OK)
+            {
+                pCurDev = pDevList;
+                while (pCurDev)
+                {
+                    tmp = pCurDev;
+                    list.push_back(std::shared_ptr<OCSecureResource>(
+                                new OCSecureResource(csdkLock, pCurDev)));
+                    pCurDev = pCurDev->next;
+                    tmp->next = nullptr;
+                }
+            }
+            else
+            {
+                oclog() <<"MultipleOwner Enabled device discovery failed!";
+            }
         }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+
+        return result;
+    }
 
+    OCStackResult OCSecure::discoverMultipleOwnedDevices(unsigned short timeout,
+            DeviceList_t &list)
+    {
         OCStackResult result;
-        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+        OCProvisionDev_t *pDevList = nullptr, *pCurDev = nullptr, *tmp = nullptr;
+        auto csdkLock = OCPlatform_impl::Instance().csdkLock();
+        auto cLock = csdkLock.lock();
 
         if (cLock)
         {
             std::lock_guard<std::recursive_mutex> lock(*cLock);
-            result = OCSetOwnerTransferCallbackData(oxm, callbackData);
-            if (result == OC_STACK_OK && (OIC_RANDOM_DEVICE_PIN == oxm))
+            result = OCDiscoverMultipleOwnedDevices(timeout, &pDevList);
+            if (result == OC_STACK_OK)
             {
-                SetInputPinCB(inputPin);
+                pCurDev = pDevList;
+                while (pCurDev)
+                {
+                    tmp = pCurDev;
+                    list.push_back(std::shared_ptr<OCSecureResource>(
+                                new OCSecureResource(csdkLock, pCurDev)));
+                    pCurDev = pCurDev->next;
+                    tmp->next = nullptr;
+                }
             }
+            else
+            {
+                oclog() <<"Multiple Owned device discovery failed!";
+            }
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+
+        return result;
+    }
+
+#endif
+    OCStackResult OCSecure::setInputPinCallback(InputPinCallback inputPin)
+    {
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            SetInputPinCB(inputPin);
+            result = OC_STACK_OK;
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+
+        return result;
+    }
+
+
+    OCStackResult OCSecure::unsetInputPinCallback()
+    {
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            UnsetInputPinCB();
+            result = OC_STACK_OK;
         }
         else
         {
@@ -194,7 +339,24 @@ namespace OC
         }
 
         return result;
+    }
 
+    OCStackResult OCSecure::setRandomPinPolicy(size_t pinSize, OicSecPinType_t pinType)
+    {
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = SetRandomPinPolicy(pinSize, pinType);
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
     }
 
     OCStackResult OCSecure::getDevInfoFromNetwork(unsigned short timeout,
@@ -332,6 +494,199 @@ namespace OC
         return result;
     }
 
+    OCStackResult OCSecure::displayNumCallbackWrapper(void* ctx,
+            uint8_t verifNum[MUTUAL_VERIF_NUM_LEN])
+    {
+        uint8_t *number = NULL;
+
+        DisplayNumContext* context = static_cast<DisplayNumContext*>(ctx);
+        if (!context)
+        {
+            oclog() << "Invalid context";
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        if (NULL != verifNum) {
+            number = new uint8_t[MUTUAL_VERIF_NUM_LEN];
+            memcpy(number, verifNum, MUTUAL_VERIF_NUM_LEN);
+        }
+
+        return context->callback(number);
+    }
+
+    OCStackResult OCSecure::registerDisplayNumCallback(DisplayNumCB displayNumCB)
+    {
+        if(!displayNumCB)
+        {
+            oclog() << "Failed to register callback for display.";
+            return OC_STACK_INVALID_CALLBACK;
+        }
+
+        OCStackResult result = OCSecure::deregisterDisplayNumCallback();
+        if (OC_STACK_OK != result)
+        {
+            oclog() << "Failed to de-register callback for display."<<std::endl;
+            return result;
+        }
+
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+        if (cLock)
+        {
+            DisplayNumContext* context = new DisplayNumContext(displayNumCB);
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            SetDisplayNumCB(static_cast<void*>(context), &OCSecure::displayNumCallbackWrapper);
+            result = OC_STACK_OK;
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecure::deregisterDisplayNumCallback()
+    {
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            DisplayNumContext* context = static_cast<DisplayNumContext*>(UnsetDisplayNumCB());
+            if (context)
+            {
+                oclog() << "Delete registered display num context"<<std::endl;
+                delete context;
+            }
+            result = OC_STACK_OK;
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecure::confirmUserCallbackWrapper(void* ctx)
+    {
+        UserConfirmNumContext* context = static_cast<UserConfirmNumContext*>(ctx);
+        if (!context)
+        {
+            oclog() << "Invalid context";
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        return context->callback();
+    }
+
+    OCStackResult OCSecure::registerUserConfirmCallback(UserConfirmNumCB userConfirmCB)
+    {
+        if(!userConfirmCB)
+        {
+            oclog() << "Failed to set callback for confirming verifying callback.";
+            return OC_STACK_INVALID_CALLBACK;
+        }
+
+        OCStackResult result = OCSecure::deregisterUserConfirmCallback();
+        if (OC_STACK_OK != result)
+        {
+            oclog() << "Failed to de-register callback for comfirm."<<std::endl;
+            return result;
+        }
+
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+        if (cLock)
+        {
+            UserConfirmNumContext* context = new UserConfirmNumContext(userConfirmCB);
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            SetUserConfirmCB(static_cast<void*>(context), &OCSecure::confirmUserCallbackWrapper);
+            result = OC_STACK_OK;
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecure::deregisterUserConfirmCallback()
+    {
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            UserConfirmNumContext* context = static_cast<UserConfirmNumContext*>(UnsetUserConfirmCB());
+            if (context)
+            {
+                oclog() << "Delete registered user confirm context"<<std::endl;
+                delete context;
+            }
+            result = OC_STACK_OK;
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecure::setVerifyOptionMask(VerifyOptionBitmask_t optionMask)
+    {
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            SetVerifyOption(optionMask);
+            result = OC_STACK_OK;
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecure::pdmCleanupForTimeout()
+    {
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+        if (cLock)
+        {
+            result = OCPDMCleanupForTimeout();
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecure::configSelfOwnership()
+    {
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCConfigSelfOwnership();
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
     OCStackResult OCSecure::saveTrustCertChain(uint8_t *trustCertChain, size_t chainSize,
                                         OicEncodingType_t encodingType, uint16_t *credId)
@@ -393,12 +748,58 @@ namespace OC
         delete context;
     }
 
-    OCStackResult OCSecure::registerTrustCertChangeNotifier(CertChainCallBack callback)
+    OCStackResult OCSecure::registerTrustCertChangeNotifier(CertChainCallBack callback)
+    {
+        if (!callback)
+        {
+            oclog() <<"callback can not be null";
+            return OC_STACK_INVALID_CALLBACK;
+        }
+
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            TrustCertChainContext* context = new TrustCertChainContext(callback);
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCRegisterTrustCertChainNotifier(static_cast<void*>(context),
+                    &OCSecure::certCallbackWrapper);
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+
+    OCStackResult OCSecure::removeTrustCertChangeNotifier()
+    {
+        OCStackResult result;
+        auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            OCRemoveTrustCertChainNotifier();
+            result = OC_STACK_OK;
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecure::setDeviceIdSeed(const uint8_t* seed, size_t seedSize)
     {
-        if (!callback)
+        if (!seed)
         {
-            oclog() <<"callback can not be null";
-            return OC_STACK_INVALID_CALLBACK;
+            oclog() <<"seed can not be null";
+            return OC_STACK_INVALID_PARAM;
         }
 
         OCStackResult result;
@@ -406,10 +807,8 @@ namespace OC
 
         if (cLock)
         {
-            TrustCertChainContext* context = new TrustCertChainContext(callback);
             std::lock_guard<std::recursive_mutex> lock(*cLock);
-            result = OCRegisterTrustCertChainNotifier(static_cast<void*>(context),
-                    &OCSecure::certCallbackWrapper);
+            result = SetDeviceIdSeed(seed, seedSize);
         }
         else
         {
@@ -419,25 +818,67 @@ namespace OC
         return result;
     }
 
+    int OCSecure::peerCertCallbackWrapper(void *ctx, const mbedtls_x509_crt *cert,
+            int depth)
+    {
+        OCStackResult ret = OC_STACK_ERROR;
 
-    OCStackResult OCSecure::removeTrustCertChangeNotifier()
+        PeerCertContext *context = static_cast<PeerCertContext*>(ctx);
+        if (NULL == context)
+        {
+            oclog() << "Invalid Context";
+            return 1;
+        }
+
+        if (context->callback)
+        {
+            ret = context->callback(cert, depth);
+        }
+
+        if (0 == depth)
+        {
+            delete context;
+        }
+
+        return (OC_STACK_OK == ret)? 0 : 1;
+    }
+
+    OCStackResult OCSecure::setPeerCertCallback(PeerCertCB peerCertCallback)
     {
         OCStackResult result;
+        // UNSET cb
+        if (NULL == peerCertCallback)
+        {
+            result = OCSetPeerCertCallback(NULL, NULL);
+            if (OC_STACK_OK != result)
+            {
+                oclog() << "OCSetPeerCertCallback() Failed";
+                return result;
+            }
+        }
+
         auto cLock = OCPlatform_impl::Instance().csdkLock().lock();
 
         if (cLock)
         {
+            PeerCertContext *context = new PeerCertContext(peerCertCallback);
+
             std::lock_guard<std::recursive_mutex> lock(*cLock);
-            OCRemoveTrustCertChainNotifier();
-            result = OC_STACK_OK;
+            result = OCSetPeerCertCallback(static_cast<void*>(context),
+                    &OCSecure::peerCertCallbackWrapper);
+            if (OC_STACK_OK != result)
+            {
+                oclog() << "OCSetPeerCertCallback() Failed";
+            }
         }
         else
         {
-            oclog() <<"Mutex not found";
+            oclog() << "Mutex not found";
             result = OC_STACK_ERROR;
         }
         return result;
     }
+
 #endif // __WITH_DTLS__ || __WITH_TLS__
 
     void OCSecureResource::callbackWrapper(void* ctx, int nOfRes, OCProvisionResult_t *arr, bool hasError)
@@ -512,6 +953,46 @@ namespace OC
         return result;
     }
 
+#ifdef MULTIPLE_OWNER
+    OCStackResult OCSecureResource::doMultipleOwnershipTransfer(ResultCallBack resultCallback)
+    {
+        if (!resultCallback)
+        {
+            oclog() <<"Result callback can't be null";
+            return OC_STACK_INVALID_CALLBACK;
+        }
+
+        OCStackResult result;
+        auto cLock = m_csdkLock.lock();
+
+        if (cLock)
+        {
+            ProvisionContext* context = new ProvisionContext(resultCallback);
+
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCDoMultipleOwnershipTransfer(static_cast<void*>(context),
+                    devPtr, &OCSecureResource::callbackWrapper);
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecureResource::getSubOwnerList(UuidList_t &uuidList)
+    {
+        validateSecureResource();
+        OicSecSubOwner_t* tmp = NULL;
+        for (tmp = devPtr->doxm->subOwners; tmp; tmp = tmp->next)
+        {
+            uuidList.push_back(tmp->uuid);
+        }
+        return OC_STACK_OK;
+    }
+
+#endif
     OCStackResult OCSecureResource::provisionACL( const OicSecAcl_t* acl,
             ResultCallBack resultCallback)
     {
@@ -818,4 +1299,247 @@ namespace OC
             throw OCException("Incomplete secure resource", OC_STACK_RESOURCE_ERROR);
         }
     }
+
+    OCStackResult OCSecureResource::getOTMethod(OicSecOxm_t* oxm)
+    {
+        if(!oxm)
+        {
+            oclog() << "Null param";
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        OCStackResult result = OC_STACK_ERROR;
+        auto cLock = m_csdkLock.lock();
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            if(devPtr && devPtr->doxm)
+            {
+                result = OCSelectOwnershipTransferMethod(devPtr->doxm->oxm, devPtr->doxm->oxmLen,
+                                                  oxm, SUPER_OWNER);
+            }
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+        }
+        return result;
+    }
+
+
+#ifdef MULTIPLE_OWNER
+    OCStackResult OCSecureResource::getMOTMethod( OicSecOxm_t* oxm)
+    {
+        if (!oxm)
+        {
+            oclog() << "Null param";
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        OCStackResult result = OC_STACK_ERROR;
+        auto cLock = m_csdkLock.lock();
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            if (devPtr && devPtr->doxm)
+            {
+                result = OCSelectOwnershipTransferMethod(devPtr->doxm->oxm, devPtr->doxm->oxmLen,
+                                                  oxm, SUB_OWNER);
+            }
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+        }
+        return result;
+    }
+
+    bool OCSecureResource::isMOTSupported()
+    {
+        if (devPtr && devPtr->doxm)
+        {
+            return (devPtr->doxm->mom ? true : false);
+        }
+        return false;
+    }
+
+    bool OCSecureResource::isMOTEnabled()
+    {
+        if (devPtr && devPtr->doxm && devPtr->doxm->mom)
+        {
+            if (OIC_MULTIPLE_OWNER_DISABLE != devPtr->doxm->mom->mode)
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    OCStackResult OCSecureResource::selectMOTMethod( const OicSecOxm_t oxmSelVal,
+            ResultCallBack resultCallback)
+    {
+        if (!resultCallback)
+        {
+            oclog() <<"result callback can not be null";
+            return OC_STACK_INVALID_CALLBACK;
+        }
+
+        OCStackResult result;
+        auto cLock = m_csdkLock.lock();
+
+        if (cLock)
+        {
+            ProvisionContext* context = new ProvisionContext(resultCallback);
+
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCSelectMOTMethod(static_cast<void*>(context),
+                    devPtr, oxmSelVal,
+                    &OCSecureResource::callbackWrapper);
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecureResource::changeMOTMode( const OicSecMomType_t momType,
+            ResultCallBack resultCallback)
+    {
+        if (!resultCallback)
+        {
+            oclog() <<"result callback can not be null";
+            return OC_STACK_INVALID_CALLBACK;
+        }
+
+        OCStackResult result;
+        auto cLock = m_csdkLock.lock();
+
+        if (cLock)
+        {
+            ProvisionContext* context = new ProvisionContext(resultCallback);
+
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCChangeMOTMode(static_cast<void*>(context),
+                    devPtr, momType,
+                    &OCSecureResource::callbackWrapper);
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+
+    OCStackResult OCSecureResource::addPreconfigPIN(const char* preconfPIN,
+            size_t preconfPINLength)
+    {
+        if (!preconfPIN)
+        {
+            oclog() <<"pre config pin can not be null";
+            return OC_STACK_INVALID_PARAM;
+        }
+        if (preconfPINLength <= 0)
+        {
+            oclog() <<"pre config pin length can not be zero or less";
+            return OC_STACK_INVALID_PARAM;
+        }
+        OCStackResult result;
+        auto cLock = m_csdkLock.lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCAddPreconfigPin(devPtr, preconfPIN,
+                    preconfPINLength);
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecureResource::provisionPreconfPin(const char * preconfPin,
+            size_t preconfPinLength, ResultCallBack resultCallback)
+    {
+        if (!resultCallback)
+        {
+            oclog() <<"result callback can not be null";
+            return OC_STACK_INVALID_CALLBACK;
+        }
+        if (!preconfPin)
+        {
+            oclog() <<"pre config pin can not be null";
+            return OC_STACK_INVALID_PARAM;
+        }
+        if (preconfPinLength <= 0)
+        {
+            oclog() <<"pre config pin length can not be zero or less";
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        OCStackResult result;
+        auto cLock = m_csdkLock.lock();
+
+        if (cLock)
+        {
+            ProvisionContext* context = new ProvisionContext(resultCallback);
+
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCProvisionPreconfigPin(static_cast<void*>(context),
+                    devPtr, preconfPin, preconfPinLength,
+                    &OCSecureResource::callbackWrapper);
+        }
+        else
+        {
+            oclog() <<"Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecureResource::removeSubOwner(const OicUuid_t* subOwnerId, ResultCallBack resultCallback)
+    {
+        validateSecureResource();
+        OCStackResult result;
+        auto cLock = m_csdkLock.lock();
+        if (cLock)
+        {
+            ProvisionContext* context = new ProvisionContext(resultCallback);
+            result = OCRemoveSubOwner(static_cast<void*>(context),
+                devPtr, subOwnerId, &OCSecureResource::callbackWrapper);
+        }
+        else
+        {
+            oclog() << "Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult OCSecureResource::removeAllSubOwner(ResultCallBack resultCallback)
+    {
+        validateSecureResource();
+        OCStackResult result;
+        auto cLock = m_csdkLock.lock();
+        if (cLock)
+        {
+            ProvisionContext* context = new ProvisionContext(resultCallback);
+            result =OCRemoveAllSubOwner(static_cast<void*>(context),
+                devPtr, &OCSecureResource::callbackWrapper);
+        }
+        else
+        {
+            oclog() << "Mutex not found";
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+#endif // MULTIPLE_OWNER
 }
old mode 100755 (executable)
new mode 100644 (file)
index 11e198b..3cb5a25
@@ -58,7 +58,7 @@ namespace OCProvisioningTest
         OicUuid_t uuid;
         ConvertStrToUuid("11111111-1111-1111-1111-111111111111", &uuid);
 
-        EXPECT_EQ(OC_STACK_OK, OCSecure::discoverSingleDevice(TIMEOUT, &uuid, secureResource));
+        EXPECT_EQ(OC_STACK_TIMEOUT, OCSecure::discoverSingleDevice(TIMEOUT, &uuid, secureResource));
     }
 
     TEST(DiscoveryTest, SecureResourceZeroTimeout)
@@ -82,6 +82,32 @@ namespace OCProvisioningTest
         EXPECT_EQ(OC_STACK_INVALID_PARAM, OCSecure::discoverUnownedDevices(0, list));
     }
 
+#ifdef MULTIPLE_OWNER
+    TEST(MOTDiscoveryTest, MultipleOwnerEnabledDevices)
+    {
+        DeviceList_t list;
+        EXPECT_EQ(OC_STACK_OK, OCSecure::discoverMultipleOwnerEnabledDevices(TIMEOUT, list));
+    }
+
+    TEST(MOTDiscoveryTest, MultipleOwnerEnabledDevicesZeroTimeOut)
+    {
+        DeviceList_t list;
+        EXPECT_EQ(OC_STACK_INVALID_PARAM, OCSecure::discoverMultipleOwnerEnabledDevices(0, list));
+    }
+
+    TEST(MOTDiscoveryTest, MultipleOwnedDevices)
+    {
+        DeviceList_t list;
+        EXPECT_EQ(OC_STACK_OK, OCSecure::discoverMultipleOwnedDevices(TIMEOUT, list));
+    }
+
+    TEST(MOTDiscoveryTest, MultipleOwnedDevicesZeroTimeOut)
+    {
+        DeviceList_t list;
+        EXPECT_EQ(OC_STACK_INVALID_PARAM, OCSecure::discoverMultipleOwnedDevices(0, list));
+    }
+#endif
+
     TEST(DiscoveryTest, OwnedDevices)
     {
         DeviceList_t list;
@@ -94,52 +120,65 @@ namespace OCProvisioningTest
         EXPECT_EQ(OC_STACK_INVALID_PARAM, OCSecure::discoverOwnedDevices(0, list));
     }
 
-    TEST(OwnershipTest, SetOwnershipTransferCBDataNull)
+    TEST(OwnershipTest, OwnershipTransferNullCallback)
     {
-        EXPECT_EQ(OC_STACK_INVALID_PARAM, OCSecure::setOwnerTransferCallbackData(
-                    OIC_JUST_WORKS, NULL, NULL));
+        OCSecureResource device;
+        EXPECT_EQ(OC_STACK_INVALID_CALLBACK, device.doOwnershipTransfer(nullptr));
     }
 
-    TEST(OwnershipTest, SetOwnershipTransferCBData)
+#ifdef MULTIPLE_OWNER
+    TEST(MOTOwnershipTest, MOTOwnershipTransferNullCallback)
     {
-        OTMCallbackData_t justWorksCBData;
-        justWorksCBData.loadSecretCB = LoadSecretJustWorksCallback;
-        justWorksCBData.createSecureSessionCB = CreateSecureSessionJustWorksCallback;
-        justWorksCBData.createSelectOxmPayloadCB = CreateJustWorksSelectOxmPayload;
-        justWorksCBData.createOwnerTransferPayloadCB = CreateJustWorksOwnerTransferPayload;
-        EXPECT_EQ(OC_STACK_OK, OCSecure::setOwnerTransferCallbackData(OIC_JUST_WORKS,
-                                        &justWorksCBData, NULL));
+        OCSecureResource device;
+        EXPECT_EQ(OC_STACK_INVALID_CALLBACK, device.doMultipleOwnershipTransfer(nullptr));
     }
 
-    TEST(OwnershipTest, SetOwnershipTransferCBDataInvalidType)
+    TEST(selectMOTMethodTest, selectMOTMethodNullCallback)
     {
-        OTMCallbackData_t justWorksCBData;
-        justWorksCBData.loadSecretCB = LoadSecretJustWorksCallback;
-        justWorksCBData.createSecureSessionCB = CreateSecureSessionJustWorksCallback;
-        justWorksCBData.createSelectOxmPayloadCB = CreateJustWorksSelectOxmPayload;
-        justWorksCBData.createOwnerTransferPayloadCB = CreateJustWorksOwnerTransferPayload;
-        EXPECT_EQ(OC_STACK_INVALID_PARAM, OCSecure::setOwnerTransferCallbackData(OIC_OXM_COUNT,
-                                        &justWorksCBData, NULL));
+        OCSecureResource device;
+        const OicSecOxm_t stsecOxm = OIC_PRECONFIG_PIN;
+        EXPECT_EQ(OC_STACK_INVALID_CALLBACK, device.selectMOTMethod(stsecOxm, NULL));
     }
 
-    TEST(OwnershipTest, SetOwnershipTransferCBDataNullInputPin)
+    TEST(changeMOTModeTest, changeMOTModeNullCallback)
     {
-        OTMCallbackData_t pinBasedCBData;
-        pinBasedCBData.loadSecretCB = InputPinCodeCallback;
-        pinBasedCBData.createSecureSessionCB = CreateSecureSessionRandomPinCallback;
-        pinBasedCBData.createSelectOxmPayloadCB = CreatePinBasedSelectOxmPayload;
-        pinBasedCBData.createOwnerTransferPayloadCB = CreatePinBasedOwnerTransferPayload;
-        OTMSetOwnershipTransferCallbackData(OIC_RANDOM_DEVICE_PIN, &pinBasedCBData);
+        OCSecureResource device;
+        const OicSecMomType_t momType = OIC_MULTIPLE_OWNER_ENABLE;
+        EXPECT_EQ(OC_STACK_INVALID_CALLBACK, device.changeMOTMode(momType, NULL));
+    }
 
-        EXPECT_EQ(OC_STACK_INVALID_PARAM, OCSecure::setOwnerTransferCallbackData(
-                    OIC_RANDOM_DEVICE_PIN, &pinBasedCBData, NULL));
+    TEST(addPreconfigPINTest, addPreconfigPINNullPin)
+    {
+        OCSecureResource device;
+        EXPECT_EQ(OC_STACK_INVALID_PARAM, device.addPreconfigPIN(NULL, 0));
     }
 
-    TEST(OwnershipTest, OwnershipTransferNullCallback)
+    TEST(provisionPreconfPinTest, provisionPreconfPinNullCallback)
     {
         OCSecureResource device;
-        EXPECT_EQ(OC_STACK_INVALID_CALLBACK, device.doOwnershipTransfer(nullptr));
+        const char *pin = "test";
+        size_t PinLength = 4;
+        EXPECT_EQ(OC_STACK_INVALID_CALLBACK, device.provisionPreconfPin(pin, PinLength, NULL));
+    }
+
+    TEST(isMOTEnabledTest, isMOTEnabledWithoutDeviceInst)
+    {
+        OCSecureResource device;
+        EXPECT_EQ(false, device.isMOTEnabled());
+    }
+
+    TEST(isMOTSupportedTest, isMOTSupportedWithoutDeviceInst)
+    {
+        OCSecureResource device;
+        EXPECT_EQ(false, device.isMOTSupported());
+    }
+
+    TEST(getMOTMethodTest, getMOTMethodNullOxM)
+    {
+        OCSecureResource device;
+        EXPECT_EQ(OC_STACK_INVALID_PARAM, device.getMOTMethod(NULL));
     }
+#endif
 
     TEST(DeviceInfoTest, DevInfoFromNetwork)
     {
@@ -211,4 +250,26 @@ namespace OCProvisioningTest
         OCSecureResource device;
         EXPECT_EQ(OC_STACK_INVALID_PARAM, device.provisionDirectPairing(nullptr, nullptr));
     }
+
+#if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+    TEST(setDeviceIdSeed, NullParam)
+    {
+        EXPECT_EQ(OC_STACK_INVALID_PARAM, OCSecure::setDeviceIdSeed(NULL, 0));
+    }
+
+    TEST(setDeviceIdSeed, InvalidParam)
+    {
+        uint8_t seed[1024] = {0};
+
+        EXPECT_EQ(OC_STACK_INVALID_PARAM, OCSecure::setDeviceIdSeed(seed, 0));
+        EXPECT_EQ(OC_STACK_INVALID_PARAM, OCSecure::setDeviceIdSeed(seed, sizeof(seed)));
+    }
+
+    TEST(setDeviceIdSeed, ValidValue)
+    {
+        uint8_t seed[16] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+                            0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};
+        EXPECT_EQ(OC_STACK_OK, OCSecure::setDeviceIdSeed(seed, sizeof(seed)));
+    }
+#endif // __WITH_DTLS__ || __WITH_TLS__
 }
old mode 100755 (executable)
new mode 100644 (file)
index d32a7a0..afb6e18 100644 (file)
 #include "CAManager.h"
 #include "cautilinterface.h"
 #include "casecurityinterface.h"
+#include "logger.h"
 
-using namespace OC;
+#define TAG "OIC_CAMANAGER"
 
+using namespace OC;
 namespace
 {
         CAManager::AdapterChangedCallback g_adapterHandler = nullptr;
@@ -106,6 +108,7 @@ OCStackResult CAManager::setNetworkMonitorHandler(AdapterChangedCallback adapter
 OCStackResult CAManager::setPortNumberToAssign(OCTransportAdapter adapter,
                                                OCTransportFlags flag, uint16_t port)
 {
+    OIC_LOG(INFO, TAG, "setPortNumberToAssign");
     CAResult_t ret = CASetPortNumberToAssign((CATransportAdapter_t) adapter,
                                              (CATransportFlags_t) flag, port);
 
@@ -114,8 +117,38 @@ OCStackResult CAManager::setPortNumberToAssign(OCTransportAdapter adapter,
 
 uint16_t CAManager::getAssignedPortNumber(OCTransportAdapter adapter, OCTransportFlags flag)
 {
+    OIC_LOG(INFO, TAG, "getAssignedPortNumber");
     return CAGetAssignedPortNumber((CATransportAdapter_t) adapter, (CATransportFlags_t) flag);
 }
+
+OCStackResult CAManager::setMulticastTTL(size_t ttl)
+{
+    OIC_LOG(INFO, TAG, "setMulticastTTL");
+    CAResult_t ret = CAUtilSetMulticastTTL(ttl);
+    return convertCAResultToOCResult(ret);
+}
+
+OCStackResult CAManager::getMulticastTTL(size_t *ttl)
+{
+    OIC_LOG(INFO, TAG, "getMulticastTTL");
+    CAResult_t ret = CAUtilGetMulticastTTL(ttl);
+    return convertCAResultToOCResult(ret);
+}
+
+OCStackResult CAManager::setBTConfigure(const CAUtilConfig& config)
+{
+    OIC_LOG(INFO, TAG, "setBTConfigure");
+    CAUtilConfig_t configs = {(CATransportBTFlags_t)config.bleFlag, { {0}, .adapter = CA_DEFAULT_ADAPTER, .level = HIGH_SPEED }};
+    CAResult_t ret = CAUtilSetBTConfigure(configs);
+    return convertCAResultToOCResult(ret);
+}
+
+void CAManager::setLogLevel(OCLogLevel level, bool hidePrivateLogEntries)
+{
+    OIC_LOG(INFO, TAG, "setLogLevel");
+    CAUtilSetLogLevel((CAUtilLogLevel_t) level, hidePrivateLogEntries);
+}
+
 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
 OCStackResult CAManager::setCipherSuite(const uint16_t cipher, OCTransportAdapter adapter)
 {
@@ -123,3 +156,68 @@ OCStackResult CAManager::setCipherSuite(const uint16_t cipher, OCTransportAdapte
     return convertCAResultToOCResult(ret);
 }
 #endif // defined(__WITH_DTLS__) || defined(__WITH_TLS__)
+
+#if defined(__TIZEN__) && defined(LE_ADAPTER) && defined(BLE_CUSTOM_ADVERTISE)
+OCStackResult CAManager::setAdvertisementData(const char* data, int length)
+{
+    CAResult_t ret = CASetAdvertisementData(data, length);
+
+    return convertCAResultToOCResult(ret);
+}
+
+OCStackResult CAManager::setScanResponseData(const char* data, int length)
+{
+    CAResult_t ret = CASetScanResponseData(data, length);
+
+    return convertCAResultToOCResult(ret);
+}
+#endif
+
+OCStackResult CAManager::startLEAdvertising()
+{
+    OIC_LOG(INFO, TAG, "startLEAdvertising");
+    CAResult_t ret = CAUtilStartLEAdvertising();
+
+    return convertCAResultToOCResult(ret);
+}
+
+OCStackResult CAManager::stopLEAdvertising()
+{
+    OIC_LOG(INFO, TAG, "stopLEAdvertising");
+    CAResult_t ret = CAUtilStopLEAdvertising();
+
+    return convertCAResultToOCResult(ret);
+}
+
+OCStackResult CAManager::disconnectTCPSession(const char *address,
+                                              uint16_t port,
+                                              OCTransportFlags flags)
+{
+    if (!address)
+    {
+        OIC_LOG(ERROR, TAG, "address is invalid");
+        return OCStackResult::OC_STACK_INVALID_PARAM;
+    }
+
+    OIC_LOG_V(INFO, TAG, "disconnectTCPSession [addr:%s][port:%d][flags:%d]",
+              address, port, flags);
+    CAResult_t ret = CAUtilTCPDisconnectSession(address, port, (CATransportFlags_t)flags);
+
+    return convertCAResultToOCResult(ret);
+}
+
+OCStackResult CAManager::startCAGattServer()
+{
+    OIC_LOG(INFO, TAG, "startCAGattServer]");
+    CAResult_t ret = CAUtilStartGattServer();
+
+    return convertCAResultToOCResult(ret);
+}
+
+OCStackResult CAManager::stopCAGattServer()
+{
+       OIC_LOG(INFO, TAG, "stopCAGattServer]");
+    CAResult_t ret = CAUtilStopGattServer();
+
+    return convertCAResultToOCResult(ret);
+}
index ce2fb92..abea511 100644 (file)
 #include "OCResource.h"
 #include "ocpayload.h"
 #include <OCSerialization.h>
+#include "logger.h"
+#ifdef TCP_ADAPTER
+#include "oickeepalive.h"
+#endif
+
+#define TAG "OIC_CLIENT_WRAPPER"
+
 using namespace std;
 
 namespace OC
@@ -36,6 +43,24 @@ namespace OC
     {
         // if the config type is server, we ought to never get called.  If the config type
         // is both, we count on the server to run the thread and do the initialize
+        start();
+    }
+
+    InProcClientWrapper::~InProcClientWrapper()
+    {
+        try
+        {
+            stop();
+        }
+        catch (InitializeException &e)
+        {
+            oclog() << "Exception in stop"<< e.what() << std::flush;
+        }
+    }
+
+    OCStackResult InProcClientWrapper::start()
+    {
+        OIC_LOG_V(INFO, TAG, "start ocplatform for client : %d", m_cfg.transportType);
 
         if (m_cfg.mode == ModeType::Client)
         {
@@ -43,32 +68,45 @@ namespace OC
                             static_cast<OCTransportFlags>(m_cfg.serverConnectivity & CT_MASK_FLAGS);
             OCTransportFlags clientFlags =
                             static_cast<OCTransportFlags>(m_cfg.clientConnectivity & CT_MASK_FLAGS);
-            OCStackResult result = OCInit1(OC_CLIENT, serverFlags, clientFlags);
+            OCStackResult result = OCInit2(OC_CLIENT, serverFlags, clientFlags,
+                                           m_cfg.transportType);
 
             if (OC_STACK_OK != result)
             {
                 throw InitializeException(OC::InitException::STACK_INIT_ERROR, result);
             }
 
-            m_threadRun = true;
-            m_listeningThread = std::thread(&InProcClientWrapper::listeningFunc, this);
+            if (false == m_threadRun)
+            {
+                m_threadRun = true;
+                m_listeningThread = std::thread(&InProcClientWrapper::listeningFunc, this);
+            }
         }
+        return OC_STACK_OK;
     }
 
-    InProcClientWrapper::~InProcClientWrapper()
+    OCStackResult InProcClientWrapper::stop()
     {
+        OIC_LOG(INFO, TAG, "stop ocplatform");
+
         if (m_threadRun && m_listeningThread.joinable())
         {
             m_threadRun = false;
             m_listeningThread.join();
         }
 
-        // only stop if we are the ones who actually called 'init'.  We are counting
+        // only stop if we are the ones who actually called 'start'.  We are counting
         // on the server to do the stop.
         if (m_cfg.mode == ModeType::Client)
         {
-            OCStop();
+            OCStackResult result = OCStop();
+
+            if (OC_STACK_OK != result)
+            {
+               throw InitializeException(OC::InitException::STACK_TERMINATE_ERROR, result);
+            }
         }
+        return OC_STACK_OK;
     }
 
     void InProcClientWrapper::listeningFunc()
@@ -105,13 +143,11 @@ namespace OC
                 )
           )
         {
-            //OCPayloadDestroy(clientResponse->payload);
             return OCRepresentation();
         }
 
         MessageContainer oc;
         oc.setPayload(clientResponse->payload);
-        //OCPayloadDestroy(clientResponse->payload);
 
         std::vector<OCRepresentation>::const_iterator it = oc.representations().begin();
         if (it == oc.representations().end())
@@ -120,21 +156,25 @@ namespace OC
         }
 
         // first one is considered the root, everything else is considered a child of this one.
-        OCRepresentation root = *it;
-        root.setDevAddr(clientResponse->devAddr);
-        root.setUri(clientResponse->resourceUri);
-        ++it;
+       OCRepresentation root = *it;
+       root.setDevAddr(clientResponse->devAddr);
+       root.setUri(clientResponse->resourceUri);
+       ++it;
 
         std::for_each(it, oc.representations().end(),
                 [&root](const OCRepresentation& repItr)
                 {root.addChild(repItr);});
         return root;
-
     }
 
     OCStackApplicationResult listenCallback(void* ctx, OCDoHandle /*handle*/,
         OCClientResponse* clientResponse)
     {
+        if (!ctx || !clientResponse)
+        {
+            return OC_STACK_KEEP_TRANSACTION;
+        }
+
         ClientCallbackContext::ListenContext* context =
             static_cast<ClientCallbackContext::ListenContext*>(ctx);
 
@@ -195,18 +235,14 @@ namespace OC
 
         ClientCallbackContext::ListenErrorContext* context =
             static_cast<ClientCallbackContext::ListenErrorContext*>(ctx);
-        if (!context)
-        {
-            return OC_STACK_KEEP_TRANSACTION;
-        }
 
         OCStackResult result = clientResponse->result;
         if (result == OC_STACK_OK)
         {
             if (!clientResponse->payload || clientResponse->payload->type != PAYLOAD_TYPE_DISCOVERY)
             {
-                oclog() << "listenCallback(): clientResponse payload was null or the wrong type"
-                    << std::flush;
+                OIC_LOG_V(DEBUG, TAG, "%s: clientResponse payload was null or the wrong type",
+                          __func__);
                 return OC_STACK_KEEP_TRANSACTION;
             }
 
@@ -214,8 +250,8 @@ namespace OC
 
             if (!clientWrapper)
             {
-                oclog() << "listenCallback(): failed to get a shared_ptr to the client wrapper"
-                        << std::flush;
+                OIC_LOG_V(DEBUG, TAG, "%s: failed to get a shared_ptr to the client wrapper",
+                          __func__);
                 return OC_STACK_KEEP_TRANSACTION;
             }
 
@@ -230,7 +266,13 @@ namespace OC
             return OC_STACK_KEEP_TRANSACTION;
         }
 
-        std::string resourceURI = clientResponse->resourceUri;
+        OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
+        std::string resourceURI;
+        if(NULL != clientResponse->resourceUri)
+        {
+            resourceURI = clientResponse->resourceUri;
+        }
+
         std::thread exec(context->errorCallback, resourceURI, result);
         exec.detach();
         return OC_STACK_KEEP_TRANSACTION;
@@ -326,15 +368,20 @@ namespace OC
         return result;
     }
 
-    OCStackApplicationResult listenCallback2(void* ctx, OCDoHandle /*handle*/,
+    OCStackApplicationResult listenResListCallback(void* ctx, OCDoHandle /*handle*/,
         OCClientResponse* clientResponse)
     {
-        ClientCallbackContext::ListenContext2* context =
-            static_cast<ClientCallbackContext::ListenContext2*>(ctx);
+        if (!ctx || !clientResponse)
+        {
+            return OC_STACK_KEEP_TRANSACTION;
+        }
+
+        ClientCallbackContext::ListenResListContext* context =
+            static_cast<ClientCallbackContext::ListenResListContext*>(ctx);
 
         if (clientResponse->result != OC_STACK_OK)
         {
-            oclog() << "listenCallback2(): failed to create resource. clientResponse: "
+            oclog() << "listenResListCallback(): failed to create resource. clientResponse: "
                     << clientResponse->result
                     << std::flush;
 
@@ -343,7 +390,7 @@ namespace OC
 
         if (!clientResponse->payload || clientResponse->payload->type != PAYLOAD_TYPE_DISCOVERY)
         {
-            oclog() << "listenCallback2(): clientResponse payload was null or the wrong type"
+            oclog() << "listenResListCallback(): clientResponse payload was null or the wrong type"
                 << std::flush;
             return OC_STACK_KEEP_TRANSACTION;
         }
@@ -352,7 +399,7 @@ namespace OC
 
         if (!clientWrapper)
         {
-            oclog() << "listenCallback2(): failed to get a shared_ptr to the client wrapper"
+            oclog() << "listenResListCallback(): failed to get a shared_ptr to the client wrapper"
                     << std::flush;
             return OC_STACK_KEEP_TRANSACTION;
         }
@@ -362,20 +409,20 @@ namespace OC
             ListenOCContainer container(clientWrapper, clientResponse->devAddr,
                                     reinterpret_cast<OCDiscoveryPayload*>(clientResponse->payload));
 
+            OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
             std::thread exec(context->callback, container.Resources());
             exec.detach();
         }
         catch (std::exception &e)
         {
-            oclog() << "Exception in listCallback2, ignoring response: "
+            oclog() << "Exception in listenResListCallback(), ignoring response: "
                     << e.what() << std::flush;
         }
 
-
         return OC_STACK_KEEP_TRANSACTION;
     }
 
-    OCStackResult InProcClientWrapper::ListenForResource2(
+    OCStackResult InProcClientWrapper::ListenForResourceList(
             const std::string& serviceUrl,
             const std::string& resourceType,
             OCConnectivityType connectivityType,
@@ -390,12 +437,122 @@ namespace OC
         ostringstream resourceUri;
         resourceUri << serviceUrl << resourceType;
 
-        ClientCallbackContext::ListenContext2* context =
-            new ClientCallbackContext::ListenContext2(callback, shared_from_this());
+        ClientCallbackContext::ListenResListContext* context =
+            new ClientCallbackContext::ListenResListContext(callback, shared_from_this());
+        OCCallbackData cbdata;
+        cbdata.context = static_cast<void*>(context),
+        cbdata.cb      = listenResListCallback;
+        cbdata.cd      = [](void* c){delete (ClientCallbackContext::ListenResListContext*)c;};
+
+        auto cLock = m_csdkLock.lock();
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCDoResource(nullptr, OC_REST_DISCOVER,
+                                  resourceUri.str().c_str(),
+                                  nullptr, nullptr, connectivityType,
+                                  static_cast<OCQualityOfService>(QoS),
+                                  &cbdata,
+                                  nullptr, 0);
+        }
+        else
+        {
+            delete context;
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackApplicationResult listenResListWithErrorCallback(void* ctx, OCDoHandle /*handle*/,
+        OCClientResponse* clientResponse)
+    {
+        if (!ctx || !clientResponse)
+        {
+            return OC_STACK_KEEP_TRANSACTION;
+        }
+
+        ClientCallbackContext::ListenResListWithErrorContext* context =
+                static_cast<ClientCallbackContext::ListenResListWithErrorContext*>(ctx);
+
+        OCStackResult result = clientResponse->result;
+        if (result != OC_STACK_OK)
+        {
+            oclog() << "listenResListWithErrorCallback(): failed to create resource. clientResponse: "
+                    << result << std::flush;
+
+            //send the error callback
+            std::string uri;
+            if(NULL != clientResponse->resourceUri)
+            {
+                uri = clientResponse->resourceUri;
+            }
+            std::thread exec(context->errorCallback, uri, result);
+            exec.detach();
+            return OC_STACK_KEEP_TRANSACTION;
+        }
+
+        if (!clientResponse->payload || clientResponse->payload->type != PAYLOAD_TYPE_DISCOVERY)
+        {
+            oclog() << "listenResListWithErrorCallback(): clientResponse payload was null or the wrong type"
+                << std::flush;
+            return OC_STACK_KEEP_TRANSACTION;
+        }
+
+        auto clientWrapper = context->clientWrapper.lock();
+
+        if (!clientWrapper)
+        {
+            oclog() << "listenResListWithErrorCallback(): failed to get a shared_ptr to the client wrapper"
+                    << std::flush;
+            return OC_STACK_KEEP_TRANSACTION;
+        }
+
+        try
+        {
+            ListenOCContainer container(clientWrapper, clientResponse->devAddr,
+                            reinterpret_cast<OCDiscoveryPayload*>(clientResponse->payload));
+
+            OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
+            std::thread exec(context->callback, container.Resources());
+            exec.detach();
+        }
+        catch (std::exception &e)
+        {
+            oclog() << "Exception in listenResListWithErrorCallback(), ignoring response: "
+            << e.what() << std::flush;
+        }
+
+        return OC_STACK_KEEP_TRANSACTION;
+    }
+
+    OCStackResult InProcClientWrapper::ListenForResourceListWithError(
+            const std::string& serviceUrl,
+            const std::string& resourceType,
+            OCConnectivityType connectivityType,
+            FindResListCallback& callback,
+            FindErrorCallback& errorCallback, QualityOfService QoS)
+    {
+        if (!callback)
+        {
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        OCStackResult result;
+        ostringstream resourceUri;
+        resourceUri << serviceUrl << resourceType;
+
+        ClientCallbackContext::ListenResListWithErrorContext* context =
+            new ClientCallbackContext::ListenResListWithErrorContext(callback, errorCallback,
+                                                          shared_from_this());
+        if (!context)
+        {
+            return OC_STACK_ERROR;
+        }
+
         OCCallbackData cbdata;
         cbdata.context = static_cast<void*>(context),
-        cbdata.cb      = listenCallback2;
-        cbdata.cd      = [](void* c){delete (ClientCallbackContext::ListenContext2*)c;};
+        cbdata.cb      = listenResListWithErrorCallback;
+        cbdata.cd      = [](void* c){delete (ClientCallbackContext::ListenResListWithErrorContext*)c;};
 
         auto cLock = m_csdkLock.lock();
         if (cLock)
@@ -428,7 +585,12 @@ namespace OC
             return OC_STACK_DELETE_TRANSACTION;
         }
 
-        std::string resourceURI = clientResponse->resourceUri;
+        std::string resourceURI;
+        if(NULL != clientResponse->resourceUri)
+        {
+            resourceURI  = clientResponse->resourceUri;
+        }
+
         if (clientResponse->result != OC_STACK_OK)
         {
             oclog() << "listenMQCallback(): failed to create resource. clientResponse: "
@@ -529,6 +691,7 @@ namespace OC
 
         try
         {
+            OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
             OCRepresentation rep = parseGetSetCallback(clientResponse);
             std::thread exec(context->callback, rep);
             exec.detach();
@@ -645,7 +808,7 @@ namespace OC
             }
         }
 
-        if (!isLocationOption)
+        if (!isLocationOption && NULL != clientResponse->resourceUri)
         {
             createdUri = std::string(clientResponse->resourceUri);
         }
@@ -676,6 +839,7 @@ namespace OC
             }
             else
             {
+                OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
                 std::thread exec(context->callback, result,
                                  createdUri,
                                  nullptr);
@@ -742,7 +906,6 @@ namespace OC
     {
         ClientCallbackContext::GetContext* context =
             static_cast<ClientCallbackContext::GetContext*>(ctx);
-
         OCRepresentation rep;
         HeaderOptions serverHeaderOptions;
         OCStackResult result = clientResponse->result;
@@ -757,6 +920,7 @@ namespace OC
             result = e.code();
         }
 
+        OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
         std::thread exec(context->callback, serverHeaderOptions, rep, result);
         exec.detach();
         return OC_STACK_DELETE_TRANSACTION;
@@ -776,12 +940,12 @@ namespace OC
         OCStackResult result;
         ClientCallbackContext::GetContext* ctx =
             new ClientCallbackContext::GetContext(callback);
+
         OCCallbackData cbdata;
-        cbdata.context = static_cast<void*>(ctx),
+        cbdata.context = static_cast<void*>(ctx);
         cbdata.cb      = getResourceCallback;
         cbdata.cd      = [](void* c){delete (ClientCallbackContext::GetContext*)c;};
 
-
         std::string uri = assembleSetResourceUri(resourceUri, queryParams);
 
         auto cLock = m_csdkLock.lock();
@@ -831,6 +995,7 @@ namespace OC
             result = e.code();
         }
 
+        OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
         std::thread exec(context->callback, serverHeaderOptions, attrs, result);
         exec.detach();
         return OC_STACK_DELETE_TRANSACTION;
@@ -1031,6 +1196,7 @@ namespace OC
 
         parseServerHeaderOptions(clientResponse, serverHeaderOptions);
 
+        OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
         std::thread exec(context->callback, serverHeaderOptions, clientResponse->result);
         exec.detach();
         return OC_STACK_DELETE_TRANSACTION;
@@ -1104,6 +1270,7 @@ namespace OC
             result = e.code();
         }
 
+        OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
         std::thread exec(context->callback, serverHeaderOptions, attrs,
                     result, sequenceNumber);
         exec.detach();
@@ -1216,6 +1383,7 @@ namespace OC
          */
         std::string url = clientResponse->devAddr.addr;
 
+        OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
         std::thread exec(context->callback, clientResponse->result,
                     clientResponse->sequenceNumber, url);
 
@@ -1350,7 +1518,9 @@ namespace OC
             options[i].protocolID = OC_COAP_ID;
             options[i].optionID = it->getOptionID();
             options[i].optionLength = it->getOptionData().length() + 1;
-            strcpy((char*)options[i].optionData, (it->getOptionData().c_str()));
+            strncpy((char*)options[i].optionData, it->getOptionData().c_str(),
+                sizeof(options[i].optionLength) -1 );
+            options[i].optionData[sizeof(options[i].optionLength) - 1] = 0;
             i++;
         }
 
@@ -1405,6 +1575,7 @@ namespace OC
                     << std::flush;
             }
             else {
+                OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
                 convert(list, dpDeviceList);
                 std::thread exec(callback, dpDeviceList);
                 exec.detach();
@@ -1440,10 +1611,10 @@ namespace OC
             if (NULL == list)
             {
                 result = OC_STACK_NO_RESOURCE;
-                oclog() << "findDirectPairingDevices(): No device found for direct pairing"
-                    << std::flush;
+                OIC_LOG_V(DEBUG, TAG, "%s: No device found for direct pairing", __func__);
             }
             else {
+                OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
                 convert(list, dpDeviceList);
                 std::thread exec(callback, dpDeviceList);
                 exec.detach();
@@ -1465,6 +1636,7 @@ namespace OC
         ClientCallbackContext::DirectPairingContext* context =
             static_cast<ClientCallbackContext::DirectPairingContext*>(ctx);
 
+        OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
         std::thread exec(context->callback, cloneDevice(peer), result);
         exec.detach();
     }
@@ -1496,4 +1668,100 @@ namespace OC
         }
         return result;
     }
+#ifdef TCP_ADAPTER
+    OCStackApplicationResult KeepAliveRespCallback(void* ctx,
+                                                 OCDoHandle /*handle*/,
+        OCClientResponse* clientResponse)
+    {
+        ClientCallbackContext::KeepAliveContext* context =
+            static_cast<ClientCallbackContext::KeepAliveContext*>(ctx);
+        OCRepresentation attrs;
+        OCStackResult result = clientResponse->result;
+
+        try
+        {
+            attrs = parseGetSetCallback(clientResponse);
+        }
+        catch(OC::OCException& e)
+        {
+            result = e.code();
+        }
+
+        OIC_LOG_V(DEBUG, TAG, "%s: call response callback", __func__);
+        std::thread exec(context->callback, result, attrs);
+        exec.detach();
+        return OC_STACK_DELETE_TRANSACTION;
+    }
+
+    OCStackResult InProcClientWrapper::findKeepAliveResource(std::string host,
+                                                             KeepAliveCallback resultCallback)
+    {
+        if (host.empty() || !resultCallback)
+        {
+            oclog() << "Invalid parameters" << std::flush;
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        OCStackResult result = OC_STACK_ERROR;
+
+        ClientCallbackContext::KeepAliveContext* ctx =
+                       new ClientCallbackContext::KeepAliveContext(resultCallback);
+        OCCallbackData cbdata;
+        cbdata.context = static_cast<void*>(ctx),
+        cbdata.cb      = KeepAliveRespCallback;
+        cbdata.cd      = [](void* c){delete (ClientCallbackContext::KeepAliveContext*)c;};
+
+        auto cLock = m_csdkLock.lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCFindKeepAliveResource(nullptr, host.c_str(), &cbdata);
+        }
+        else
+        {
+            delete ctx;
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+
+    OCStackResult InProcClientWrapper::sendKeepAliveRequest(std::string host,
+                                                            const OCRepresentation& rep,
+                                                            KeepAliveCallback resultCallback)
+    {
+        if (!resultCallback)
+        {
+            oclog() << "Invalid parameters" << std::flush;
+            return OC_STACK_INVALID_PARAM;
+        }
+
+        OCStackResult result = OC_STACK_ERROR;
+
+        ClientCallbackContext::KeepAliveContext* ctx = new ClientCallbackContext::KeepAliveContext(resultCallback);
+        OCCallbackData cbdata;
+        cbdata.context = static_cast<void*>(ctx),
+        cbdata.cb      = KeepAliveRespCallback;
+        cbdata.cd      = [](void* c){delete (ClientCallbackContext::KeepAliveContext*)c;};
+
+        auto cLock = m_csdkLock.lock();
+
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            OCRepPayload *payload = rep.getPayload();
+            result = OCSendKeepAliveRequest (nullptr, host.c_str(), (OCPayload*)payload, &cbdata);
+            if (result != OC_STACK_OK)
+            {
+                OCRepPayloadDestroy(payload);
+            }
+        }
+        else
+        {
+            delete ctx;
+            result = OC_STACK_ERROR;
+        }
+        return result;
+    }
+#endif
 }
index fb26655..0659116 100644 (file)
@@ -38,6 +38,9 @@
 #include <oic_malloc.h>
 #include <OCPlatform.h>
 #include <OCUtilities.h>
+#include "logger.h"
+
+#define TAG "OIC_SERVER_WRAPPER"
 
 using namespace std;
 using namespace OC;
@@ -254,19 +257,27 @@ namespace OC
 {
     InProcServerWrapper::InProcServerWrapper(
         std::weak_ptr<std::recursive_mutex> csdkLock, PlatformConfig cfg)
-     : m_csdkLock(csdkLock)
+     : m_threadRun(false),
+       m_csdkLock(csdkLock),
+       m_cfg { cfg }       
     {
-        OCMode initType;
+        start();
+    }
+
+    OCStackResult InProcServerWrapper::start()
+    {
+        OIC_LOG_V(INFO, TAG, "start ocplatform for server : %d", m_cfg.transportType);
 
-        if(cfg.mode == ModeType::Server)
+        OCMode initType;
+        if(m_cfg.mode == ModeType::Server)
         {
             initType = OC_SERVER;
         }
-        else if (cfg.mode == ModeType::Both)
+        else if (m_cfg.mode == ModeType::Both)
         {
             initType = OC_CLIENT_SERVER;
         }
-        else if (cfg.mode == ModeType::Gateway)
+        else if (m_cfg.mode == ModeType::Gateway)
         {
             initType = OC_GATEWAY;
         }
@@ -277,18 +288,43 @@ namespace OC
         }
 
         OCTransportFlags serverFlags =
-                            static_cast<OCTransportFlags>(cfg.serverConnectivity & CT_MASK_FLAGS);
+                            static_cast<OCTransportFlags>(m_cfg.serverConnectivity & CT_MASK_FLAGS);
         OCTransportFlags clientFlags =
-                            static_cast<OCTransportFlags>(cfg.clientConnectivity & CT_MASK_FLAGS);
-        OCStackResult result = OCInit1(initType, serverFlags, clientFlags);
+                            static_cast<OCTransportFlags>(m_cfg.clientConnectivity & CT_MASK_FLAGS);
+        OCStackResult result = OCInit2(initType, serverFlags, clientFlags,
+                                       m_cfg.transportType);
 
         if(OC_STACK_OK != result)
         {
             throw InitializeException(OC::InitException::STACK_INIT_ERROR, result);
         }
 
-        m_threadRun = true;
-        m_processThread = std::thread(&InProcServerWrapper::processFunc, this);
+        if (false == m_threadRun)
+        {
+            m_threadRun = true;
+            m_processThread = std::thread(&InProcServerWrapper::processFunc, this);
+        }
+        return OC_STACK_OK;
+    }
+
+    OCStackResult InProcServerWrapper::stop()
+    {
+        OIC_LOG(INFO, TAG, "stop");
+
+        if(m_processThread.joinable())
+        {
+            m_threadRun = false;
+            m_processThread.join();
+        }
+
+        OCStackResult res = OCStop();
+
+        if (OC_STACK_OK != res)
+        {
+           throw InitializeException(OC::InitException::STACK_TERMINATE_ERROR, res);
+        }
+
+        return OC_STACK_OK;
     }
 
     void InProcServerWrapper::processFunc()
@@ -612,7 +648,6 @@ namespace OC
             }
             else
             {
-                OICFree(response.payload);
                 result = OC_STACK_ERROR;
             }
 
@@ -620,18 +655,67 @@ namespace OC
             {
                 oclog() << "Error sending response\n";
             }
+
+            OCPayloadDestroy(response.payload);
             return result;
         }
     }
 
-    InProcServerWrapper::~InProcServerWrapper()
+    OCStackResult InProcServerWrapper::notifyAllObservers(OCResourceHandle resourceHandle,
+                                                          QualityOfService QoS)
     {
-        if(m_processThread.joinable())
+        auto cLock = m_csdkLock.lock();
+        OCStackResult result = OC_STACK_ERROR;
+        if (cLock)
         {
-            m_threadRun = false;
-            m_processThread.join();
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+            result = OCNotifyAllObservers(resourceHandle, static_cast<OCQualityOfService>(QoS));
         }
 
-        OCStop();
+        return result;
+    }
+
+    OCStackResult InProcServerWrapper::notifyListOfObservers(OCResourceHandle resourceHandle,
+                                               ObservationIds& observationIds,
+                                               const std::shared_ptr<OCResourceResponse> pResponse,
+                                               QualityOfService QoS)
+    {
+        if (!pResponse)
+        {
+            return OC_STACK_ERROR;
+        }
+
+        auto cLock = m_csdkLock.lock();
+        OCStackResult result = OC_STACK_ERROR;
+        if (cLock)
+        {
+            std::lock_guard<std::recursive_mutex> lock(*cLock);
+
+            OCRepPayload* pl = pResponse->getResourceRepresentation().getPayload();
+            result = OCNotifyListOfObservers(resourceHandle,
+                                             &observationIds[0],
+                                             observationIds.size(),
+                                             pl,
+                                             static_cast<OCQualityOfService>(QoS));
+            OCRepPayloadDestroy(pl);
+        }
+
+        if (result != OC_STACK_OK)
+        {
+            throw OCException(OC::Exception::NOTIFY_LIST_OBSERVERS_FAILED, result);
+        }
+        return result;
+    }
+
+    InProcServerWrapper::~InProcServerWrapper()
+    {
+        try
+        {
+            stop();
+        }
+        catch (InitializeException &e)
+        {
+            oclog() << "Exception in stop"<< e.what() << std::flush;
+        }
     }
 }
index 6f2f6b6..8e55515 100644 (file)
@@ -107,14 +107,32 @@ std::string OC::OCException::reason(const OCStackResult sr)
             return OC::Exception::DUPLICATE_UUID;
         case OC_STACK_INCONSISTENT_DB:
             return OC::Exception::INCONSISTENT_DB;
+        case OC_STACK_SVR_DB_NOT_EXIST:
+            return OC::Exception::SVR_DB_NOT_EXIST;
         case OC_STACK_AUTHENTICATION_FAILURE:
             return OC::Exception::AUTHENTICATION_FAILURE;
         case OC_STACK_NOT_ALLOWED_OXM:
             return OC::Exception::NOT_ALLOWED_OXM;
+        case OC_STACK_USER_DENIED_REQ:
+            return OC::Exception::USER_DENIED_REQ;
+        case OC_STACK_NOT_ACCEPTABLE:
+            return OC::Exception::NOT_ACCEPTABLE;
         case OC_STACK_FORBIDDEN_REQ:
             return OC::Exception::FORBIDDEN_REQ;
         case OC_STACK_INTERNAL_SERVER_ERROR:
             return OC::Exception::INTERNAL_SERVER_ERROR;
+        case OC_STACK_METHOD_NOT_ALLOWED:
+            return OC::Exception::METHOD_NOT_ALLOWED;
+        case OC_STACK_NOT_IMPLEMENTED:
+            return OC::Exception::NOT_IMPLEMENTED;
+        case OC_STACK_BAD_GATEWAY:
+            return OC::Exception::BAD_GATEWAY;
+        case OC_STACK_SERVICE_UNAVAILABLE:
+            return OC::Exception::SERVICE_UNAVAILABLE;
+        case OC_STACK_GATEWAY_TIMEOUT:
+            return OC::Exception::GATEWAY_TIMEOUT;
+        case OC_STACK_PROXY_NOT_SUPPORTED:
+            return OC::Exception::PROXY_NOT_SUPPORTED;
     }
 
     return OC::Exception::UNKNOWN_ERROR;
index e9e90a1..f4cb635 100644 (file)
@@ -32,9 +32,19 @@ namespace OC
 {
     namespace OCPlatform
     {
-        void Configure(const PlatformConfig& config)
+        OCStackResult Configure(const PlatformConfig& config)
         {
-            OCPlatform_impl::Configure(config);
+            return OCPlatform_impl::Configure(config);
+        }
+
+        OCStackResult start()
+        {
+            return OCPlatform_impl::Instance().start();
+        }
+
+        OCStackResult stop()
+        {
+            return OCPlatform_impl::Instance().stop();
         }
 
         OCStackResult setDefaultDeviceEntityHandler(EntityHandler entityHandler)
@@ -131,6 +141,14 @@ namespace OC
                                     connectivityType, resourceHandler, QoS);
         }
 
+        OCStackResult findResourceList(const std::string& host, const std::string& resourceURI,
+                    OCConnectivityType connectivityType, FindResListCallback resourceHandler,
+                    FindErrorCallback errorHandler, QualityOfService QoS)
+        {
+            return OCPlatform_impl::Instance().findResourceList(host, resourceURI,
+                                    connectivityType, resourceHandler, errorHandler, QoS);
+        }
+
         OCStackResult getDeviceInfo(const std::string& host,
                                  const std::string& deviceURI,
                                  OCConnectivityType connectivityType,
@@ -336,6 +354,18 @@ namespace OC
                                                                              connectivityType);
         }
 #endif // WITH_CLOUD
+#ifdef TCP_ADAPTER
+        OCStackResult findKeepAliveResource(std::string host, KeepAliveCallback resultCallback)
+        {
+            return OCPlatform_impl::Instance().findKeepAliveResource(host, resultCallback);
+        }
+
+        OCStackResult sendKeepAliveRequest(std::string host, const OCRepresentation& rep,
+                                                             KeepAliveCallback pingHandler)
+        {
+            return OCPlatform_impl::Instance().sendKeepAliveRequest(host, rep, pingHandler);
+        }
+#endif
 
         OCStackResult getDeviceId(OCUUIdentity *deviceId)
         {
old mode 100644 (file)
new mode 100755 (executable)
index a8e8fd3..d782d6b
 #include "OCUtilities.h"
 #include "ocpayload.h"
 
+#include "logger.h"
 #include "oc_logger.hpp"
 
+#define TAG "OIC_PLATFORM"
+
 namespace OC
 {
 
@@ -55,10 +58,24 @@ namespace OC
         return s_config;
     }
 
-    void OCPlatform_impl::Configure(const PlatformConfig& config)
+    OCStackResult OCPlatform_impl::Configure(const PlatformConfig& config)
     {
-        OCRegisterPersistentStorageHandler(config.ps);
+        OIC_LOG_V(INFO, TAG, "Configure : %d %p", config.transportType, config.ps);
+        OCStackResult res = OC_STACK_OK;
+
+        res = OCSetSecurePSI(config.key, config.ps, config.psEnc, config.psRescue);
+        if (OC_STACK_OK == res && config.psEnc)
+        {
+            OIC_LOG(INFO, TAG, "It uses psEnc for svr db.");
+            res = OCRegisterPersistentStorageHandler(config.psEnc);
+        } else
+        {
+            OIC_LOG(INFO, TAG, "It uses ps for svr db.");
+            res = OCRegisterPersistentStorageHandler(config.ps);
+        }
+
         globalConfig() = config;
+        return res;
     }
 
     OCPlatform_impl& OCPlatform_impl::Instance()
@@ -67,22 +84,105 @@ namespace OC
         return platform;
     }
 
+    OCStackResult OCPlatform_impl::start()
+    {
+        OIC_LOG(INFO, TAG, "start");
+
+        OCStackResult res = OC_STACK_OK;
+        if (OC_CLIENT == m_modeType)
+        {
+            if (OC_STACK_OK != checked_guard(m_client, &IClientWrapper::start))
+            {
+                res = OC_STACK_ERROR;
+            }
+        }
+        else if (OC_SERVER == m_modeType)
+        {
+            if (OC_STACK_OK != checked_guard(m_server, &IServerWrapper::start))
+            {
+                res = OC_STACK_ERROR;
+            }
+        }
+        else if (OC_CLIENT_SERVER == m_modeType || OC_GATEWAY == m_modeType)
+        {
+            if (OC_STACK_OK != checked_guard(m_client, &IClientWrapper::start))
+            {
+                res = OC_STACK_ERROR;
+            }
+
+            if (OC_STACK_OK != checked_guard(m_server, &IServerWrapper::start))
+            {
+                res = OC_STACK_ERROR;
+            }
+        }
+        else
+        {
+            res = OC_STACK_ERROR;
+        }
+
+        return res;
+    }
+
+    OCStackResult OCPlatform_impl::stop()
+    {
+        OIC_LOG(INFO, TAG, "stop");
+
+        OCStackResult res = OC_STACK_OK;
+        if (OC_CLIENT == m_modeType)
+        {
+            if (OC_STACK_OK != checked_guard(m_client, &IClientWrapper::stop))
+            {
+                res = OC_STACK_ERROR;
+            }
+        }
+        else if (OC_SERVER == m_modeType)
+        {
+            if (OC_STACK_OK != checked_guard(m_server, &IServerWrapper::stop))
+            {
+                res = OC_STACK_ERROR;
+            }
+        }
+        else if (OC_CLIENT_SERVER == m_modeType)
+        {
+            if (OC_STACK_OK != checked_guard(m_client, &IClientWrapper::stop))
+            {
+                res = OC_STACK_ERROR;
+            }
+
+            if (OC_STACK_OK != checked_guard(m_server, &IServerWrapper::stop))
+            {
+                res = OC_STACK_ERROR;
+            }
+        }
+        else
+        {
+            res = OC_STACK_ERROR;
+        }
+
+        return res;
+    }
+
     void OCPlatform_impl::init(const PlatformConfig& config)
     {
+        OIC_LOG(INFO, TAG, "init");
+
         switch(config.mode)
         {
             case ModeType::Server:
                 m_server = m_WrapperInstance->CreateServerWrapper(m_csdkLock, config);
+                m_modeType = OC_SERVER;
                 break;
 
             case ModeType::Client:
                 m_client = m_WrapperInstance->CreateClientWrapper(m_csdkLock, config);
+                m_modeType = OC_CLIENT;
                 break;
 
             case ModeType::Both:
             case ModeType::Gateway:
                 m_server = m_WrapperInstance->CreateServerWrapper(m_csdkLock, config);
                 m_client = m_WrapperInstance->CreateClientWrapper(m_csdkLock, config);
+                m_modeType = OC_CLIENT_SERVER;
                 break;
          }
     }
@@ -108,8 +208,7 @@ namespace OC
     OCStackResult OCPlatform_impl::notifyAllObservers(OCResourceHandle resourceHandle,
                                                 QualityOfService QoS)
     {
-        return result_guard(OCNotifyAllObservers(resourceHandle,
-                    static_cast<OCQualityOfService>(QoS)));
+        return checked_guard(m_server, &IServerWrapper::notifyAllObservers, resourceHandle, QoS);
     }
 
     OCStackResult OCPlatform_impl::notifyAllObservers(OCResourceHandle resourceHandle)
@@ -129,19 +228,8 @@ namespace OC
                                        const std::shared_ptr<OCResourceResponse> pResponse,
                                        QualityOfService QoS)
     {
-        if(!pResponse)
-        {
-         return result_guard(OC_STACK_ERROR);
-        }
-
-        OCRepPayload* pl = pResponse->getResourceRepresentation().getPayload();
-        OCStackResult result =
-                   OCNotifyListOfObservers(resourceHandle,
-                            &observationIds[0], observationIds.size(),
-                            pl,
-                            static_cast<OCQualityOfService>(QoS));
-        OCRepPayloadDestroy(pl);
-        return result_guard(result);
+        return checked_guard(m_server, &IServerWrapper::notifyListOfObservers, resourceHandle,
+                             observationIds, pResponse, QoS);
     }
 
     OCResource::Ptr OCPlatform_impl::constructResourceObject(const std::string& host,
@@ -166,7 +254,7 @@ namespace OC
                                             uri, "", connectivityType,
                                             resourceProperty,
                                             resourceTypes,
-                                            interfaces));
+                                            interfaces, ""));
     }
 
     OCStackResult OCPlatform_impl::findResource(const std::string& host,
@@ -215,10 +303,22 @@ namespace OC
                                             FindResListCallback resourceHandler,
                                             QualityOfService QoS)
     {
-        return checked_guard(m_client, &IClientWrapper::ListenForResource2,
+        return checked_guard(m_client, &IClientWrapper::ListenForResourceList,
                              host, resourceName, connectivityType, resourceHandler, QoS);
     }
 
+    OCStackResult OCPlatform_impl::findResourceList(const std::string& host,
+                                            const std::string& resourceName,
+                                            OCConnectivityType connectivityType,
+                                            FindResListCallback resourceHandler,
+                                            FindErrorCallback errorHandler,
+                                            QualityOfService Qos)
+    {
+        return checked_guard(m_client, &IClientWrapper::ListenForResourceListWithError,
+                             host, resourceName, connectivityType, resourceHandler,
+                             errorHandler, Qos);
+    }
+
     OCStackResult OCPlatform_impl::getDeviceInfo(const std::string& host,
                                             const std::string& deviceURI,
                                             OCConnectivityType connectivityType,
@@ -478,7 +578,19 @@ namespace OC
                                                                       connectivityType));
     }
 #endif // WITH_CLOUD
+#ifdef TCP_ADAPTER
+    OCStackResult OCPlatform_impl::findKeepAliveResource(std::string host, KeepAliveCallback resultCallback)
+    {
+        return checked_guard(m_client, &IClientWrapper::findKeepAliveResource, host, resultCallback);
+    }
 
+    OCStackResult OCPlatform_impl::sendKeepAliveRequest(std::string host, const OCRepresentation& rep,
+                                                        KeepAliveCallback resultCallback)
+    {
+        return checked_guard(m_client, &IClientWrapper::sendKeepAliveRequest, host,
+                             rep, resultCallback);
+    }
+#endif
     OCStackResult OCPlatform_impl::getDeviceId(OCUUIdentity *myUuid)
     {
         return OCGetDeviceId(myUuid);
index 9db45ec..3d42719 100644 (file)
@@ -633,14 +633,14 @@ namespace OC
         m_children = children;
     }
 
-    void OCRepresentation::setDevAddr(const OCDevAddr m_devAddr)
+    void OCRepresentation::setDevAddr(const OCDevAddrdevAddr)
     {
         std::ostringstream ss;
-        if (m_devAddr.flags & OC_SECURE)
+        if (devAddr.flags & OC_SECURE)
         {
             ss << COAPS;
         }
-        else if (m_devAddr.adapter & OC_ADAPTER_TCP)
+        else if (devAddr.adapter & OC_ADAPTER_TCP)
         {
             ss << COAP_TCP;
         }
@@ -648,13 +648,13 @@ namespace OC
         {
             ss << COAP;
         }
-        if (m_devAddr.flags & OC_IP_USE_V6)
+        if (devAddr.flags & OC_IP_USE_V6)
         {
             char addressEncoded[128] = {0};
 
             OCStackResult result = OCEncodeAddressForRFC6874(addressEncoded,
                                                              sizeof(addressEncoded),
-                                                             m_devAddr.addr);
+                                                             devAddr.addr);
             if (OC_STACK_OK != result)
             {
                 throw OC::OCException("Invalid address in setDevAddr");
@@ -663,11 +663,11 @@ namespace OC
         }
         else
         {
-            ss << m_devAddr.addr;
+            ss << devAddr.addr;
         }
-        if (m_devAddr.port)
+        if (devAddr.port)
         {
-            ss << ':' << m_devAddr.port;
+            ss << ':' << devAddr.port;
         }
         m_host = ss.str();
     }
index 60306d8..0728df0 100644 (file)
@@ -52,12 +52,13 @@ OCResource::OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
                         const OCDevAddr& devAddr, const std::string& uri,
                         const std::string& serverId, uint8_t property,
                         const std::vector<std::string>& resourceTypes,
-                        const std::vector<std::string>& interfaces)
+                        const std::vector<std::string>& interfaces,
+                        const std::string& deviceName)
  :  m_clientWrapper(clientWrapper), m_uri(uri),
     m_resourceId(serverId, m_uri), m_devAddr(devAddr),
     m_isCollection(false), m_property(property),
     m_resourceTypes(resourceTypes), m_interfaces(interfaces),
-    m_observeHandle(nullptr)
+    m_observeHandle(nullptr), m_deviceName(deviceName)
 {
     m_isCollection = std::find(m_interfaces.begin(), m_interfaces.end(), LINK_INTERFACE)
                         != m_interfaces.end();
@@ -67,8 +68,8 @@ OCResource::OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
         interfaces.empty()||
         m_clientWrapper.expired())
     {
-        throw ResourceInitException(m_uri.empty(), resourceTypes.empty(),
-                interfaces.empty(), m_clientWrapper.expired(), false, false);
+        throw ResourceInitException(m_uri.empty(), false, resourceTypes.empty(),
+                interfaces.empty(), m_clientWrapper.expired(), false, false, false);
     }
 }
 
@@ -77,18 +78,19 @@ OCResource::OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
                         const std::string& serverId,
                         OCConnectivityType connectivityType, uint8_t property,
                         const std::vector<std::string>& resourceTypes,
-                        const std::vector<std::string>& interfaces)
+                        const std::vector<std::string>& interfaces,
+                        const std::string& deviceName)
  :  m_clientWrapper(clientWrapper), m_uri(uri),
     m_resourceId(serverId, m_uri),
     m_isCollection(false), m_property(property),
     m_resourceTypes(resourceTypes), m_interfaces(interfaces),
-    m_observeHandle(nullptr)
+    m_observeHandle(nullptr), m_deviceName(deviceName)
 {
     m_devAddr = OCDevAddr{OC_DEFAULT_ADAPTER, OC_DEFAULT_FLAGS, 0, {0}, 0,
 #if defined (ROUTING_GATEWAY) || defined (ROUTING_EP)
-                          {0}
+                          {0},
 #endif
-                        };
+                          {0}};
     m_isCollection = std::find(m_interfaces.begin(), m_interfaces.end(), LINK_INTERFACE)
                         != m_interfaces.end();
 
@@ -97,20 +99,20 @@ OCResource::OCResource(std::weak_ptr<IClientWrapper> clientWrapper,
         interfaces.empty()||
         m_clientWrapper.expired())
     {
-        throw ResourceInitException(m_uri.empty(), resourceTypes.empty(),
-                interfaces.empty(), m_clientWrapper.expired(), false, false);
+        throw ResourceInitException(m_uri.empty(), false, resourceTypes.empty(),
+                interfaces.empty(), m_clientWrapper.expired(), false, false, false);
     }
 
     if (uri.length() == 1 && uri[0] == '/')
     {
-        throw ResourceInitException(m_uri.empty(), resourceTypes.empty(),
-                interfaces.empty(), m_clientWrapper.expired(), false, false);
+        throw ResourceInitException(m_uri.empty(), true, resourceTypes.empty(),
+                interfaces.empty(), m_clientWrapper.expired(), false, false, false);
     }
 
     if (uri[0] != '/')
     {
-        throw ResourceInitException(m_uri.empty(), resourceTypes.empty(),
-                interfaces.empty(), m_clientWrapper.expired(), false, false);
+        throw ResourceInitException(m_uri.empty(), true, resourceTypes.empty(),
+                interfaces.empty(), m_clientWrapper.expired(), false, false, false);
     }
 
     // construct the devAddr from the pieces we have
@@ -156,8 +158,8 @@ void OCResource::setHost(const std::string& host)
     }
     else
     {
-        throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-            m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+        throw ResourceInitException(m_uri.empty(), false, m_resourceTypes.empty(),
+            m_interfaces.empty(), m_clientWrapper.expired(), false, false, true);
     }
 
     // remove 'coap://' or 'coaps://' or 'coap+tcp://' or 'coap+gatt://' or 'coap+rfcomm://'
@@ -169,8 +171,8 @@ void OCResource::setHost(const std::string& host)
 
         if (std::string::npos == bracket || 0 == bracket)
         {
-            throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-                m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+            throw ResourceInitException(m_uri.empty(), false, m_resourceTypes.empty(),
+                m_interfaces.empty(), m_clientWrapper.expired(), false, true, false);
         }
         // extract the ipv6 address
         std::string ip6Addr = host_token.substr(1, bracket - 1);
@@ -186,8 +188,8 @@ void OCResource::setHost(const std::string& host)
         const char *cAddr = ip6AddrToValidityCheck.c_str();
         if (0 == inet_pton(AF_INET6, cAddr, &buf))
         {
-            throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-                m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+            throw ResourceInitException(m_uri.empty(), false, m_resourceTypes.empty(),
+                m_interfaces.empty(), m_clientWrapper.expired(), true, false, false);
         }
 
         //skip ']' and ':' characters in host string
@@ -196,8 +198,8 @@ void OCResource::setHost(const std::string& host)
 
         if (0 > port || UINT16_MAX < port)
         {
-            throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-                m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+            throw ResourceInitException(m_uri.empty(), false, m_resourceTypes.empty(),
+                m_interfaces.empty(), m_clientWrapper.expired(), true, false, false);
         }
 
         OCStackResult result = OCDecodeAddressForRFC6874(m_devAddr.addr,
@@ -205,8 +207,8 @@ void OCResource::setHost(const std::string& host)
 
         if (OC_STACK_OK != result)
         {
-            throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-                m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+            throw ResourceInitException(m_uri.empty(), false, m_resourceTypes.empty(),
+                m_interfaces.empty(), m_clientWrapper.expired(), false, true, false);
         }
 
         m_devAddr.port = static_cast<uint16_t>(port);
@@ -214,8 +216,8 @@ void OCResource::setHost(const std::string& host)
     }
     else if (host_token[0] == ':')
     {
-        throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-            m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+        throw ResourceInitException(m_uri.empty(), false, m_resourceTypes.empty(),
+            m_interfaces.empty(), m_clientWrapper.expired(), false, false, true);
     }
     else
     {
@@ -227,8 +229,8 @@ void OCResource::setHost(const std::string& host)
             // address validity check
             if (MAC_ADDR_STR_SIZE != macAddr.length())
             {
-                throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-                    m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+                throw ResourceInitException(m_uri.empty(), false, m_resourceTypes.empty(),
+                    m_interfaces.empty(), m_clientWrapper.expired(), false, true, false);
             }
 
             for (size_t blockCnt = 0; blockCnt < MAC_ADDR_BLOCKS; blockCnt++)
@@ -237,8 +239,8 @@ void OCResource::setHost(const std::string& host)
 
                 if (std::string::npos != block.find_first_not_of("0123456789ABCDEFabcdef"))
                 {
-                    throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-                        m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+                    throw ResourceInitException(m_uri.empty(), false, m_resourceTypes.empty(),
+                        m_interfaces.empty(), m_clientWrapper.expired(), false, true, false);
                 }
 
                 if (MAC_ADDR_BLOCKS - 1 > blockCnt)
@@ -247,8 +249,8 @@ void OCResource::setHost(const std::string& host)
 
                     if (':' != delimiter)
                     {
-                        throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-                            m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+                        throw ResourceInitException(m_uri.empty(), false, m_resourceTypes.empty(),
+                            m_interfaces.empty(), m_clientWrapper.expired(), false, true, false);
                     }
                 }
             }
@@ -262,8 +264,8 @@ void OCResource::setHost(const std::string& host)
 
             if (colon == std::string::npos || colon == 0)
             {
-                throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-                    m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+                throw ResourceInitException(m_uri.empty(), false, m_resourceTypes.empty(),
+                    m_interfaces.empty(), m_clientWrapper.expired(), false, true, false);
             }
 
             // extract the ipv4 address
@@ -274,8 +276,8 @@ void OCResource::setHost(const std::string& host)
             const char *cAddr = ip4Addr.c_str();
             if (0 == inet_pton(AF_INET, cAddr, &buf))
             {
-                throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-                    m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+                throw ResourceInitException(m_uri.empty(), false, m_resourceTypes.empty(),
+                    m_interfaces.empty(), m_clientWrapper.expired(), true, false, false);
             }
 
             //skip ':' characters in host string
@@ -284,8 +286,8 @@ void OCResource::setHost(const std::string& host)
 
             if (0 > port || UINT16_MAX < port)
             {
-                throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-                    m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+                throw ResourceInitException(m_uri.empty(), false, m_resourceTypes.empty(),
+                    m_interfaces.empty(), m_clientWrapper.expired(), true, false, false);
             }
 
             ip4Addr.copy(m_devAddr.addr, sizeof(m_devAddr.addr));
@@ -554,8 +556,8 @@ std::string OCResource::host() const
                                                          m_devAddr.addr);
         if (OC_STACK_OK != result)
         {
-            throw ResourceInitException(m_uri.empty(), m_resourceTypes.empty(),
-                m_interfaces.empty(), m_clientWrapper.expired(), false, false);
+            throw ResourceInitException(m_uri.empty(), false, m_resourceTypes.empty(),
+                m_interfaces.empty(), m_clientWrapper.expired(), false, true, false);
         }
         ss << '[' << addressEncoded << ']';
     }
@@ -613,6 +615,16 @@ std::string OCResource::sid() const
     return this->uniqueIdentifier().m_representation;
 }
 
+std::string OCResource::deviceName() const
+{
+    return m_deviceName;
+}
+
+OCDevAddr OCResource::getDevAddr() const
+{
+    return m_devAddr;
+}
+
 #ifdef WITH_MQ
 OCStackResult OCResource::discoveryMQTopics(const QueryParamsMap& queryParametersMap,
                                             MQTopicCallback attributeHandler,
index 463bffb..79900ae 100644 (file)
@@ -33,6 +33,7 @@ secured = oclib_env.get('SECURED')
 target_os = oclib_env.get('TARGET_OS')
 with_cloud = oclib_env.get('WITH_CLOUD')
 with_mq = oclib_env.get('WITH_MQ')
+ble_custom_adv = oclib_env.get('BLE_CUSTOM_ADV')
 
 ######################################################################
 # Build flags
@@ -91,6 +92,9 @@ if target_os in ['msys_nt', 'windows']:
 if with_cloud:
        oclib_env.AppendUnique(CPPDEFINES = ['WITH_CLOUD'])
 
+if ble_custom_adv == True:
+               env.AppendUnique(CPPDEFINES = ['BLE_CUSTOM_ADVERTISE'])
+
 if 'SUB' in with_mq:
        oclib_env.AppendUnique(CPPDEFINES = ['MQ_SUBSCRIBER', 'WITH_MQ'])
 
index 3c4fcf0..921b45f 100644 (file)
@@ -66,17 +66,26 @@ namespace OC
                 OC_STACK_INVALID_JSON,
                 OC_STACK_UNAUTHORIZED_REQ,
                 OC_STACK_TOO_LARGE_REQ,
-                OC_STACK_PRESENCE_STOPPED,
-                OC_STACK_PRESENCE_TIMEOUT,
-                OC_STACK_PRESENCE_DO_NOT_HANDLE,
-                OC_STACK_ERROR,
                 OC_STACK_PDM_IS_NOT_INITIALIZED,
                 OC_STACK_DUPLICATE_UUID,
                 OC_STACK_INCONSISTENT_DB,
+                OC_STACK_SVR_DB_NOT_EXIST,
                 OC_STACK_AUTHENTICATION_FAILURE,
                 OC_STACK_NOT_ALLOWED_OXM,
+                OC_STACK_PRESENCE_STOPPED,
+                OC_STACK_PRESENCE_TIMEOUT,
+                OC_STACK_PRESENCE_DO_NOT_HANDLE,
+                OC_STACK_USER_DENIED_REQ,
+                OC_STACK_NOT_ACCEPTABLE,
+                OC_STACK_METHOD_NOT_ALLOWED,
                 OC_STACK_FORBIDDEN_REQ,
-                OC_STACK_INTERNAL_SERVER_ERROR
+                OC_STACK_INTERNAL_SERVER_ERROR,
+                OC_STACK_NOT_IMPLEMENTED,
+                OC_STACK_BAD_GATEWAY,
+                OC_STACK_SERVICE_UNAVAILABLE,
+                OC_STACK_GATEWAY_TIMEOUT,
+                OC_STACK_PROXY_NOT_SUPPORTED,
+                OC_STACK_ERROR
             };
 
             std::string resultMessages[]=
@@ -114,17 +123,26 @@ namespace OC
                 OC::Exception::INVALID_REPRESENTATION,
                 OC::Exception::UNAUTHORIZED_REQUEST,
                 OC::Exception::TOO_LARGE_REQ,
-                OC::Exception::PRESENCE_STOPPED,
-                OC::Exception::PRESENCE_TIMEOUT,
-                OC::Exception::PRESENCE_NOT_HANDLED,
-                OC::Exception::GENERAL_FAULT,
                 OC::Exception::PDM_DB_NOT_INITIALIZED,
                 OC::Exception::DUPLICATE_UUID,
                 OC::Exception::INCONSISTENT_DB,
+                OC::Exception::SVR_DB_NOT_EXIST,
                 OC::Exception::AUTHENTICATION_FAILURE,
                 OC::Exception::NOT_ALLOWED_OXM,
+                OC::Exception::PRESENCE_STOPPED,
+                OC::Exception::PRESENCE_TIMEOUT,
+                OC::Exception::PRESENCE_NOT_HANDLED,
+                OC::Exception::USER_DENIED_REQ,
+                OC::Exception::NOT_ACCEPTABLE,
+                OC::Exception::METHOD_NOT_ALLOWED,
                 OC::Exception::FORBIDDEN_REQ,
-                OC::Exception::INTERNAL_SERVER_ERROR
+                OC::Exception::INTERNAL_SERVER_ERROR,
+                OC::Exception::NOT_IMPLEMENTED,
+                OC::Exception::BAD_GATEWAY,
+                OC::Exception::SERVICE_UNAVAILABLE,
+                OC::Exception::GATEWAY_TIMEOUT,
+                OC::Exception::PROXY_NOT_SUPPORTED,
+                OC::Exception::GENERAL_FAULT
             };
             TEST(OCExceptionTest, ReasonCodeMatches)
             {
index d39ae95..5c5a69f 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <gtest/gtest.h>
 #include <OCApi.h>
+#include "oic_string.h"
 #include <string>
 #include <limits>
 #include <boost/lexical_cast.hpp>
@@ -1449,7 +1450,7 @@ namespace OCRepresentationTest
     {
         OCDevAddr addr = {OC_DEFAULT_ADAPTER, OC_IP_USE_V6};
         addr.port = 5000;
-        strcpy(addr.addr, "fe80::1%eth0");
+        OICStrcpy(addr.addr, sizeof(addr.addr), "fe80::1%eth0");
 
         OCRepresentation rep;
         rep.setDevAddr(addr);
@@ -1462,7 +1463,7 @@ namespace OCRepresentationTest
     {
         OCDevAddr addr = {OC_DEFAULT_ADAPTER, OC_IP_USE_V6};
         addr.port = 5000;
-        strcpy(addr.addr, "fe80::1%%");
+        OICStrcpy(addr.addr, sizeof(addr.addr), "fe80::1%%");
 
         OCRepresentation rep;
         EXPECT_ANY_THROW(rep.setDevAddr(addr));
index d28d59f..4c7175a 100755 (executable)
@@ -26,29 +26,32 @@ Import('env')
 
 target_os = env.get('TARGET_OS')
 
-if target_os not in ['arduino','darwin','windows']:
+if target_os not in ['arduino','darwin','ios','windows']:
+    # Build resource-hosting project
+    # SConscript('resource-hosting/SConscript')
+
     # Build resource-encapsulation project
     SConscript('resource-encapsulation/SConscript')
 
     # Build resource-container project
-    SConscript('resource-container/SConscript')
+    SConscript('resource-container/SConscript')
 
     # Build scene-manager project
-    if target_os in ['linux','ios']:
-        SConscript('scene-manager/SConscript')
+    # if target_os in ['linux']:
+    #    SConscript('scene-manager/SConscript')
 
     # Build notification-service project
-    if target_os in ['linux','android','tizen','ios']:
+    if target_os in ['linux','android','tizen']:
         SConscript('notification/SConscript')
 
     # Build simulator module
-    if target_os in ['linux'] and env.get('SIMULATOR', False):
-        SConscript('simulator/SConscript')
+    if target_os in ['linux'] and env.get('SIMULATOR', False):
+    #    SConscript('simulator/SConscript')
 
     # Build coap-http-proxy project
-    if target_os in ['linux', 'tizen'] and env.get('WITH_PROXY', False):
-        SConscript('coap-http-proxy/SConscript')
+    if target_os in ['linux', 'tizen'] and env.get('WITH_PROXY', False):
+    #    SConscript('coap-http-proxy/SConscript')
 
 # Build EasySetup module
-if target_os in ['arduino', 'android', 'ios', 'linux','tizen']:
+if target_os in ['arduino', 'android','linux','tizen']:
     SConscript('easy-setup/SConscript')
index c0e9d6e..6912e5d 100644 (file)
@@ -32,7 +32,11 @@ extern "C"
 #endif
 
 #include "CoapHttpParser.h"
+#if defined (__TIZENRT__)
+#include <apps/netutils/cJSON.h>
+#else
 #include "cJSON.h"
+#endif
 
 /**
  * Function to get CoAP code for an HTTP code.
index 688d780..8d7eb64 100644 (file)
 #include "uarraylist.h"
 #include "CoapHttpParser.h"
 #include "CoapHttpMap.h"
+#if defined (__TIZENRT__)
+#include <apps/netutils/cJSON.h>
+#else
 #include "cJSON.h"
+#endif
 
 #define TAG "CHPHandler"
 
index 3fa714f..3eade69 100644 (file)
 #include "uarraylist.h"
 #include "CoapHttpParser.h"
 #include "CoapHttpMap.h"
+#if defined (__TIZENRT__)
+#include <apps/netutils/cJSON.h>
+#else
 #include "cJSON.h"
+#endif
 
 #include <signal.h>
 #ifdef HAVE_UNISTD_H
index e5677bc..cb3edca 100644 (file)
@@ -80,8 +80,7 @@ if target_os in ['linux']:
 
 
 if CoAP_test_env.get('SECURED') == '1':
-       if CoAP_test_env.get('WITH_TCP') == True:
-               CoAP_test_env.AppendUnique(LIBS = ['mbedtls', 'mbedx509', 'mbedcrypto','tinydtls'])
+    CoAP_test_env.AppendUnique(LIBS = ['mbedtls', 'mbedx509', 'mbedcrypto'])
 ######################################################################
 # Build Test
 ######################################################################
index c740000..b2401f2 100644 (file)
@@ -50,9 +50,10 @@ enrollee_env.PrependUnique(CPPPATH = [
                enrollee_env.get('SRC_DIR') + '/extlibs/cjson',
                enrollee_env.get('SRC_DIR') + '/service/easy-setup/inc',
                enrollee_env.get('SRC_DIR') + '/service/easy-setup/enrollee/inc',
-               enrollee_env.get('SRC_DIR') + '/service/easy-setup/enrollee/src'])
-
-if target_os not in ['linux', 'tizen']:
+               enrollee_env.get('SRC_DIR') + '/service/easy-setup/enrollee/src',
+               enrollee_env.get('SRC_DIR') + '/service/easy-setup/enrollee/inc/samsung',
+               enrollee_env.get('SRC_DIR') + '/service/easy-setup/enrollee/src/samsung'])
+if target_os not in ['tizen']:
     enrollee_env.PrependUnique(CPPPATH = [
         enrollee_env.get('SRC_DIR') + '/extlibs/sqlite3'])
 
@@ -105,7 +106,7 @@ if target_os == 'arduino':
 es_enrollee_src = None
 
 if target_os in ['linux', 'tizen']:
-       es_enrollee_common_src = ['./src/easysetup.c','./src/resourcehandler.c']
+       es_enrollee_common_src = ['./src/easysetup.c','./src/resourcehandler.c', './src/samsung/sc_easysetup.c']
        enrollee_sdk_shared = enrollee_env.SharedLibrary('ESEnrolleeSDK', es_enrollee_common_src)
        enrollee_sdk_static = enrollee_env.StaticLibrary('ESEnrolleeSDK', es_enrollee_common_src)
        enrollee_env.InstallTarget([enrollee_sdk_shared, enrollee_sdk_static], 'libESEnrollee')
@@ -123,9 +124,10 @@ if target_os == 'arduino':
 #if target_os == 'arduino':
 #      SConscript('../sampleapp/enrollee/arduino/SConscript')
 
-if target_os in ['linux']:
-       SConscript('../sampleapp/enrollee/linux/SConscript')
-       #Build UnitTestcases for Enrollee
-       if enrollee_env.get('SECURED') == '0':
-               SConscript('../enrollee/unittests/SConscript')
+#if target_os in ['linux']:
+#      SConscript('../sampleapp/enrollee/linux/SConscript')
+#      SConscript('../sampleapp/enrollee/linux-samsung/SConscript')
+#      #Build UnitTestcases for Enrollee
+#      if enrollee_env.get('SECURED') == '0':
+#              SConscript('../enrollee/unittests/SConscript')
 
index 41f1902..91811a5 100755 (executable)
@@ -30,27 +30,34 @@ extern "C"
 #endif
 
 /**
+ * @brief Data structure for connect request from Mediator
+ */
+typedef struct
+{
+    ES_CONNECT_TYPE connect[NUM_CONNECT_TYPE];
+    int numRequest;
+} ESConnectRequest;
+
+/**
  * @brief Data structure delivered from mediator, which provides WiFi information
  */
 typedef struct
 {
-    char ssid[OIC_STRING_MAX_VALUE];         /**< Ssid of the Enroller**/
-    char pwd[OIC_STRING_MAX_VALUE];          /**< Pwd of the Enroller**/
-    WIFI_AUTHTYPE authtype;         /**< Auth type of the Enroller**/
-    WIFI_ENCTYPE enctype;           /**< Encryption type of the Enroller**/
-    void *userdata;                 /**< Vender-specific data**/
-} ESWiFiProvData;
+    char ssid[OIC_STRING_MAX_VALUE];        /**< Ssid of the Enroller**/
+    char pwd[OIC_STRING_MAX_VALUE];         /**< Pwd of the Enroller**/
+    WIFI_AUTHTYPE authtype;                 /**< Auth type of the Enroller**/
+    WIFI_ENCTYPE enctype;                   /**< Encryption type of the Enroller**/
+    void *userdata;                         /**< Vender-specific data**/
+} ESWiFiConfData;
 
 /**
  * @brief Data structure delivered from mediator, which provides device configuration information
  */
 typedef struct
 {
-    char location[OIC_STRING_MAX_VALUE];    /**< GPS information of device. Longitude and latitude in json format **/
-    char language[OIC_STRING_MAX_VALUE];    /**< IETF language tag using ISO 639X **/
-    char country[OIC_STRING_MAX_VALUE];     /**< ISO Country Code (ISO 3166-1 Alpha-2) **/
+    // TODO: variables can be added when some properties in oic.r.devconf resource are specified.
     void *userdata;                         /**< Vender-specific data**/
-} ESDevConfProvData;
+} ESDevConfData;
 
 /**
  * @brief Data structure delivered from mediator, which provides Cloud server information
@@ -58,10 +65,12 @@ typedef struct
 typedef struct
 {
     char authCode[OIC_STRING_MAX_VALUE];        /**< Auth code issued by OAuth2.0-compatible account server **/
+    char accessToken[OIC_STRING_MAX_VALUE];     /**< Access token resolved with an auth code **/
+    OAUTH_TOKENTYPE accessTokenType;            /**< Access token type **/
     char authProvider[OIC_STRING_MAX_VALUE];    /**< Auth provider ID **/
     char ciServer[OIC_STRING_MAX_VALUE];        /**< Cloud interface server URL which an Enrollee is going to registered **/
     void *userdata;                             /**< Vender-specific data**/
-} ESCloudProvData;
+} ESCoapCloudConfData;
 
 /**
  * @brief Data structure stored for Device property which includes a WiFi and device configuration.
@@ -83,7 +92,6 @@ typedef struct
     struct
     {
         char deviceName[OIC_STRING_MAX_VALUE];
-        char modelNumber[OIC_STRING_MAX_VALUE];
     } DevConf;
 } ESDeviceProperty;
 
@@ -93,9 +101,10 @@ typedef struct
  */
 typedef struct
 {
-    void (*WiFiProvCb) (ESWiFiProvData *);
-    void (*DevConfProvCb) (ESDevConfProvData *);
-    void (*CloudDataProvCb) (ESCloudProvData *);
+    void (*ConnectRequestCb) (ESConnectRequest *);
+    void (*WiFiConfProvCb) (ESWiFiConfData *);
+    void (*DevConfProvCb) (ESDevConfData *);
+    void (*CoapCloudConfProvCb) (ESCoapCloudConfData *);
 } ESProvisioningCallbacks;
 
 
index 5c993cc..99b926f 100755 (executable)
@@ -61,10 +61,10 @@ typedef void (*ESReadUserdataCb)(OCRepPayload* payload, char* resourceType, void
  *
  * @param isSecured         True if the Enrollee is operating in secured mode.
  * @param resourceMask      Provisining Resource Type which application wants to make.
- *                          ES_WIFI_RESOURCE = 0x01,
- *                          ES_CLOUD_RESOURCE = 0x02,
+ *                          ES_WIFICONF_RESOURCE = 0x01,
+ *                          ES_COAPCLOUDCONF_RESOURCE = 0x02,
  *                          ES_DEVCONF_RESOURCE = 0x04
- * @param callbacks         ESProvisioningCallbacks for updating Provisioning Resources' data to the application
+ * @param callbacks         ESProvisioningCallbacks for updating Easy setup Resources' data to the application
  * @return ::ES_OK on success, some other value upon failure.
  */
 ESResult ESInitEnrollee(bool isSecured, ESResourceMask resourceMask, ESProvisioningCallbacks callbacks);
@@ -73,7 +73,7 @@ ESResult ESInitEnrollee(bool isSecured, ESResourceMask resourceMask, ESProvision
 /**
  * This function Sets Device Information.
  *
- * @param deviceProperty   Contains device information composed of WiFi Structure & DevConf Structure
+ * @param deviceProperty   Contains device information composed of WiFiConf Structure & DevConf Structure
  * @return ::ES_OK on success, some other value upon failure.
  *
  * @see ESDeviceProperty
@@ -103,8 +103,7 @@ ESResult ESSetState(ESEnrolleeState esState);
 ESResult ESSetErrorCode(ESErrorCode esErrCode);
 
 /**
- * This function performs termination of Provisioning and Network resources.
- * Also terminates the IoTivity core stack.
+ * This function performs termination of all Easy setup resources.
  *
  * @return ::ES_OK on success, some other value upon failure.
  */
diff --git a/service/easy-setup/enrollee/inc/samsung/sc_easysetup.h b/service/easy-setup/enrollee/inc/samsung/sc_easysetup.h
new file mode 100755 (executable)
index 0000000..5542094
--- /dev/null
@@ -0,0 +1,153 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include "easysetup.h"
+#include "escommon.h"
+
+#ifndef EASYSETUPX_ENROLLEE_H__
+#define EASYSETUPX_ENROLLEE_H__
+
+#define MAXLEN_STRING 1000
+#define MAXNUM_LOCATION 20
+#define MAXLEN_DATE_TIME 33
+
+#define SC_RSRVD_ES_VENDOR_NETCONNECTION_STATE  "x.com.samsung.ncs"
+#define SC_RSRVD_ES_VENDOR_DISCOVERY_CHANNEL    "x.com.samsung.chn"
+#define SC_RSRVD_ES_VENDOR_DEVICE_TYPE          "x.com.samsung.dt"
+#define SC_RSRVD_ES_VENDOR_DEVICE_SUBTYPE       "x.com.samsung.sdt"
+#define SC_RSRVD_ES_VENDOR_LOCATION             "x.com.samsung.location"
+#define SC_RSRVD_ES_VENDOR_CLIENTID             "x.com.samsung.clientid"
+#define SC_RSRVD_ES_VENDOR_REGISTER_MOBILE_DEV  "x.com.samsung.rmd"
+#define SC_RSRVD_ES_VENDOR_REGISTER_SET_DEV     "x.com.samsung.rsd"
+#define SC_RSRVD_ES_VENDOR_NETWORK_PROV_INFO    "x.com.samsung.npi"
+#define SC_RSRVD_ES_VENDOR_ACCOUNT              "x.com.samsung.account"
+#define SC_RSRVD_ES_VENDOR_AAC                  "x.com.samsung.aac"
+#define SC_RSRVD_ES_VENDOR_TNC_HEADER           "x.com.samsung.tcheader"
+#define SC_RSRVD_ES_VENDOR_TNC_VERSION          "x.com.samsung.tcversion"
+#define SC_RSRVD_ES_VENDOR_TNC_RESULT           "x.com.samsung.tcresult"
+#define SC_RSRVD_ES_VENDOR_TNC_STATUS           "x.com.samsung.tcstatus"
+#define SC_RSRVD_ES_VENDOR_REFRESH_TOKEN        "x.com.samsung.refreshtoken"
+#define SC_RSRVD_ES_VENDOR_UID                  "x.com.samsung.uid"
+#define SC_RSRVD_ES_VENDOR_BSSID                "x.com.samsung.bssid"
+#define SC_RSRVD_ES_VENDOR_PNP_PIN              "x.com.samsung.pnppin"
+#define SC_RSRVD_ES_VENDOR_MODEL_NUMBER         "x.com.samsung.modelnumber"
+#define SC_RSRVD_ES_VENDOR_LANGUAGE             "x.com.samsung.language"
+#define SC_RSRVD_ES_VENDOR_COUNTRY              "x.com.samsung.country"
+#define SC_RSRVD_ES_VENDOR_GPSLOCATION          "x.com.samsung.gpslocation"
+#define SC_RSRVD_ES_VENDOR_UTC_DATE_TIME        "x.com.samsung.datetime"
+#define SC_RSRVD_ES_VENDOR_REGIONAL_DATE_TIME   "x.com.samsung.regionaldatetime"
+#define SC_RSRVD_ES_VENDOR_ES_PROTOCOL_VERSION  "x.com.samsung.espv"
+
+
+#define WIFI_DISCOVERY_CHANNEL_INIT             -1
+
+/**
+ * @brief  Supported WIFI frequency like 2.4G and 5G
+ */
+typedef enum
+{
+    NET_STATE_INIT = -1,                /**< Init state **/
+    NET_STATE_WIRED_CONNECTED = 0,      /**< Wired connected **/
+    NET_STATE_WIRELESS_CONNECTED,       /**< Wireless connected **/
+    NET_STATE_NOT_CONNECTED             /**< Not connected, at all **/
+} NETCONNECTION_STATE;
+
+typedef struct SCWiFiConfProperties
+{
+    int discoveryChannel;                   /**< Wi-Fi AP Channel used for fast discovery **/
+    char bssid[MAXLEN_STRING];              /**< Wi-Fi bssid information. **/
+} SCWiFiConfProperties;
+
+typedef struct SCTncInfo
+{
+    char header[MAXLEN_STRING]; /**< Terms & Conditions header **/
+    char version[MAXLEN_STRING];    /**< Terms & Conditions version **/
+}SCTncInfo;
+
+typedef struct SCDevConfProperties
+{
+    int numLocation;
+    char location[MAXNUM_LOCATION][MAXLEN_STRING];  /**< Samsung-specific location-related information **/
+    char regMobileDev[MAXLEN_STRING];               /**< Samsung-specific mobile device information for 'register TV' **/
+    char account[MAXLEN_STRING];  /**< Samsung-specific account-related information **/
+    SCTncInfo scTnCInfo;    /**< Samsung-specific Terms & Conditions information **/
+    char modelNumber[MAXLEN_STRING];                /**< Samsung-specific model number **/
+    char language[MAXLEN_STRING];                   /**< IETF language tag using ISO 639X **/
+    char country[MAXLEN_STRING];                    /**< ISO Country Code (ISO 3166-1 Alpha-2) **/
+    char gpsLocation[MAXLEN_STRING];                /**< GPS information of device. Longitude and latitude in json format **/
+    char utcDateTime[MAXLEN_DATE_TIME];             /**< UTC date time **/
+    char regionalDateTime[MAXLEN_DATE_TIME];        /**< Regional date time **/
+} SCDevConfProperties;
+
+typedef struct SCCoapCloudServerConfProperties
+{
+    char clientID[MAXLEN_STRING];               /**< Samsung-specific clientId for sign-up to IoT Cloud **/
+    char aac[MAXLEN_STRING];                    /**< Samsung-specific aac information **/
+    char tncResult[MAXLEN_STRING];              /**< Samsung-specific Terms & Conditions result **/
+    char refreshToken[MAXLEN_STRING];           /**< Samsung-specific refreshToken information. Indicate refresh token to be used if the access token is expired**/
+    char uid[MAXLEN_STRING];                    /**< Samsung-specific aac information. Indicate user ID corresponding to user account **/
+} SCCoapCloudServerConfProperties;
+
+typedef struct SCProperties
+{
+    NETCONNECTION_STATE netConnectionState; /**< A state of network connection **/
+    int discoveryChannel;                   /**< Wi-Fi AP Channel used for fast discovery **/
+    char deviceType[MAXLEN_STRING];         /**< Generated with Device Type + Icon Type **/
+    char deviceSubType[MAXLEN_STRING];      /**< Device Sub Category **/
+    int numLocation;
+    char location[MAXNUM_LOCATION][MAXLEN_STRING];  /**< Samsung-specific location-related information **/
+    char clientID[MAXLEN_STRING];           /**< Samsung-specific clientId for sign-up to IoT Cloud **/
+    char regMobileDev[MAXLEN_STRING];       /**< Samsung-specific mobile device information for 'register TV' **/
+    char regSetDev[MAXLEN_STRING];          /**< Samsung-specific set device information for 'register TV' **/
+    char nwProvInfo[MAXLEN_STRING];         /**< Samsung-specific network provisioning information for cellular network vendor **/
+    char account[MAXLEN_STRING];            /**< Samsung-specific account-related information **/
+    char aac[MAXLEN_STRING];                /**< Samsung-specific aac information **/
+    SCTncInfo tncInfo;                      /**< Samsung-specific Terms & Conditions information **/
+    char tncResult[MAXLEN_STRING];          /**< Samsung-specific Terms & Conditions result **/
+    int tncStatus;                          /**< Samsung-specific Terms & Conditions status **/
+    char refreshToken[MAXLEN_STRING];       /**< Samsung-specific refreshToken information. Indicate refresh token to be used if the access token is expired**/
+    char uid[MAXLEN_STRING];                /**< Samsung-specific aac information. Indicate user ID corresponding to user account **/
+    char bssid[MAXLEN_STRING];              /**< Samsung-specific Wi-Fi bssid information. **/
+    char pnpPin[MAXLEN_STRING];             /**< Samsung-specific PnP Pin **/
+    char modelNumber[MAXLEN_STRING];                /**< Samsung-specific model number **/
+    char language[MAXLEN_STRING];                   /**< IETF language tag using ISO 639X **/
+    char country[MAXLEN_STRING];                    /**< ISO Country Code (ISO 3166-1 Alpha-2) **/
+    char gpsLocation[MAXLEN_STRING];                /**< GPS information of device. Longitude and latitude in json format **/
+    char utcDateTime[MAXLEN_DATE_TIME];             /**< UTC date time **/
+    char regionalDateTime[MAXLEN_DATE_TIME];        /**< Regional date time **/
+    char esProtocolVersion[MAXLEN_STRING];          /**< Samsung Easy Setup Protocol Version **/
+} SCProperties;
+
+void ReadUserdataCb(OCRepPayload* payload, char* resourceType, void** userdata);
+void WriteUserdataCb(OCRepPayload* payload, char* resourceType);
+
+ESResult SetSCProperties(const SCProperties *prop);
+
+ESResult SetRegisterSetDevice(const char *regSetDevice);
+ESResult SetNetworkProvInfo(const char *nwProvInfo);
+
+ESResult SetSCTncInfo(SCTncInfo *tncInfo);
+ESResult SetSCTncStatus(int status);
+ESResult SetSCNetConnectionState(NETCONNECTION_STATE netConnectionState);
+ESResult SetSCPnPPin(const char *pnp);
+
+ESResult SetESVersionInfo(const char *esVersionInfo);
+
+#endif /* EASYSETUPX_ENROLLEE_H__ */
index d79b4ef..d4546a2 100755 (executable)
@@ -44,56 +44,77 @@ static bool gIsSecured = false;
 static ESProvisioningCallbacks gESProvisioningCb;
 static ESDeviceProperty gESDeviceProperty;
 
-void ESWiFiRsrcCallback(ESResult esResult, ESWiFiProvData *eventData)
+void ESConnectRequestCallback(ESResult esResult, ESConnectRequest *eventData)
 {
-    OIC_LOG_V(DEBUG, ES_ENROLLEE_TAG, "ESWiFiRsrcCallback IN");
+    OIC_LOG_V(DEBUG, ES_ENROLLEE_TAG, "ESConnectRequestCallback IN");
 
     if(esResult != ES_OK)
     {
-        OIC_LOG_V(ERROR, ES_ENROLLEE_TAG, "ESWiFiRsrcCallback Error Occured");
+        OIC_LOG_V(ERROR, ES_ENROLLEE_TAG, "ESConnectRequestCallback Error Occured");
+        return;
+    }
+
+    if(gESProvisioningCb.ConnectRequestCb != NULL)
+    {
+        gESProvisioningCb.ConnectRequestCb(eventData);
+    }
+    else
+    {
+        OIC_LOG_V(ERROR, ES_ENROLLEE_TAG, "ConnectRequestCb is NULL");
+        return;
+    }
+}
+
+void ESWiFiConfRsrcCallback(ESResult esResult, ESWiFiConfData *eventData)
+{
+    OIC_LOG(INFO, ES_ENROLLEE_TAG, "ESWiFiConfRsrcCallback IN");
+
+    if(esResult != ES_OK)
+    {
+        OIC_LOG(ERROR, ES_ENROLLEE_TAG, "ESWiFiConfRsrcCallback Error Occured");
         return;
     }
 
     // deliver data to ESProvisioningCallbacks
-    if(gESProvisioningCb.WiFiProvCb != NULL)
+    if(gESProvisioningCb.WiFiConfProvCb != NULL)
     {
-        gESProvisioningCb.WiFiProvCb(eventData);
+        gESProvisioningCb.WiFiConfProvCb(eventData);
     }
     else
     {
-        OIC_LOG_V(ERROR, ES_ENROLLEE_TAG, "WiFiProvCb is NULL");
+        OIC_LOG(ERROR, ES_ENROLLEE_TAG, "WiFiConfProvCb is NULL");
         return;
     }
 }
 
-void ESCloudRsrcCallback(ESResult esResult, ESCloudProvData *eventData)
+void ESCoapCloudConfRsrcCallback(ESResult esResult, ESCoapCloudConfData *eventData)
 {
-    OIC_LOG_V(DEBUG, ES_ENROLLEE_TAG, "ESCloudRsrcCallback IN");
+    OIC_LOG(INFO, ES_ENROLLEE_TAG, "ESCoapCloudConfRsrcCallback IN");
 
     if(esResult != ES_OK)
     {
-        OIC_LOG_V(ERROR, ES_ENROLLEE_TAG, "ESCloudRsrcCallback Error Occured");
+        OIC_LOG(ERROR, ES_ENROLLEE_TAG, "ESCoapCloudConfRsrcCallback Error Occured");
         return;
     }
 
-    if(gESProvisioningCb.CloudDataProvCb != NULL)
+    if(gESProvisioningCb.CoapCloudConfProvCb != NULL)
     {
-        gESProvisioningCb.CloudDataProvCb(eventData);
+        gESProvisioningCb.CoapCloudConfProvCb(eventData);
     }
     else
     {
-        OIC_LOG_V(ERROR, ES_ENROLLEE_TAG, "CloudDataProvCb is NULL");
+        OIC_LOG(ERROR, ES_ENROLLEE_TAG, "CoapCloudConfProvCb is NULL");
         return;
     }
 }
 
-void ESDevconfRsrcallback(ESResult esResult, ESDevConfProvData *eventData)
+void ESDevConfRsrcallback(ESResult esResult, ESDevConfData *eventData)
 {
-    OIC_LOG_V(DEBUG, ES_ENROLLEE_TAG, "ESDevconfRsrcallback IN");
+    OIC_LOG(INFO, ES_ENROLLEE_TAG, "ESDevConfRsrcallback IN");
 
     if(esResult != ES_OK)
     {
-        OIC_LOG_V(ERROR, ES_ENROLLEE_TAG, "ESDevconfRsrcallback Error Occured");
+        OIC_LOG(ERROR, ES_ENROLLEE_TAG, "ESDevConfRsrcallback Error Occured");
         return;
     }
 
@@ -103,7 +124,7 @@ void ESDevconfRsrcallback(ESResult esResult, ESDevConfProvData *eventData)
     }
     else
     {
-        OIC_LOG_V(ERROR, ES_ENROLLEE_TAG, "DevConfProvCb is NULL");
+        OIC_LOG(ERROR, ES_ENROLLEE_TAG, "DevConfProvCb is NULL");
         return;
     }
 }
@@ -114,16 +135,16 @@ ESResult ESInitEnrollee(bool isSecured, ESResourceMask resourceMask, ESProvision
 
     gIsSecured = isSecured;
 
-    if((resourceMask & ES_WIFI_RESOURCE) == ES_WIFI_RESOURCE)
+    if((resourceMask & ES_WIFICONF_RESOURCE) == ES_WIFICONF_RESOURCE)
     {
-        if(callbacks.WiFiProvCb != NULL)
+        if(callbacks.WiFiConfProvCb != NULL)
         {
-            gESProvisioningCb.WiFiProvCb = callbacks.WiFiProvCb;
-            RegisterWifiRsrcEventCallBack(ESWiFiRsrcCallback);
+            gESProvisioningCb.WiFiConfProvCb = callbacks.WiFiConfProvCb;
+            RegisterWifiRsrcEventCallBack(ESWiFiConfRsrcCallback);
         }
         else
         {
-            OIC_LOG(ERROR, ES_ENROLLEE_TAG, "WiFiProvCb NULL");
+            OIC_LOG(ERROR, ES_ENROLLEE_TAG, "WiFiConfProvCb NULL");
             return ES_ERROR;
         }
     }
@@ -132,7 +153,7 @@ ESResult ESInitEnrollee(bool isSecured, ESResourceMask resourceMask, ESProvision
         if(callbacks.DevConfProvCb != NULL)
         {
             gESProvisioningCb.DevConfProvCb = callbacks.DevConfProvCb;
-            RegisterDevConfRsrcEventCallBack(ESDevconfRsrcallback);
+            RegisterDevConfRsrcEventCallBack(ESDevConfRsrcallback);
         }
         else
         {
@@ -140,20 +161,27 @@ ESResult ESInitEnrollee(bool isSecured, ESResourceMask resourceMask, ESProvision
             return ES_ERROR;
         }
     }
-    if((resourceMask & ES_CLOUD_RESOURCE) == ES_CLOUD_RESOURCE)
+    if((resourceMask & ES_COAPCLOUDCONF_RESOURCE) == ES_COAPCLOUDCONF_RESOURCE)
     {
-        if(callbacks.CloudDataProvCb != NULL)
+        if(callbacks.CoapCloudConfProvCb != NULL)
         {
-            gESProvisioningCb.CloudDataProvCb = callbacks.CloudDataProvCb;
-            RegisterCloudRsrcEventCallBack(ESCloudRsrcCallback);
+            gESProvisioningCb.CoapCloudConfProvCb = callbacks.CoapCloudConfProvCb;
+            RegisterCloudRsrcEventCallBack(ESCoapCloudConfRsrcCallback);
         }
         else
         {
-            OIC_LOG(ERROR, ES_ENROLLEE_TAG, "CloudDataProvCb NULL");
+            OIC_LOG(ERROR, ES_ENROLLEE_TAG, "CoapCloudConfProvCb NULL");
             return ES_ERROR;
         }
     }
 
+    // TODO: if EasySetupProvCb is NULL, we should return an error at this moment.
+    if(callbacks.ConnectRequestCb != NULL)
+    {
+        gESProvisioningCb.ConnectRequestCb = callbacks.ConnectRequestCb;
+        RegisterConnectRequestEventCallBack(ESConnectRequestCallback);
+    }
+
     if(CreateEasySetupResources(gIsSecured, resourceMask) != OC_STACK_OK)
     {
         UnRegisterResourceEventCallBack();
@@ -166,7 +194,6 @@ ESResult ESInitEnrollee(bool isSecured, ESResourceMask resourceMask, ESProvision
         return ES_ERROR;
     }
 
-
     OIC_LOG(INFO, ES_ENROLLEE_TAG, "ESInitEnrollee OUT");
     return ES_OK;
 }
@@ -185,14 +212,14 @@ ESResult ESSetDeviceProperty(ESDeviceProperty *deviceProperty)
     while((deviceProperty->WiFi).mode[modeIdx] != WiFi_EOF)
     {
         (gESDeviceProperty.WiFi).mode[modeIdx] = (deviceProperty->WiFi).mode[modeIdx];
-        OIC_LOG_V(INFO, ES_ENROLLEE_TAG, "WiFi Mode : %d", (gESDeviceProperty.WiFi).mode[modeIdx]);
+        OIC_LOG_V(INFO_PRIVATE, ES_ENROLLEE_TAG, "WiFi Mode : %d", (gESDeviceProperty.WiFi).mode[modeIdx]);
         modeIdx ++;
     }
     (gESDeviceProperty.WiFi).freq = (deviceProperty->WiFi).freq;
-    OIC_LOG_V(INFO, ES_ENROLLEE_TAG, "WiFi Freq : %d", (gESDeviceProperty.WiFi).freq);
+    OIC_LOG_V(INFO_PRIVATE, ES_ENROLLEE_TAG, "WiFi Freq : %d", (gESDeviceProperty.WiFi).freq);
 
     OICStrcpy((gESDeviceProperty.DevConf).deviceName, OIC_STRING_MAX_VALUE, (deviceProperty->DevConf).deviceName);
-    OIC_LOG_V(INFO, ES_ENROLLEE_TAG, "Device Name : %s", (gESDeviceProperty.DevConf).deviceName);
+    OIC_LOG_V(INFO_PRIVATE, ES_ENROLLEE_TAG, "Device Name : %s", (gESDeviceProperty.DevConf).deviceName);
 
     OIC_LOG(INFO, ES_ENROLLEE_TAG, "ESSetDeviceProperty OUT");
     return ES_OK;
@@ -202,7 +229,7 @@ ESResult ESSetState(ESEnrolleeState esState)
 {
     OIC_LOG(INFO, ES_ENROLLEE_TAG, "ESSetState IN");
 
-    if(esState < ES_STATE_INIT || esState > ES_STATE_EOF)
+    if(esState < ES_STATE_INIT || esState >= ES_STATE_EOF)
     {
         OIC_LOG_V(ERROR, ES_ENROLLEE_TAG, "Invalid ESEnrolleeState : %d", esState);
         return ES_ERROR;
@@ -235,7 +262,7 @@ ESResult ESSetErrorCode(ESErrorCode esErrCode)
         return ES_ERROR;
     }
 
-    OIC_LOG_V(DEBUG, ES_ENROLLEE_TAG, "Set ESErrorCode succesfully : %d", esErrCode);
+    OIC_LOG_V(INFO, ES_ENROLLEE_TAG, "Set ESErrorCode succesfully : %d", esErrCode);
     OIC_LOG(INFO, ES_ENROLLEE_TAG, "ESSetErrorCode OUT");
     return ES_OK;
 }
@@ -259,6 +286,8 @@ ESResult ESTerminateEnrollee()
 
 ESResult ESSetCallbackForUserdata(ESReadUserdataCb readCb, ESWriteUserdataCb writeCb)
 {
+    OIC_LOG(INFO, ES_ENROLLEE_TAG, "ESSetCallbackForUserdata IN");
+
     if(!readCb && !writeCb)
     {
         OIC_LOG(INFO, ES_ENROLLEE_TAG, "Both of callbacks for user data are null");
@@ -267,4 +296,4 @@ ESResult ESSetCallbackForUserdata(ESReadUserdataCb readCb, ESWriteUserdataCb wri
 
     SetCallbackForUserData(readCb, writeCb);
     return ES_OK;
-}
\ No newline at end of file
+}
index 6c12afb..eb626c8 100755 (executable)
 //-----------------------------------------------------------------------------
 
 /**
- * @var gProvResource
- * @brief Structure for holding the Provisioning status and target information required to
- * connect to the target network
+ * @var g_ESEasySetupResource
+ * @brief Structure for holding the Provisioning status
  */
-static ProvResource gProvResource;
-static WiFiResource gWiFiResource;
-static CloudResource gCloudResource;
-static DevConfResource gDevConfResource;
+EasySetupResource g_ESEasySetupResource;
+WiFiConfResource g_ESWiFiConfResource;
+CoapCloudConfResource g_ESCoapCloudConfResource;
+DevConfResource g_ESDevConfResource;
 
 //-----------------------------------------------------------------------------
 // Private internal function prototypes
@@ -52,14 +51,15 @@ OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag, OCEntityHandle
 OCEntityHandlerResult ProcessGetRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload** payload);
 OCEntityHandlerResult ProcessPutRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload** payload);
 OCEntityHandlerResult ProcessPostRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload** payload);
-void updateProvResource(OCEntityHandlerRequest* ehRequest, OCRepPayload* input);
-void updateWiFiResource(OCRepPayload* input);
-void updateCloudResource(OCRepPayload* input);
+void updateEasySetupResource(OCEntityHandlerRequest* ehRequest, OCRepPayload* input);
+void updateWiFiConfResource(OCRepPayload* input);
+void updateCoapCloudConfResource(OCRepPayload* input);
 void updateDevConfResource(OCRepPayload* input);
 const char *getResult(OCStackResult result);
 
-ESWiFiCB gWifiRsrcEvtCb = NULL;
-ESCloudCB gCloudRsrcEvtCb = NULL;
+ESConnectRequestCB gConnectRequestEvtCb = NULL;
+ESWiFiConfCB gWifiConfRsrcEvtCb = NULL;
+ESCoapCloudConfCB gCoapCloudConfRsrcEvtCb = NULL;
 ESDevConfCB gDevConfRsrcEvtCb = NULL;
 
 ESReadUserdataCb gReadUserdataCb = NULL;
@@ -72,6 +72,7 @@ bool CompareResourceInterface(char *from, char *iface)
 
     if(ptr == NULL)
     {
+        OICFree(str);
         return false;
     }
 
@@ -85,12 +86,14 @@ bool CompareResourceInterface(char *from, char *iface)
 
             if(!strcmp(if_ptr, iface))
             {
+                OICFree(str);
                 return true;
             }
         }
 
     } while ((ptr = strtok(NULL, ";")));
 
+    OICFree(str);
     return false;
 }
 
@@ -98,7 +101,7 @@ ESResult SetCallbackForUserData(ESReadUserdataCb readCb, ESWriteUserdataCb write
 {
     if(!readCb && !writeCb)
     {
-        OIC_LOG(INFO, ES_RH_TAG, "Both of callbacks for user data are null");
+        OIC_LOG(DEBUG, ES_RH_TAG, "Both of callbacks for user data are null");
         return ES_ERROR;
     }
     gReadUserdataCb = readCb;
@@ -106,14 +109,14 @@ ESResult SetCallbackForUserData(ESReadUserdataCb readCb, ESWriteUserdataCb write
     return ES_OK;
 }
 
-void RegisterWifiRsrcEventCallBack(ESWiFiCB cb)
+void RegisterWifiRsrcEventCallBack(ESWiFiConfCB cb)
 {
-    gWifiRsrcEvtCb = cb;
+    gWifiConfRsrcEvtCb = cb;
 }
 
-void RegisterCloudRsrcEventCallBack(ESCloudCB cb)
+void RegisterCloudRsrcEventCallBack(ESCoapCloudConfCB cb)
 {
-    gCloudRsrcEvtCb = cb;
+    gCoapCloudConfRsrcEvtCb = cb;
 }
 
 void RegisterDevConfRsrcEventCallBack(ESDevConfCB cb)
@@ -121,128 +124,144 @@ void RegisterDevConfRsrcEventCallBack(ESDevConfCB cb)
     gDevConfRsrcEvtCb = cb;
 }
 
+void RegisterConnectRequestEventCallBack(ESConnectRequestCB cb)
+{
+    gConnectRequestEvtCb = cb;
+}
+
 void UnRegisterResourceEventCallBack()
 {
-    if (gWifiRsrcEvtCb)
+    if (gWifiConfRsrcEvtCb)
     {
-        gWifiRsrcEvtCb = NULL;
+        gWifiConfRsrcEvtCb = NULL;
     }
-    if (gCloudRsrcEvtCb)
+    if (gCoapCloudConfRsrcEvtCb)
     {
-        gCloudRsrcEvtCb = NULL;
+        gCoapCloudConfRsrcEvtCb = NULL;
     }
     if (gDevConfRsrcEvtCb)
     {
         gDevConfRsrcEvtCb = NULL;
     }
+    if (gConnectRequestEvtCb)
+    {
+        gConnectRequestEvtCb = NULL;
+    }
 }
 
-OCStackResult initProvResource(bool isSecured)
+OCStackResult initEasySetupResource(bool isSecured)
 {
-    gProvResource.status = ES_STATE_INIT;
-    gProvResource.lastErrCode = ES_ERRCODE_NO_ERROR;
+    g_ESEasySetupResource.status = ES_STATE_INIT;
+    g_ESEasySetupResource.lastErrCode = ES_ERRCODE_NO_ERROR;
+    for( int i = 0 ; i < NUM_CONNECT_TYPE ; ++i )
+    {
+        g_ESEasySetupResource.connectRequest[i] = ES_CONNECT_NONE;
+    }
+    g_ESEasySetupResource.numRequest = 0;
 
     OCStackResult res = OC_STACK_ERROR;
     if (isSecured)
     {
-        res = OCCreateResource(&gProvResource.handle, OC_RSRVD_ES_RES_TYPE_PROV,
+        res = OCCreateResource(&g_ESEasySetupResource.handle, OC_RSRVD_ES_RES_TYPE_EASYSETUP,
         OC_RSRVD_INTERFACE_DEFAULT,
-        OC_RSRVD_ES_URI_PROV, OCEntityHandlerCb,
+        OC_RSRVD_ES_URI_EASYSETUP, OCEntityHandlerCb,
         NULL, OC_DISCOVERABLE | OC_OBSERVABLE | OC_SECURE);
     }else
     {
-        res = OCCreateResource(&gProvResource.handle, OC_RSRVD_ES_RES_TYPE_PROV,
+        res = OCCreateResource(&g_ESEasySetupResource.handle, OC_RSRVD_ES_RES_TYPE_EASYSETUP,
         OC_RSRVD_INTERFACE_DEFAULT,
-        OC_RSRVD_ES_URI_PROV, OCEntityHandlerCb,
+        OC_RSRVD_ES_URI_EASYSETUP, OCEntityHandlerCb,
         NULL, OC_DISCOVERABLE | OC_OBSERVABLE);
     }
-    if(res)
+    if(res != OC_STACK_OK)
     {
-        OIC_LOG_V(INFO, ES_RH_TAG, "Created Prov resource with result: %s", getResult(res));
+        OIC_LOG_V(ERROR, ES_RH_TAG, "Created EasySetup resource with result: %s", getResult(res));
         return res;
     }
 
-    res = OCBindResourceTypeToResource(gProvResource.handle, OC_RSRVD_ES_RES_TYPE_COL);
-    if(res)
+    res = OCBindResourceTypeToResource(g_ESEasySetupResource.handle, OC_RSRVD_ES_RES_TYPE_COL);
+    if(res != OC_STACK_OK)
     {
-        OIC_LOG_V(INFO, ES_RH_TAG, "Binding Resource type with result: %s", getResult(res));
+        OIC_LOG_V(ERROR, ES_RH_TAG, "Binding Resource type with result: %s", getResult(res));
         return res;
     }
 
-    res = OCBindResourceInterfaceToResource(gProvResource.handle, OC_RSRVD_INTERFACE_LL);
-    if(res)
+    res = OCBindResourceInterfaceToResource(g_ESEasySetupResource.handle, OC_RSRVD_INTERFACE_LL);
+    if(res != OC_STACK_OK)
     {
-        OIC_LOG_V(INFO, ES_RH_TAG, "Binding Resource interface with result: %s", getResult(res));
+        OIC_LOG_V(ERROR, ES_RH_TAG, "Binding Resource interface with result: %s", getResult(res));
         return res;
     }
-    res = OCBindResourceInterfaceToResource(gProvResource.handle, OC_RSRVD_INTERFACE_BATCH);
-    if(res)
+    res = OCBindResourceInterfaceToResource(g_ESEasySetupResource.handle, OC_RSRVD_INTERFACE_BATCH);
+    if(res != OC_STACK_OK)
     {
-        OIC_LOG_V(INFO, ES_RH_TAG, "Binding Resource interface with result: %s", getResult(res));
+        OIC_LOG_V(ERROR, ES_RH_TAG, "Binding Resource interface with result: %s", getResult(res));
         return res;
     }
 
-    OIC_LOG_V(INFO, ES_RH_TAG, "Created Prov resource with result: %s", getResult(res));
+    OIC_LOG_V(DEBUG, ES_RH_TAG, "Created EasySetup resource with result: %s", getResult(res));
     return res;
 }
 
-OCStackResult initWiFiResource(bool isSecured)
+OCStackResult initWiFiConfResource(bool isSecured)
 {
     OCStackResult res = OC_STACK_ERROR;
 
-    gWiFiResource.supportedFreq = WIFI_BOTH;
-    gWiFiResource.supportedMode[0] = WIFI_11A;
-    gWiFiResource.supportedMode[1] = WIFI_11B;
-    gWiFiResource.supportedMode[2] = WIFI_11G;
-    gWiFiResource.supportedMode[3] = WIFI_11N;
-    gWiFiResource.numMode = 4;
-    gWiFiResource.authType = NONE_AUTH;
-    gWiFiResource.encType = NONE_ENC;
-    OICStrcpy(gWiFiResource.ssid, sizeof(gWiFiResource.ssid), "");
-    OICStrcpy(gWiFiResource.cred, sizeof(gWiFiResource.cred), "");
+    g_ESWiFiConfResource.supportedFreq = WIFI_BOTH;
+    g_ESWiFiConfResource.supportedMode[0] = WIFI_11A;
+    g_ESWiFiConfResource.supportedMode[1] = WIFI_11B;
+    g_ESWiFiConfResource.supportedMode[2] = WIFI_11G;
+    g_ESWiFiConfResource.supportedMode[3] = WIFI_11N;
+    g_ESWiFiConfResource.numMode = 4;
+    g_ESWiFiConfResource.authType = NONE_AUTH;
+    g_ESWiFiConfResource.encType = NONE_ENC;
+    OICStrcpy(g_ESWiFiConfResource.ssid, sizeof(g_ESWiFiConfResource.ssid), "");
+    OICStrcpy(g_ESWiFiConfResource.cred, sizeof(g_ESWiFiConfResource.cred), "");
 
     if (isSecured)
     {
-        res = OCCreateResource(&gWiFiResource.handle, OC_RSRVD_ES_RES_TYPE_WIFI,
+        res = OCCreateResource(&g_ESWiFiConfResource.handle, OC_RSRVD_ES_RES_TYPE_WIFICONF,
         OC_RSRVD_INTERFACE_DEFAULT,
-        OC_RSRVD_ES_URI_WIFI, OCEntityHandlerCb,
+        OC_RSRVD_ES_URI_WIFICONF, OCEntityHandlerCb,
         NULL, OC_DISCOVERABLE | OC_OBSERVABLE | OC_SECURE);
     }else
     {
-        res = OCCreateResource(&gWiFiResource.handle, OC_RSRVD_ES_RES_TYPE_WIFI,
+        res = OCCreateResource(&g_ESWiFiConfResource.handle, OC_RSRVD_ES_RES_TYPE_WIFICONF,
         OC_RSRVD_INTERFACE_DEFAULT,
-        OC_RSRVD_ES_URI_WIFI, OCEntityHandlerCb,
+        OC_RSRVD_ES_URI_WIFICONF, OCEntityHandlerCb,
         NULL, OC_DISCOVERABLE | OC_OBSERVABLE);
     }
 
-    OIC_LOG_V(INFO, ES_RH_TAG, "Created WiFi resource with result: %s", getResult(res));
+    OIC_LOG_V(DEBUG, ES_RH_TAG, "Created WiFiConf resource with result: %s", getResult(res));
     return res;
 
 }
 
-OCStackResult initCloudServerResource(bool isSecured)
+OCStackResult initCoapCloudConfResource(bool isSecured)
 {
     OCStackResult res = OC_STACK_ERROR;
 
-    OICStrcpy(gCloudResource.authCode, sizeof(gCloudResource.authCode), "");
-    OICStrcpy(gCloudResource.authProvider, sizeof(gCloudResource.authProvider), "");
-    OICStrcpy(gCloudResource.ciServer, sizeof(gCloudResource.ciServer), "");
+    OICStrcpy(g_ESCoapCloudConfResource.authCode, sizeof(g_ESCoapCloudConfResource.authCode), "");
+    OICStrcpy(g_ESCoapCloudConfResource.accessToken, sizeof(g_ESCoapCloudConfResource.accessToken), "");
+    g_ESCoapCloudConfResource.accessTokenType = NONE_OAUTH_TOKENTYPE;
+    OICStrcpy(g_ESCoapCloudConfResource.authProvider, sizeof(g_ESCoapCloudConfResource.authProvider), "");
+    OICStrcpy(g_ESCoapCloudConfResource.ciServer, sizeof(g_ESCoapCloudConfResource.ciServer), "");
 
     if (isSecured)
     {
-        res = OCCreateResource(&gCloudResource.handle, OC_RSRVD_ES_RES_TYPE_CLOUDSERVER,
+        res = OCCreateResource(&g_ESCoapCloudConfResource.handle, OC_RSRVD_ES_RES_TYPE_COAPCLOUDCONF,
         OC_RSRVD_INTERFACE_DEFAULT,
-        OC_RSRVD_ES_URI_CLOUDSERVER, OCEntityHandlerCb,
+        OC_RSRVD_ES_URI_COAPCLOUDCONF, OCEntityHandlerCb,
         NULL, OC_DISCOVERABLE | OC_OBSERVABLE | OC_SECURE);
     }else
     {
-        res = OCCreateResource(&gCloudResource.handle, OC_RSRVD_ES_RES_TYPE_CLOUDSERVER,
+        res = OCCreateResource(&g_ESCoapCloudConfResource.handle, OC_RSRVD_ES_RES_TYPE_COAPCLOUDCONF,
         OC_RSRVD_INTERFACE_DEFAULT,
-        OC_RSRVD_ES_URI_CLOUDSERVER, OCEntityHandlerCb,
+        OC_RSRVD_ES_URI_COAPCLOUDCONF, OCEntityHandlerCb,
         NULL, OC_DISCOVERABLE | OC_OBSERVABLE);
     }
 
-    OIC_LOG_V(INFO, ES_RH_TAG, "Created CloudServer resource with result: %s", getResult(res));
+    OIC_LOG_V(DEBUG, ES_RH_TAG, "Created CoapCloudConf resource with result: %s", getResult(res));
     return res;
 
 }
@@ -251,50 +270,92 @@ OCStackResult initDevConfResource(bool isSecured)
 {
     OCStackResult res = OC_STACK_ERROR;
 
-    OICStrcpy(gDevConfResource.devName, sizeof(gDevConfResource.devName), "");
-    OICStrcpy(gDevConfResource.modelNumber, sizeof(gDevConfResource.modelNumber), "");
-    OICStrcpy(gDevConfResource.location, sizeof(gDevConfResource.location), "");
-    OICStrcpy(gDevConfResource.country, sizeof(gDevConfResource.country), "");
-    OICStrcpy(gDevConfResource.language, sizeof(gDevConfResource.language), "");
+    OICStrcpy(g_ESDevConfResource.devName, sizeof(g_ESDevConfResource.devName), "");
 
     if (isSecured)
     {
-        res = OCCreateResource(&gDevConfResource.handle, OC_RSRVD_ES_RES_TYPE_DEVCONF,
+        res = OCCreateResource(&g_ESDevConfResource.handle, OC_RSRVD_ES_RES_TYPE_DEVCONF,
         OC_RSRVD_INTERFACE_DEFAULT,
         OC_RSRVD_ES_URI_DEVCONF, OCEntityHandlerCb,
         NULL, OC_DISCOVERABLE | OC_OBSERVABLE | OC_SECURE);
     }else
     {
-        res = OCCreateResource(&gDevConfResource.handle, OC_RSRVD_ES_RES_TYPE_DEVCONF,
+        res = OCCreateResource(&g_ESDevConfResource.handle, OC_RSRVD_ES_RES_TYPE_DEVCONF,
         OC_RSRVD_INTERFACE_DEFAULT,
         OC_RSRVD_ES_URI_DEVCONF, OCEntityHandlerCb,
         NULL, OC_DISCOVERABLE | OC_OBSERVABLE);
     }
 
-    OIC_LOG_V(INFO, ES_RH_TAG, "Created DevConf resource with result: %s", getResult(res));
+    OIC_LOG_V(DEBUG, ES_RH_TAG, "Created DevConf resource with result: %s", getResult(res));
     return res;
 
 }
 
-void updateProvResource(OCEntityHandlerRequest* ehRequest, OCRepPayload* input)
+void updateEasySetupResource(OCEntityHandlerRequest* ehRequest, OCRepPayload* input)
 {
-    OIC_LOG_V(INFO, ES_RH_TAG, "gProvResource.status %d", gProvResource.status);
+    OIC_LOG_V(DEBUG, ES_RH_TAG, "g_ESEasySetupResource.status %d", g_ESEasySetupResource.status);
+
+    int64_t *connect_req = NULL;
+    size_t dimensions[MAX_REP_ARRAY_DEPTH] = { 0 };
+    if (OCRepPayloadGetIntArray(input, OC_RSRVD_ES_CONNECT, &connect_req, dimensions))
+    {
+        ESConnectRequest* connectRequest = (ESConnectRequest*)OICMalloc(sizeof(ESConnectRequest));
+        if( !connectRequest )
+        {
+            OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
+            return;
+        }
+
+        int cntRequest = 0;
+        for (size_t i = 0 ; i < NUM_CONNECT_TYPE ; ++i)
+        {
+            g_ESEasySetupResource.connectRequest[i] = ES_CONNECT_NONE;
+            connectRequest->connect[i] = ES_CONNECT_NONE;
+
+            if(i < dimensions[0] &&
+                (connect_req[i] == ES_CONNECT_WIFI || connect_req[i] == ES_CONNECT_COAPCLOUD))
+            {
+                g_ESEasySetupResource.connectRequest[cntRequest] = connect_req[i];
+                connectRequest->connect[cntRequest] = connect_req[i];
+                OIC_LOG_V(DEBUG, ES_RH_TAG, "g_ESEasySetupResource.connectType[%d] : %d",
+                                                    cntRequest, g_ESEasySetupResource.connectRequest[cntRequest]);
+                cntRequest++;
+            }
+        }
+        connectRequest->numRequest = cntRequest;
+        g_ESEasySetupResource.numRequest = cntRequest;
+
+        if(g_ESEasySetupResource.connectRequest[0] != ES_CONNECT_NONE)
+        {
+            OIC_LOG(DEBUG, ES_RH_TAG, "Send ConnectRequest Callback To ES");
+
+            // TODO : Need to check appropriateness of gWiFiData
+            if(gConnectRequestEvtCb != NULL)
+            {
+                gConnectRequestEvtCb(ES_OK, connectRequest);
+            }
+            else
+            {
+                OIC_LOG(ERROR, ES_RH_TAG, "gConnectRequestEvtCb is NULL");
+            }
+        }
+    }
 
     if(ehRequest->query)
     {
         if(CompareResourceInterface(ehRequest->query, OC_RSRVD_INTERFACE_BATCH))
         {
             // When Provisioning resource has a POST with BatchInterface
-            updateCloudResource(input);
-            updateWiFiResource(input);
+            updateCoapCloudConfResource(input);
+            updateWiFiConfResource(input);
             updateDevConfResource(input);
         }
     }
 }
 
-void updateWiFiResource(OCRepPayload* input)
+void updateWiFiConfResource(OCRepPayload* input)
 {
-    ESWiFiProvData* wiFiData = (ESWiFiProvData*)OICMalloc(sizeof(ESWiFiProvData));
+    ESWiFiConfData* wiFiData = (ESWiFiConfData*)OICMalloc(sizeof(ESWiFiConfData));
 
     if(wiFiData == NULL)
     {
@@ -311,66 +372,66 @@ void updateWiFiResource(OCRepPayload* input)
     char* ssid = NULL;
     if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_SSID, &ssid))
     {
-        OICStrcpy(gWiFiResource.ssid, sizeof(gWiFiResource.ssid), ssid);
+        OICStrcpy(g_ESWiFiConfResource.ssid, sizeof(g_ESWiFiConfResource.ssid), ssid);
         OICStrcpy(wiFiData->ssid, sizeof(wiFiData->ssid), ssid);
-        OIC_LOG_V(INFO, ES_RH_TAG, "gWiFiResource.ssid : %s", gWiFiResource.ssid);
+        OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "g_ESWiFiConfResource.ssid : %s", g_ESWiFiConfResource.ssid);
     }
 
     char* cred = NULL;
     if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_CRED, &cred))
     {
-        OICStrcpy(gWiFiResource.cred, sizeof(gWiFiResource.cred), cred);
+        OICStrcpy(g_ESWiFiConfResource.cred, sizeof(g_ESWiFiConfResource.cred), cred);
         OICStrcpy(wiFiData->pwd, sizeof(wiFiData->pwd), cred);
-        OIC_LOG_V(INFO, ES_RH_TAG, "gWiFiResource.cred %s", gWiFiResource.cred);
+        OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "g_ESWiFiConfResource.cred %s", g_ESWiFiConfResource.cred);
     }
 
     int64_t authType = -1;
     if (OCRepPayloadGetPropInt(input, OC_RSRVD_ES_AUTHTYPE, &authType))
     {
-        gWiFiResource.authType = authType;
-        wiFiData->authtype = gWiFiResource.authType;
-        OIC_LOG_V(INFO, ES_RH_TAG, "gWiFiResource.authType %u", gWiFiResource.authType);
+        g_ESWiFiConfResource.authType = authType;
+        wiFiData->authtype = g_ESWiFiConfResource.authType;
+        OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "g_ESWiFiConfResource.authType %u", g_ESWiFiConfResource.authType);
     }
 
     int64_t encType = -1;
     if (OCRepPayloadGetPropInt(input, OC_RSRVD_ES_ENCTYPE, &encType))
     {
-        gWiFiResource.encType = encType;
-        wiFiData->enctype = gWiFiResource.encType;
-        OIC_LOG_V(INFO, ES_RH_TAG, "gWiFiResource.encType %u", gWiFiResource.encType);
+        g_ESWiFiConfResource.encType = encType;
+        wiFiData->enctype = g_ESWiFiConfResource.encType;
+        OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "g_ESWiFiConfResource.encType %u", g_ESWiFiConfResource.encType);
     }
 
     if(gReadUserdataCb)
     {
-        gReadUserdataCb(input, OC_RSRVD_ES_RES_TYPE_WIFI, &wiFiData->userdata);
+        gReadUserdataCb(input, OC_RSRVD_ES_RES_TYPE_WIFICONF, &wiFiData->userdata);
     }
 
     if(ssid || cred || authType!= -1 || encType != -1)
     {
-        OIC_LOG(INFO, ES_RH_TAG, "Send WiFiRsrc Callback To ES");
+        OIC_LOG(DEBUG, ES_RH_TAG, "Send WiFiConfRsrc Callback To ES");
 
         // TODO : Need to check appropriateness of gWiFiData
-        if(gWifiRsrcEvtCb != NULL)
+        if(gWifiConfRsrcEvtCb != NULL)
         {
-            gWifiRsrcEvtCb(ES_OK, wiFiData);
+            gWifiConfRsrcEvtCb(ES_OK, wiFiData);
         }
         else
         {
-            OIC_LOG(ERROR, ES_RH_TAG, "gWifiRsrcEvtCb is NULL");
+            OIC_LOG(ERROR, ES_RH_TAG, "gWifiConfRsrcEvtCb is NULL");
         }
     }
 
-    if(OC_STACK_NO_OBSERVERS == OCNotifyAllObservers(gWiFiResource.handle, OC_HIGH_QOS))
+    if(OC_STACK_NO_OBSERVERS == OCNotifyAllObservers(g_ESWiFiConfResource.handle, OC_HIGH_QOS))
     {
-        OIC_LOG(INFO, ES_RH_TAG, "Enrollee doesn't have any observers.");
+        OIC_LOG(DEBUG, ES_RH_TAG, "Enrollee doesn't have any observer.");
     }
 
     OICFree(wiFiData);
 }
 
-void updateCloudResource(OCRepPayload* input)
+void updateCoapCloudConfResource(OCRepPayload* input)
 {
-    ESCloudProvData* cloudData = (ESCloudProvData*)OICMalloc(sizeof(ESCloudProvData));
+    ESCoapCloudConfData* cloudData = (ESCoapCloudConfData*)OICMalloc(sizeof(ESCoapCloudConfData));
 
     if(cloudData == NULL)
     {
@@ -379,6 +440,8 @@ void updateCloudResource(OCRepPayload* input)
     }
 
     memset(cloudData->authCode, 0, OIC_STRING_MAX_VALUE);
+    memset(cloudData->accessToken, 0, OIC_STRING_MAX_VALUE);
+    g_ESCoapCloudConfResource.accessTokenType = NONE_OAUTH_TOKENTYPE;
     memset(cloudData->authProvider, 0, OIC_STRING_MAX_VALUE);
     memset(cloudData->ciServer, 0, OIC_STRING_MAX_VALUE);
     cloudData->userdata = NULL;
@@ -386,50 +449,66 @@ void updateCloudResource(OCRepPayload* input)
     char *authCode = NULL;
     if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_AUTHCODE, &authCode))
     {
-        OICStrcpy(gCloudResource.authCode, sizeof(gCloudResource.authCode), authCode);
+        OICStrcpy(g_ESCoapCloudConfResource.authCode, sizeof(g_ESCoapCloudConfResource.authCode), authCode);
         OICStrcpy(cloudData->authCode, sizeof(cloudData->authCode), authCode);
-        OIC_LOG_V(INFO, ES_RH_TAG, "gCloudResource.authCode %s", gCloudResource.authCode);
+        OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "g_ESCoapCloudConfResource.authCode %s", g_ESCoapCloudConfResource.authCode);
+    }
+
+    char *accessToken = NULL;
+    if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_ACCESSTOKEN, &accessToken))
+    {
+        OICStrcpy(g_ESCoapCloudConfResource.accessToken, sizeof(g_ESCoapCloudConfResource.accessToken), accessToken);
+        OICStrcpy(cloudData->accessToken, sizeof(cloudData->accessToken), accessToken);
+        OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "g_ESCoapCloudConfResource.accessToken %s", g_ESCoapCloudConfResource.accessToken);
+    }
+
+    int64_t accessTokenType = -1;
+    if (OCRepPayloadGetPropInt(input, OC_RSRVD_ES_ACCESSTOKEN_TYPE, &accessTokenType))
+    {
+        g_ESCoapCloudConfResource.accessTokenType = accessTokenType;
+        cloudData->accessTokenType = g_ESCoapCloudConfResource.accessTokenType;
+        OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "g_ESCoapCloudConfResource.accessTokenType %d", g_ESCoapCloudConfResource.accessTokenType);
     }
 
     char *authProvider = NULL;
     if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_AUTHPROVIDER, &authProvider))
     {
-        OICStrcpy(gCloudResource.authProvider, sizeof(gCloudResource.authProvider), authProvider);
+        OICStrcpy(g_ESCoapCloudConfResource.authProvider, sizeof(g_ESCoapCloudConfResource.authProvider), authProvider);
         OICStrcpy(cloudData->authProvider, sizeof(cloudData->authProvider), authProvider);
-        OIC_LOG_V(INFO, ES_RH_TAG, "gCloudResource.authServerUrl %s", gCloudResource.authProvider);
+        OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "g_ESCoapCloudConfResource.authServerUrl %s", g_ESCoapCloudConfResource.authProvider);
     }
 
     char *ciServer = NULL;
     if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_CISERVER, &ciServer))
     {
-        OICStrcpy(gCloudResource.ciServer, sizeof(gCloudResource.ciServer), ciServer);
+        OICStrcpy(g_ESCoapCloudConfResource.ciServer, sizeof(g_ESCoapCloudConfResource.ciServer), ciServer);
         OICStrcpy(cloudData->ciServer, sizeof(cloudData->ciServer), ciServer);
-        OIC_LOG_V(INFO, ES_RH_TAG, "gCloudResource.ciServer %s", gCloudResource.ciServer);
+        OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "g_ESCoapCloudConfResource.ciServer %s", g_ESCoapCloudConfResource.ciServer);
     }
 
     if(gReadUserdataCb)
     {
-        gReadUserdataCb(input, OC_RSRVD_ES_RES_TYPE_CLOUDSERVER, &cloudData->userdata);
+        gReadUserdataCb(input, OC_RSRVD_ES_RES_TYPE_COAPCLOUDCONF, &cloudData->userdata);
     }
 
-    if(authCode || authProvider || ciServer)
+    if(authCode || accessToken || authProvider || ciServer)
     {
-        OIC_LOG(INFO, ES_RH_TAG, "Send CloudRsrc Callback To ES");
+        OIC_LOG(DEBUG, ES_RH_TAG, "Send CoapCloudConfRsrc Callback To ES");
 
         // TODO : Need to check appropriateness of gCloudData
-        if(gCloudRsrcEvtCb != NULL)
+        if(gCoapCloudConfRsrcEvtCb != NULL)
         {
-            gCloudRsrcEvtCb(ES_OK, cloudData);
+            gCoapCloudConfRsrcEvtCb(ES_OK, cloudData);
         }
         else
         {
-            OIC_LOG(ERROR, ES_RH_TAG, "gCloudRsrcEvtCb is NULL");
+            OIC_LOG(DEBUG, ES_RH_TAG, "gCoapCloudConfRsrcEvtCb is NULL");
         }
     }
 
-    if(OC_STACK_NO_OBSERVERS == OCNotifyAllObservers(gCloudResource.handle, OC_HIGH_QOS))
+    if(OC_STACK_NO_OBSERVERS == OCNotifyAllObservers(g_ESCoapCloudConfResource.handle, OC_HIGH_QOS))
     {
-        OIC_LOG(INFO, ES_RH_TAG, "cloudResource doesn't have any observers.");
+        OIC_LOG(DEBUG, ES_RH_TAG, "CoapCloudConf resource doesn't have any observer.");
     }
 
     OICFree(cloudData);
@@ -437,49 +516,23 @@ void updateCloudResource(OCRepPayload* input)
 
 void updateDevConfResource(OCRepPayload* input)
 {
-    ESDevConfProvData* devConfData = (ESDevConfProvData*)OICMalloc(sizeof(ESDevConfProvData));
+    ESDevConfData* devConfData = (ESDevConfData*)OICMalloc(sizeof(ESDevConfData));
 
     if(devConfData == NULL)
     {
         OIC_LOG(DEBUG, ES_RH_TAG, "OICMalloc is failed");
         return;
     }
-    memset(devConfData->language, 0, OIC_STRING_MAX_VALUE);
-    memset(devConfData->country, 0, OIC_STRING_MAX_VALUE);
     devConfData->userdata = NULL;
 
-    char *location = NULL;
-    if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_LOCATION, &location))
-    {
-        OICStrcpy(gDevConfResource.location, sizeof(gDevConfResource.location), location);
-        OICStrcpy(devConfData->location, sizeof(devConfData->location), location);
-        OIC_LOG_V(INFO, ES_RH_TAG, "gDevConfResource.location %s", gDevConfResource.location);
-    }
-
-    char *country = NULL;
-    if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_COUNTRY, &country))
-    {
-        OICStrcpy(gDevConfResource.country, sizeof(gDevConfResource.country), country);
-        OICStrcpy(devConfData->country, sizeof(devConfData->country), country);
-        OIC_LOG_V(INFO, ES_RH_TAG, "gDevConfResource.country %s", gDevConfResource.country);
-    }
-
-    char *language = NULL;
-    if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_LANGUAGE, &language))
-    {
-        OICStrcpy(gDevConfResource.language, sizeof(gDevConfResource.language), language);
-        OICStrcpy(devConfData->language, sizeof(devConfData->language), language);
-        OIC_LOG_V(INFO, ES_RH_TAG, "gDevConfResource.language %s", gDevConfResource.language);
-    }
-
-    if(gReadUserdataCb)
+    if (gReadUserdataCb)
     {
         gReadUserdataCb(input, OC_RSRVD_ES_RES_TYPE_DEVCONF, &devConfData->userdata);
     }
 
-    if(country || language)
+    if( devConfData->userdata != NULL )
     {
-        OIC_LOG(INFO, ES_RH_TAG, "Send DevConfRsrc Callback To ES");
+        OIC_LOG(DEBUG, ES_RH_TAG, "Send DevConfRsrc Callback To ES");
 
         // TODO : Need to check appropriateness of gDevConfData
         if(gDevConfRsrcEvtCb != NULL)
@@ -488,19 +541,19 @@ void updateDevConfResource(OCRepPayload* input)
         }
         else
         {
-            OIC_LOG(ERROR, ES_RH_TAG, "gDevConfRsrcEvtCb is NULL");
+            OIC_LOG(DEBUG, ES_RH_TAG, "gDevConfRsrcEvtCb is NULL");
         }
     }
 
-    if(OC_STACK_NO_OBSERVERS == OCNotifyAllObservers(gDevConfResource.handle, OC_HIGH_QOS))
+    if(OC_STACK_NO_OBSERVERS == OCNotifyAllObservers(g_ESDevConfResource.handle, OC_HIGH_QOS))
     {
-        OIC_LOG(INFO, ES_RH_TAG, "devConfResource doesn't have any observers.");
+        OIC_LOG(DEBUG, ES_RH_TAG, "devConfResource doesn't have any observer.");
     }
 
     OICFree(devConfData);
 }
 
-OCRepPayload* constructResponseOfWiFi(char *interface)
+OCRepPayload* constructResponseOfWiFiConf(char *interface)
 {
     OCRepPayload* payload = OCRepPayloadCreate();
     if (!payload)
@@ -509,14 +562,14 @@ OCRepPayload* constructResponseOfWiFi(char *interface)
         return NULL;
     }
 
-    if(gWiFiResource.handle == NULL)
+    if(g_ESWiFiConfResource.handle == NULL)
     {
-        OIC_LOG(ERROR, ES_RH_TAG, "WiFi resource is not created");
+        OIC_LOG(ERROR, ES_RH_TAG, "WiFiConf resource is not created");
         return NULL;
     }
 
-    OIC_LOG(INFO, ES_RH_TAG, "constructResponse wifi res");
-    OCRepPayloadSetUri(payload, OC_RSRVD_ES_URI_WIFI);
+    OIC_LOG(DEBUG, ES_RH_TAG, "constructResponse WiFiConf res");
+    OCRepPayloadSetUri(payload, OC_RSRVD_ES_URI_WIFICONF);
 
     OCRepPayload* repPayload = NULL;
     OCRepPayload* tempPayload = NULL;
@@ -534,41 +587,57 @@ OCRepPayload* constructResponseOfWiFi(char *interface)
 
         size_t interfacesDimensions[MAX_REP_ARRAY_DEPTH] = {1, 0, 0};
         char **interfaces = (char **)OICMalloc(3 * sizeof(char*));
+        if( !interfaces )
+        {
+            OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
+            return NULL;
+        }
 
         interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
 
-        OCRepPayloadSetStringArray(payload, OC_RSRVD_ES_INTERFACE, (char **)interfaces, interfacesDimensions);
+        OCRepPayloadSetStringArray(payload, OC_RSRVD_ES_INTERFACE, (const char **)interfaces, interfacesDimensions);
 
         size_t resourceTypesDimensions[MAX_REP_ARRAY_DEPTH] = {1, 0, 0};
         char **resourceTypes = (char **)OICMalloc(2 * sizeof(char*));
+        if( !resourceTypes )
+        {
+            OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
+            return NULL;
+        }
 
-        resourceTypes[0] = OICStrdup(OC_RSRVD_ES_RES_TYPE_WIFI);
+        resourceTypes[0] = OICStrdup(OC_RSRVD_ES_RES_TYPE_WIFICONF);
 
-        OCRepPayloadSetStringArray(payload, OC_RSRVD_ES_RES_TYPE, (char **)resourceTypes, resourceTypesDimensions);
+        OCRepPayloadSetStringArray(payload, OC_RSRVD_ES_RES_TYPE, (const char **)resourceTypes, resourceTypesDimensions);
     }
     else
     {
         OCRepPayloadAddInterface(payload, OC_RSRVD_INTERFACE_DEFAULT);
-        OCRepPayloadAddResourceType(payload, OC_RSRVD_ES_RES_TYPE_WIFI);\r
+        OCRepPayloadAddResourceType(payload, OC_RSRVD_ES_RES_TYPE_WIFICONF);
+    }
+
+    size_t dimensions[MAX_REP_ARRAY_DEPTH] = {g_ESWiFiConfResource.numMode, 0, 0};
+    int64_t *modes_64 = (int64_t *)OICMalloc(g_ESWiFiConfResource.numMode * sizeof(int64_t));
+    if( !modes_64 )
+    {
+        OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
+        return NULL;
     }
 
-    size_t dimensions[MAX_REP_ARRAY_DEPTH] = {gWiFiResource.numMode, 0, 0};
-    int64_t *modes_64 = (int64_t *)OICMalloc(gWiFiResource.numMode * sizeof(int64_t));
-    for(int i = 0 ; i < gWiFiResource.numMode ; ++i)
+    for(int i = 0 ; i < g_ESWiFiConfResource.numMode ; ++i)
     {
-        modes_64[i] = gWiFiResource.supportedMode[i];
+        modes_64[i] = g_ESWiFiConfResource.supportedMode[i];
     }
     OCRepPayloadSetIntArray(payload, OC_RSRVD_ES_SUPPORTEDWIFIMODE, (int64_t *)modes_64, dimensions);
 
-    OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_SUPPORTEDWIFIFREQ, gWiFiResource.supportedFreq);
-    OCRepPayloadSetPropString(payload, OC_RSRVD_ES_SSID, gWiFiResource.ssid);
-    OCRepPayloadSetPropString(payload, OC_RSRVD_ES_CRED, gWiFiResource.cred);
-    OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_AUTHTYPE, (int) gWiFiResource.authType);
-    OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_ENCTYPE, (int) gWiFiResource.encType);
+    OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_SUPPORTEDWIFIFREQ, g_ESWiFiConfResource.supportedFreq);
+    OCRepPayloadSetPropString(payload, OC_RSRVD_ES_SSID, g_ESWiFiConfResource.ssid);
+    OCRepPayloadSetPropString(payload, OC_RSRVD_ES_CRED, g_ESWiFiConfResource.cred);
+    OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_AUTHTYPE, (int) g_ESWiFiConfResource.authType);
+    OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_ENCTYPE, (int) g_ESWiFiConfResource.encType);
 
     if(gWriteUserdataCb)
     {
-        gWriteUserdataCb(payload, OC_RSRVD_ES_RES_TYPE_WIFI);
+        gWriteUserdataCb(payload, OC_RSRVD_ES_RES_TYPE_WIFICONF);
     }
 
     if(!strcmp(interface, OC_RSRVD_INTERFACE_BATCH))
@@ -580,7 +649,7 @@ OCRepPayload* constructResponseOfWiFi(char *interface)
     return payload;
 }
 
-OCRepPayload* constructResponseOfCloud(char *interface)
+OCRepPayload* constructResponseOfCoapCloudConf(char *interface)
 {
     OCRepPayload* payload = OCRepPayloadCreate();
     if (!payload)
@@ -589,14 +658,14 @@ OCRepPayload* constructResponseOfCloud(char *interface)
         return NULL;
     }
 
-    if(gCloudResource.handle == NULL)
+    if(g_ESCoapCloudConfResource.handle == NULL)
     {
-        OIC_LOG(ERROR, ES_RH_TAG, "CloudServer resource is not created");
+        OIC_LOG(ERROR, ES_RH_TAG, "CoapCloudConf resource is not created");
         return NULL;
     }
 
-    OIC_LOG(INFO, ES_RH_TAG, "constructResponse cloudserver res");
-    OCRepPayloadSetUri(payload, OC_RSRVD_ES_URI_CLOUDSERVER);
+    OIC_LOG(DEBUG, ES_RH_TAG, "constructResponse CoapCloudConf res");
+    OCRepPayloadSetUri(payload, OC_RSRVD_ES_URI_COAPCLOUDCONF);
 
     OCRepPayload* repPayload = NULL;
     OCRepPayload* tempPayload = NULL;
@@ -614,31 +683,43 @@ OCRepPayload* constructResponseOfCloud(char *interface)
 
         size_t interfacesDimensions[MAX_REP_ARRAY_DEPTH] = {1, 0, 0};
         char **interfaces = (char **)OICMalloc(3 * sizeof(char*));
+        if(!interfaces)
+        {
+            OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
+            return NULL;
+        }
 
         interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
 
-        OCRepPayloadSetStringArray(payload, OC_RSRVD_ES_INTERFACE, (char **)interfaces, interfacesDimensions);
+        OCRepPayloadSetStringArray(payload, OC_RSRVD_ES_INTERFACE, (const char **)interfaces, interfacesDimensions);
 
         size_t resourceTypesDimensions[MAX_REP_ARRAY_DEPTH] = {1, 0, 0};
         char **resourceTypes = (char **)OICMalloc(2 * sizeof(char*));
+        if(!resourceTypes)
+        {
+            OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
+            return NULL;
+        }
 
-        resourceTypes[0] = OICStrdup(OC_RSRVD_ES_RES_TYPE_CLOUDSERVER);
+        resourceTypes[0] = OICStrdup(OC_RSRVD_ES_RES_TYPE_COAPCLOUDCONF);
 
-        OCRepPayloadSetStringArray(payload, OC_RSRVD_ES_RES_TYPE, (char **)resourceTypes, resourceTypesDimensions);
+        OCRepPayloadSetStringArray(payload, OC_RSRVD_ES_RES_TYPE, (const char **)resourceTypes, resourceTypesDimensions);
     }
     else
     {
         OCRepPayloadAddInterface(payload, OC_RSRVD_INTERFACE_DEFAULT);
-        OCRepPayloadAddResourceType(payload, OC_RSRVD_ES_RES_TYPE_CLOUDSERVER);
+        OCRepPayloadAddResourceType(payload, OC_RSRVD_ES_RES_TYPE_COAPCLOUDCONF);
     }
 
-    OCRepPayloadSetPropString(payload, OC_RSRVD_ES_AUTHCODE, gCloudResource.authCode);
-    OCRepPayloadSetPropString(payload, OC_RSRVD_ES_AUTHPROVIDER, gCloudResource.authProvider);
-    OCRepPayloadSetPropString(payload, OC_RSRVD_ES_CISERVER, gCloudResource.ciServer);
+    OCRepPayloadSetPropString(payload, OC_RSRVD_ES_AUTHCODE, g_ESCoapCloudConfResource.authCode);
+    OCRepPayloadSetPropString(payload, OC_RSRVD_ES_ACCESSTOKEN, g_ESCoapCloudConfResource.accessToken);
+    OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_ACCESSTOKEN_TYPE, (int)g_ESCoapCloudConfResource.accessTokenType);
+    OCRepPayloadSetPropString(payload, OC_RSRVD_ES_AUTHPROVIDER, g_ESCoapCloudConfResource.authProvider);
+    OCRepPayloadSetPropString(payload, OC_RSRVD_ES_CISERVER, g_ESCoapCloudConfResource.ciServer);
 
     if(gWriteUserdataCb)
     {
-        gWriteUserdataCb(payload, OC_RSRVD_ES_RES_TYPE_CLOUDSERVER);
+        gWriteUserdataCb(payload, OC_RSRVD_ES_RES_TYPE_COAPCLOUDCONF);
     }
 
     if(!strcmp(interface, OC_RSRVD_INTERFACE_BATCH))
@@ -659,13 +740,13 @@ OCRepPayload* constructResponseOfDevConf(char *interface)
         return NULL;
     }
 
-    if(gDevConfResource.handle == NULL)
+    if(g_ESDevConfResource.handle == NULL)
     {
         OIC_LOG(ERROR, ES_RH_TAG, "DevConf resource is not created");
         return NULL;
     }
 
-    OIC_LOG(INFO, ES_RH_TAG, "constructResponse devconf res");
+    OIC_LOG(DEBUG, ES_RH_TAG, "constructResponse DevConf res");
     OCRepPayloadSetUri(payload, OC_RSRVD_ES_URI_DEVCONF);
 
     OCRepPayload* repPayload = NULL;
@@ -684,17 +765,27 @@ OCRepPayload* constructResponseOfDevConf(char *interface)
 
         size_t interfacesDimensions[MAX_REP_ARRAY_DEPTH] = {1, 0, 0};
         char **interfaces = (char **)OICMalloc(3 * sizeof(char*));
+        if( !interfaces )
+        {
+            OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
+            return NULL;
+        }
 
         interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
 
-        OCRepPayloadSetStringArray(payload, OC_RSRVD_ES_INTERFACE, (char **)interfaces, interfacesDimensions);
+        OCRepPayloadSetStringArray(payload, OC_RSRVD_ES_INTERFACE, (const char **)interfaces, interfacesDimensions);
 
         size_t resourceTypesDimensions[MAX_REP_ARRAY_DEPTH] = {1, 0, 0};
         char **resourceTypes = (char **)OICMalloc(2 * sizeof(char*));
+        if( !resourceTypes )
+        {
+            OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
+            return NULL;
+        }
 
         resourceTypes[0] = OICStrdup(OC_RSRVD_ES_RES_TYPE_DEVCONF);
 
-        OCRepPayloadSetStringArray(payload, OC_RSRVD_ES_RES_TYPE, (char **)resourceTypes, resourceTypesDimensions);
+        OCRepPayloadSetStringArray(payload, OC_RSRVD_ES_RES_TYPE, (const char **)resourceTypes, resourceTypesDimensions);
     }
     else
     {
@@ -702,11 +793,7 @@ OCRepPayload* constructResponseOfDevConf(char *interface)
         OCRepPayloadAddResourceType(payload, OC_RSRVD_ES_RES_TYPE_DEVCONF);
     }
 
-    OCRepPayloadSetPropString(payload, OC_RSRVD_ES_DEVNAME, gDevConfResource.devName);
-    OCRepPayloadSetPropString(payload, OC_RSRVD_ES_MODELNUMBER, gDevConfResource.modelNumber);
-    OCRepPayloadSetPropString(payload, OC_RSRVD_ES_LOCATION, gDevConfResource.location);
-    OCRepPayloadSetPropString(payload, OC_RSRVD_ES_LANGUAGE, gDevConfResource.language);
-    OCRepPayloadSetPropString(payload, OC_RSRVD_ES_COUNTRY, gDevConfResource.country);
+    OCRepPayloadSetPropString(payload, OC_RSRVD_ES_DEVNAME, g_ESDevConfResource.devName);
 
     if(gWriteUserdataCb)
     {
@@ -722,7 +809,7 @@ OCRepPayload* constructResponseOfDevConf(char *interface)
     return payload;
 }
 
-OCRepPayload* constructResponseOfProv(OCEntityHandlerRequest *ehRequest)
+OCRepPayload* constructResponseOfEasySetup(OCEntityHandlerRequest *ehRequest)
 {
     OCRepPayload* payload = OCRepPayloadCreate();
     if (!payload)
@@ -742,7 +829,7 @@ OCRepPayload* constructResponseOfProv(OCEntityHandlerRequest *ehRequest)
 
         int childResCnt = 0;
 
-        if(gWiFiResource.handle != NULL)
+        if(g_ESWiFiConfResource.handle != NULL)
         {
             OCRepPayload *add = OCRepPayloadCreate();
             if(!add)
@@ -763,17 +850,17 @@ OCRepPayload* constructResponseOfProv(OCEntityHandlerRequest *ehRequest)
                 return NULL;
             }
 
-            resourceType[0] = OICStrdup(OC_RSRVD_ES_RES_TYPE_WIFI);
+            resourceType[0] = OICStrdup(OC_RSRVD_ES_RES_TYPE_WIFICONF);
             resourceInterface[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
 
             add->base.type = PAYLOAD_TYPE_REPRESENTATION;
-            OCRepPayloadSetPropString(add, OC_RSRVD_HREF, OC_RSRVD_ES_URI_WIFI);
+            OCRepPayloadSetPropString(add, OC_RSRVD_HREF, OC_RSRVD_ES_URI_WIFICONF);
             OCRepPayloadSetStringArray(add, OC_RSRVD_RESOURCE_TYPE,
                                             (const char **)resourceType, dimensions);
             OCRepPayloadSetStringArray(add, OC_RSRVD_INTERFACE,
                                             (const char **)resourceInterface, dimensions);
 
-            OCResourceProperty p = OCGetResourceProperties((OCResourceHandle *)gWiFiResource.handle);
+            OCResourceProperty p = OCGetResourceProperties((OCResourceHandle *)g_ESWiFiConfResource.handle);
             OCRepPayload *policy = OCRepPayloadCreate();
             if (!policy)
             {
@@ -796,7 +883,7 @@ OCRepPayload* constructResponseOfProv(OCEntityHandlerRequest *ehRequest)
             arrayPayload[childResCnt++] = add;
         }
 
-        if(gDevConfResource.handle != NULL)
+        if(g_ESDevConfResource.handle != NULL)
         {
             OCRepPayload *add = OCRepPayloadCreate();
             if(!add)
@@ -827,7 +914,7 @@ OCRepPayload* constructResponseOfProv(OCEntityHandlerRequest *ehRequest)
             OCRepPayloadSetStringArray(add, OC_RSRVD_INTERFACE,
                                             (const char **)resourceInterface, dimensions);
 
-            OCResourceProperty p = OCGetResourceProperties((OCResourceHandle *)gDevConfResource.handle);
+            OCResourceProperty p = OCGetResourceProperties((OCResourceHandle *)g_ESDevConfResource.handle);
             OCRepPayload *policy = OCRepPayloadCreate();
             if (!policy)
             {
@@ -850,7 +937,7 @@ OCRepPayload* constructResponseOfProv(OCEntityHandlerRequest *ehRequest)
             arrayPayload[childResCnt++] = add;
         }
 
-        if(gCloudResource.handle != NULL)
+        if(g_ESCoapCloudConfResource.handle != NULL)
         {
             OCRepPayload *add = OCRepPayloadCreate();
             if(!add)
@@ -871,17 +958,17 @@ OCRepPayload* constructResponseOfProv(OCEntityHandlerRequest *ehRequest)
                 return NULL;
             }
 
-            resourceType[0] = OICStrdup(OC_RSRVD_ES_RES_TYPE_CLOUDSERVER);
+            resourceType[0] = OICStrdup(OC_RSRVD_ES_RES_TYPE_COAPCLOUDCONF);
             resourceInterface[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
 
             add->base.type = PAYLOAD_TYPE_REPRESENTATION;
-            OCRepPayloadSetPropString(add, OC_RSRVD_HREF, OC_RSRVD_ES_URI_CLOUDSERVER);
+            OCRepPayloadSetPropString(add, OC_RSRVD_HREF, OC_RSRVD_ES_URI_COAPCLOUDCONF);
             OCRepPayloadSetStringArray(add, OC_RSRVD_RESOURCE_TYPE,
                                             (const char **)resourceType, dimensions);
             OCRepPayloadSetStringArray(add, OC_RSRVD_INTERFACE,
                                             (const char **)resourceInterface, dimensions);
 
-            OCResourceProperty p = OCGetResourceProperties((OCResourceHandle *)gCloudResource.handle);
+            OCResourceProperty p = OCGetResourceProperties((OCResourceHandle *)g_ESCoapCloudConfResource.handle);
             OCRepPayload *policy = OCRepPayloadCreate();
             if (!policy)
             {
@@ -910,16 +997,44 @@ OCRepPayload* constructResponseOfProv(OCEntityHandlerRequest *ehRequest)
             (ehRequest->query && !strcmp(ehRequest->query, "")) ||
             (ehRequest->query && CompareResourceInterface(ehRequest->query, OC_RSRVD_INTERFACE_DEFAULT)))
         {
-            OIC_LOG(INFO, ES_RH_TAG, "constructResponse prov res");
-            OCRepPayloadSetUri(payload, OC_RSRVD_ES_URI_PROV);
+            OIC_LOG(DEBUG, ES_RH_TAG, "constructResponse EasySetup res");
+            OCRepPayloadSetUri(payload, OC_RSRVD_ES_URI_EASYSETUP);
             OCRepPayloadAddInterface(payload, OC_RSRVD_INTERFACE_DEFAULT);
             OCRepPayloadAddInterface(payload, OC_RSRVD_INTERFACE_LL);
             OCRepPayloadAddInterface(payload, OC_RSRVD_INTERFACE_BATCH);
-            OCRepPayloadAddResourceType(payload, OC_RSRVD_ES_RES_TYPE_PROV);
+            OCRepPayloadAddResourceType(payload, OC_RSRVD_ES_RES_TYPE_EASYSETUP);
             OCRepPayloadAddResourceType(payload, OC_RSRVD_ES_RES_TYPE_COL);
 
-            OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_PROVSTATUS, gProvResource.status);
-            OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_LAST_ERRORCODE, gProvResource.lastErrCode);
+            OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_PROVSTATUS, g_ESEasySetupResource.status);
+            OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_LAST_ERRORCODE, g_ESEasySetupResource.lastErrCode);
+
+            if(g_ESEasySetupResource.numRequest > 0)
+            {
+                size_t dimensions[MAX_REP_ARRAY_DEPTH] = {g_ESEasySetupResource.numRequest, 0, 0};
+                int64_t *connectRequest = (int64_t *)OICMalloc(g_ESEasySetupResource.numRequest  * sizeof(int64_t));
+                if(!connectRequest)
+                {
+                    OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
+                    return NULL;
+                }
+
+                for(int i = 0 ; i < g_ESEasySetupResource.numRequest  ; ++i)
+                {
+                    connectRequest[i] = g_ESEasySetupResource.connectRequest[i];
+                }
+                OCRepPayloadSetIntArray(payload, OC_RSRVD_ES_CONNECT, (int64_t *)connectRequest, dimensions);
+            }
+            else
+            {
+                OIC_LOG(DEBUG, ES_RH_TAG, "g_ESEasySetupResource.numRequest is 0");
+                size_t dimensions[MAX_REP_ARRAY_DEPTH] = {0, 0, 0};
+                OCRepPayloadSetIntArray(payload, OC_RSRVD_ES_CONNECT, NULL, dimensions);
+            }
+
+            if(gWriteUserdataCb)
+            {
+                gWriteUserdataCb(payload, OC_RSRVD_ES_RES_TYPE_EASYSETUP);
+            }
 
             OCRepPayloadSetPropObjectArray(payload, OC_RSRVD_ES_LINKS, arrayPayload, dimensions);
         }
@@ -931,8 +1046,8 @@ OCRepPayload* constructResponseOfProv(OCEntityHandlerRequest *ehRequest)
         ehRequest->query && CompareResourceInterface(ehRequest->query, OC_RSRVD_INTERFACE_BATCH))
 
     {
-        OIC_LOG(INFO, ES_RH_TAG, "constructResponse prov res");
-        OCRepPayloadSetUri(payload, OC_RSRVD_ES_URI_PROV);
+        OIC_LOG(DEBUG, ES_RH_TAG, "constructResponse EasySetup res");
+        OCRepPayloadSetUri(payload, OC_RSRVD_ES_URI_EASYSETUP);
 
         OCRepPayload* repPayload = NULL;
 
@@ -945,30 +1060,62 @@ OCRepPayload* constructResponseOfProv(OCEntityHandlerRequest *ehRequest)
 
         size_t interfacesDimensions[MAX_REP_ARRAY_DEPTH] = {3, 0, 0};
         char **interfaces = (char **)OICMalloc(3 * sizeof(char*));
+        if(!interfaces)
+        {
+            OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
+            return NULL;
+        }
 
         interfaces[0] = OICStrdup(OC_RSRVD_INTERFACE_DEFAULT);
         interfaces[1] = OICStrdup(OC_RSRVD_INTERFACE_LL);
         interfaces[2] = OICStrdup(OC_RSRVD_INTERFACE_BATCH);
 
-        OCRepPayloadSetStringArray(repPayload, OC_RSRVD_ES_INTERFACE, (char **)interfaces, interfacesDimensions);
+        OCRepPayloadSetStringArray(repPayload, OC_RSRVD_ES_INTERFACE, (const char **)interfaces, interfacesDimensions);
 
         size_t resourceTypesDimensions[MAX_REP_ARRAY_DEPTH] = {2, 0, 0};
         char **resourceTypes = (char **)OICMalloc(2 * sizeof(char*));
+        if(!resourceTypes)
+        {
+            OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
+            return NULL;
+        }
 
-        resourceTypes[0] = OICStrdup(OC_RSRVD_ES_RES_TYPE_PROV);
+        resourceTypes[0] = OICStrdup(OC_RSRVD_ES_RES_TYPE_EASYSETUP);
         resourceTypes[1] = OICStrdup(OC_RSRVD_ES_RES_TYPE_COL);
 
-        OCRepPayloadSetStringArray(repPayload, OC_RSRVD_ES_RES_TYPE, (char **)resourceTypes, resourceTypesDimensions);
+        OCRepPayloadSetStringArray(repPayload, OC_RSRVD_ES_RES_TYPE, (const char **)resourceTypes, resourceTypesDimensions);
 
-        OCRepPayloadSetPropInt(repPayload, OC_RSRVD_ES_PROVSTATUS, gProvResource.status);
-        OCRepPayloadSetPropInt(repPayload, OC_RSRVD_ES_LAST_ERRORCODE, gProvResource.lastErrCode);
+        OCRepPayloadSetPropInt(repPayload, OC_RSRVD_ES_PROVSTATUS, g_ESEasySetupResource.status);
+        OCRepPayloadSetPropInt(repPayload, OC_RSRVD_ES_LAST_ERRORCODE, g_ESEasySetupResource.lastErrCode);
+        if(g_ESEasySetupResource.numRequest > 0)
+        {
+            size_t dimensions[MAX_REP_ARRAY_DEPTH] = {g_ESEasySetupResource.numRequest, 0, 0};
+            int64_t *connectRequest = (int64_t *)OICMalloc(g_ESEasySetupResource.numRequest  * sizeof(int64_t));
+            if(!connectRequest)
+            {
+                OIC_LOG(ERROR, ES_RH_TAG, "Failed to allocate Payload");
+                return NULL;
+            }
 
-        OCRepPayloadSetPropObject(payload, OC_RSRVD_REPRESENTATION, repPayload);
-    }
+            for(int i = 0 ; i < g_ESEasySetupResource.numRequest ; ++i)
+            {
+                connectRequest[i] = g_ESEasySetupResource.connectRequest[i];
+            }
+            OCRepPayloadSetIntArray(repPayload, OC_RSRVD_ES_CONNECT, (int64_t *)connectRequest, dimensions);
+        }
+        else
+        {
+            OIC_LOG(DEBUG, ES_RH_TAG, "g_ESEasySetupResource.numRequest is 0");
+            size_t dimensions[MAX_REP_ARRAY_DEPTH] = {0, 0, 0};
+            OCRepPayloadSetIntArray(repPayload, OC_RSRVD_ES_CONNECT, NULL, dimensions);
+        }
 
-    if(gWriteUserdataCb)
-    {
-        gWriteUserdataCb(payload, OC_RSRVD_ES_RES_TYPE_PROV);
+        if(gWriteUserdataCb)
+        {
+            gWriteUserdataCb(repPayload, OC_RSRVD_ES_RES_TYPE_EASYSETUP);
+        }
+
+        OCRepPayloadSetPropObject(payload, OC_RSRVD_REPRESENTATION, repPayload);
     }
 
     if(ehRequest->query)
@@ -978,14 +1125,14 @@ OCRepPayload* constructResponseOfProv(OCEntityHandlerRequest *ehRequest)
             OCRepPayload* head = payload;
             OCRepPayload* nextPayload = NULL;
 
-            nextPayload = constructResponseOfWiFi(OC_RSRVD_INTERFACE_BATCH);
+            nextPayload = constructResponseOfWiFiConf(OC_RSRVD_INTERFACE_BATCH);
             if(nextPayload != NULL)
             {
                 payload->next = nextPayload;
                 payload = payload->next;
             }
 
-            nextPayload = constructResponseOfCloud(OC_RSRVD_INTERFACE_BATCH);
+            nextPayload = constructResponseOfCoapCloudConf(OC_RSRVD_INTERFACE_BATCH);
             if(nextPayload != NULL)
             {
                 payload->next = nextPayload;
@@ -1011,48 +1158,48 @@ OCStackResult CreateEasySetupResources(bool isSecured, ESResourceMask resourceMa
     OCStackResult res = OC_STACK_ERROR;
     bool maskFlag = false;
 
-    res = initProvResource(isSecured);
+    res = initEasySetupResource(isSecured);
     if(res != OC_STACK_OK)
     {
         // TODO: destroy logic will be added
-        OIC_LOG_V(ERROR, ES_RH_TAG, "initProvResource result: %s", getResult(res));
+        OIC_LOG_V(ERROR, ES_RH_TAG, "initEasySetupResource result: %s", getResult(res));
 
         return res;
     }
 
-    if((resourceMask & ES_WIFI_RESOURCE) == ES_WIFI_RESOURCE)
+    if((resourceMask & ES_WIFICONF_RESOURCE) == ES_WIFICONF_RESOURCE)
     {
         maskFlag = true;
-        res = initWiFiResource(isSecured);
+        res = initWiFiConfResource(isSecured);
         if(res != OC_STACK_OK)
         {
-            OIC_LOG_V(ERROR, ES_RH_TAG, "initWiFiResource result: %s", getResult(res));
+            OIC_LOG_V(ERROR, ES_RH_TAG, "initWiFiConfResource result: %s", getResult(res));
             return res;
         }
 
-        res = OCBindResource(gProvResource.handle, gWiFiResource.handle);
+        res = OCBindResource(g_ESEasySetupResource.handle, g_ESWiFiConfResource.handle);
         if(res != OC_STACK_OK)
         {
-            OIC_LOG_V(ERROR, ES_RH_TAG, "Bind WiFiResource result: %s", getResult(res));
+            OIC_LOG_V(ERROR, ES_RH_TAG, "Bind WiFiConfResource result: %s", getResult(res));
             return res;
         }
 
     }
 
-    if((resourceMask & ES_CLOUD_RESOURCE) == ES_CLOUD_RESOURCE)
+    if((resourceMask & ES_COAPCLOUDCONF_RESOURCE) == ES_COAPCLOUDCONF_RESOURCE)
     {
         maskFlag = true;
-        res = initCloudServerResource(isSecured);
+        res = initCoapCloudConfResource(isSecured);
         if(res != OC_STACK_OK)
         {
-            OIC_LOG_V(ERROR, ES_RH_TAG, "initCloudResource result: %s", getResult(res));
+            OIC_LOG_V(ERROR, ES_RH_TAG, "initCoapCloudConfResource result: %s", getResult(res));
             return res;
         }
 
-        res = OCBindResource(gProvResource.handle, gCloudResource.handle);
+        res = OCBindResource(g_ESEasySetupResource.handle, g_ESCoapCloudConfResource.handle);
         if(res != OC_STACK_OK)
         {
-            OIC_LOG_V(ERROR, ES_RH_TAG, "Bind CloudResource result: %s", getResult(res));
+            OIC_LOG_V(ERROR, ES_RH_TAG, "Bind CoapCloudConfResource result: %s", getResult(res));
             return res;
         }
     }
@@ -1067,7 +1214,7 @@ OCStackResult CreateEasySetupResources(bool isSecured, ESResourceMask resourceMa
             return res;
         }
 
-        res = OCBindResource(gProvResource.handle, gDevConfResource.handle);
+        res = OCBindResource(g_ESEasySetupResource.handle, g_ESDevConfResource.handle);
         if(res != OC_STACK_OK)
         {
             OIC_LOG_V(ERROR, ES_RH_TAG, "Bind DevConfResource result: %s", getResult(res));
@@ -1075,7 +1222,6 @@ OCStackResult CreateEasySetupResources(bool isSecured, ESResourceMask resourceMa
         }
     }
 
-
     if(maskFlag == false)
     {
         OIC_LOG_V(ERROR, ES_RH_TAG, "Invalid ResourceMask");
@@ -1083,18 +1229,7 @@ OCStackResult CreateEasySetupResources(bool isSecured, ESResourceMask resourceMa
 
     }
 
-    OIC_LOG_V(INFO, ES_RH_TAG, "Created all resources with result: %s", getResult(res));
-
-    return res;
-}
-
-OCStackResult DeleteProvisioningResource()
-{
-    OCStackResult res = OCDeleteResource(gProvResource.handle);
-    if (res != OC_STACK_OK)
-    {
-        OIC_LOG_V(INFO, ES_RH_TAG, "Deleting Prov resource error with result: %s", getResult(res));
-    }
+    OIC_LOG_V(DEBUG, ES_RH_TAG, "Created all resources with result: %s", getResult(res));
 
     return res;
 }
@@ -1102,61 +1237,61 @@ OCStackResult DeleteProvisioningResource()
 OCStackResult DeleteEasySetupResources()
 {
     OCStackResult res = OC_STACK_ERROR;
-    if (gWiFiResource.handle != NULL)
+    if (g_ESWiFiConfResource.handle != NULL)
     {
-        res = OCUnBindResource(gProvResource.handle, gWiFiResource.handle);
+        res = OCUnBindResource(g_ESEasySetupResource.handle, g_ESWiFiConfResource.handle);
         if(res != OC_STACK_OK)
         {
             OIC_LOG_V(ERROR, ES_RH_TAG, "Unbind WiFi resource error with result: %s", getResult(res));
         }
     }
-    if (gCloudResource.handle != NULL)
+    if (g_ESCoapCloudConfResource.handle != NULL)
     {
-        res = OCUnBindResource(gProvResource.handle, gCloudResource.handle);
+        res = OCUnBindResource(g_ESEasySetupResource.handle, g_ESCoapCloudConfResource.handle);
         if(res != OC_STACK_OK)
         {
             OIC_LOG_V(ERROR, ES_RH_TAG, "Unbind CloudServer resource error with result: %s", getResult(res));
         }
     }
-    if (gDevConfResource.handle != NULL)
+    if (g_ESDevConfResource.handle != NULL)
     {
-        res = OCUnBindResource(gProvResource.handle, gDevConfResource.handle);
+        res = OCUnBindResource(g_ESEasySetupResource.handle, g_ESDevConfResource.handle);
         if(res != OC_STACK_OK)
         {
             OIC_LOG_V(ERROR, ES_RH_TAG, "Unbind DevConf resource error with result: %s", getResult(res));
         }
     }
 
-    if (gWiFiResource.handle != NULL)
+    if (g_ESWiFiConfResource.handle != NULL)
     {
-        res = OCDeleteResource(gWiFiResource.handle);
+        res = OCDeleteResource(g_ESWiFiConfResource.handle);
         if (res != OC_STACK_OK)
         {
             OIC_LOG_V(ERROR, ES_RH_TAG, "Deleting WiFi resource error with result: %s", getResult(res));
         }
     }
 
-    if(gCloudResource.handle != NULL)
+    if(g_ESCoapCloudConfResource.handle != NULL)
     {
-        res = OCDeleteResource(gCloudResource.handle);
+        res = OCDeleteResource(g_ESCoapCloudConfResource.handle);
         if (res != OC_STACK_OK)
         {
             OIC_LOG_V(ERROR, ES_RH_TAG, "Deleting CloudServer resource error with result: %s", getResult(res));
         }
     }
 
-    if(gDevConfResource.handle != NULL)
+    if(g_ESDevConfResource.handle != NULL)
     {
-        res = OCDeleteResource(gDevConfResource.handle);
+        res = OCDeleteResource(g_ESDevConfResource.handle);
         if (res != OC_STACK_OK)
         {
             OIC_LOG_V(ERROR, ES_RH_TAG, "Deleting DevConf resource error with result: %s", getResult(res));
         }
     }
 
-    if(gProvResource.handle != NULL)
+    if(g_ESEasySetupResource.handle != NULL)
     {
-        res = OCDeleteResource(gProvResource.handle);
+        res = OCDeleteResource(g_ESEasySetupResource.handle);
         if (res != OC_STACK_OK)
         {
             OIC_LOG_V(ERROR, ES_RH_TAG, "Deleting Prov resource error with result: %s", getResult(res));
@@ -1183,7 +1318,7 @@ OCEntityHandlerResult ProcessGetRequest(OCEntityHandlerRequest *ehRequest, OCRep
     OCRepPayload *getResp = NULL;
     *payload = NULL;
 
-    if(ehRequest->resource == gProvResource.handle)
+    if(ehRequest->resource == g_ESEasySetupResource.handle)
     {
         if(ehRequest->query &&
             strcmp(ehRequest->query, "") &&
@@ -1196,10 +1331,10 @@ OCEntityHandlerResult ProcessGetRequest(OCEntityHandlerRequest *ehRequest, OCRep
         }
         else
         {
-            getResp = constructResponseOfProv(ehRequest);
+            getResp = constructResponseOfEasySetup(ehRequest);
         }
     }
-    else if(ehRequest->resource == gWiFiResource.handle)
+    else if(ehRequest->resource == g_ESWiFiConfResource.handle)
     {
         if(CheckEhRequestPayload(ehRequest) != OC_EH_OK)
         {
@@ -1208,10 +1343,10 @@ OCEntityHandlerResult ProcessGetRequest(OCEntityHandlerRequest *ehRequest, OCRep
         }
         else
         {
-            getResp = constructResponseOfWiFi(OC_RSRVD_INTERFACE_DEFAULT);
+            getResp = constructResponseOfWiFiConf(OC_RSRVD_INTERFACE_DEFAULT);
         }
     }
-    else if(ehRequest->resource == gCloudResource.handle)
+    else if(ehRequest->resource == g_ESCoapCloudConfResource.handle)
     {
         if(CheckEhRequestPayload(ehRequest) != OC_EH_OK)
         {
@@ -1220,10 +1355,10 @@ OCEntityHandlerResult ProcessGetRequest(OCEntityHandlerRequest *ehRequest, OCRep
         }
         else
         {
-            getResp = constructResponseOfCloud(OC_RSRVD_INTERFACE_DEFAULT);
+            getResp = constructResponseOfCoapCloudConf(OC_RSRVD_INTERFACE_DEFAULT);
         }
     }
-    else if(ehRequest->resource == gDevConfResource.handle)
+    else if(ehRequest->resource == g_ESDevConfResource.handle)
     {
         if(CheckEhRequestPayload(ehRequest) != OC_EH_OK)
         {
@@ -1250,7 +1385,7 @@ OCEntityHandlerResult ProcessGetRequest(OCEntityHandlerRequest *ehRequest, OCRep
 
 OCEntityHandlerResult ProcessPostRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload** payload)
 {
-    OIC_LOG(INFO, ES_RH_TAG, "ProcessPostRequest enter");
+    OIC_LOG(DEBUG, ES_RH_TAG, "ProcessPostRequest enter");
     OCEntityHandlerResult ehResult = OC_EH_ERROR;
     if (ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
     {
@@ -1265,7 +1400,7 @@ OCEntityHandlerResult ProcessPostRequest(OCEntityHandlerRequest *ehRequest, OCRe
         return ehResult;
     }
 
-    if(ehRequest->resource == gProvResource.handle)
+    if(ehRequest->resource == g_ESEasySetupResource.handle)
     {
         if(ehRequest->query &&
             strcmp(ehRequest->query, "") &&
@@ -1277,10 +1412,10 @@ OCEntityHandlerResult ProcessPostRequest(OCEntityHandlerRequest *ehRequest, OCRe
         }
         else
         {
-            updateProvResource(ehRequest, input);
+            updateEasySetupResource(ehRequest, input);
         }
     }
-    else if(ehRequest->resource == gWiFiResource.handle)
+    else if(ehRequest->resource == g_ESWiFiConfResource.handle)
     {
         if(CheckEhRequestPayload(ehRequest) != OC_EH_OK)
         {
@@ -1289,10 +1424,10 @@ OCEntityHandlerResult ProcessPostRequest(OCEntityHandlerRequest *ehRequest, OCRe
         }
         else
         {
-            updateWiFiResource(input);
+            updateWiFiConfResource(input);
         }
     }
-    else if(ehRequest->resource == gCloudResource.handle)
+    else if(ehRequest->resource == g_ESCoapCloudConfResource.handle)
     {
         if(CheckEhRequestPayload(ehRequest) != OC_EH_OK)
         {
@@ -1301,10 +1436,10 @@ OCEntityHandlerResult ProcessPostRequest(OCEntityHandlerRequest *ehRequest, OCRe
         }
         else
         {
-            updateCloudResource(input);
+            updateCoapCloudConfResource(input);
         }
     }
-    else if(ehRequest->resource == gDevConfResource.handle)
+    else if(ehRequest->resource == g_ESDevConfResource.handle)
     {
         if(CheckEhRequestPayload(ehRequest) != OC_EH_OK)
         {
@@ -1318,19 +1453,19 @@ OCEntityHandlerResult ProcessPostRequest(OCEntityHandlerRequest *ehRequest, OCRe
     }
 
     OCRepPayload *getResp = NULL;
-    if(ehRequest->resource == gProvResource.handle)
+    if(ehRequest->resource == g_ESEasySetupResource.handle)
     {
-        getResp = constructResponseOfProv(ehRequest);
+        getResp = constructResponseOfEasySetup(ehRequest);
     }
-    else if(ehRequest->resource == gWiFiResource.handle)
+    else if(ehRequest->resource == g_ESWiFiConfResource.handle)
     {
-        getResp = constructResponseOfWiFi(OC_RSRVD_INTERFACE_DEFAULT);
+        getResp = constructResponseOfWiFiConf(OC_RSRVD_INTERFACE_DEFAULT);
     }
-    else if(ehRequest->resource == gCloudResource.handle)
+    else if(ehRequest->resource == g_ESCoapCloudConfResource.handle)
     {
-        getResp = constructResponseOfCloud(OC_RSRVD_INTERFACE_DEFAULT);
+        getResp = constructResponseOfCoapCloudConf(OC_RSRVD_INTERFACE_DEFAULT);
     }
-    else if(ehRequest->resource == gDevConfResource.handle)
+    else if(ehRequest->resource == g_ESDevConfResource.handle)
     {
         getResp = constructResponseOfDevConf(OC_RSRVD_INTERFACE_DEFAULT);
     }
@@ -1375,15 +1510,15 @@ OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag,
     {
         if (OC_REST_GET == entityHandlerRequest->method)
         {
-            OIC_LOG(INFO, ES_RH_TAG, "Received GET request");
+            OIC_LOG(DEBUG, ES_RH_TAG, "Received GET request");
             ehRet = ProcessGetRequest(entityHandlerRequest, &payload);
         }
         else if (OC_REST_PUT == entityHandlerRequest->method)
         {
-            OIC_LOG(INFO, ES_RH_TAG, "Received PUT request");
+            OIC_LOG(DEBUG, ES_RH_TAG, "Received PUT request");
 
             //PUT request will be handled in the internal implementation
-            if (gProvResource.handle != NULL)
+            if (g_ESEasySetupResource.handle != NULL)
             {
                 ehRet = ProcessPutRequest(entityHandlerRequest, &payload);
             }
@@ -1395,8 +1530,8 @@ OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag,
         }
         else if (OC_REST_POST == entityHandlerRequest->method)
         {
-            OIC_LOG(INFO, ES_RH_TAG, "Received OC_REST_POST from client");
-            if (gProvResource.handle != NULL)
+            OIC_LOG(DEBUG, ES_RH_TAG, "Received OC_REST_POST from client");
+            if (g_ESEasySetupResource.handle != NULL)
             {
                 ehRet = ProcessPostRequest(entityHandlerRequest, &payload);
             }
@@ -1429,15 +1564,15 @@ OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag,
     }
     if (entityHandlerRequest && (flag & OC_OBSERVE_FLAG))
     {
-        OIC_LOG(INFO, ES_RH_TAG, "Flag includes OC_OBSERVE_FLAG");
+        OIC_LOG(DEBUG, ES_RH_TAG, "Flag includes OC_OBSERVE_FLAG");
 
         if (OC_OBSERVE_REGISTER == entityHandlerRequest->obsInfo.action)
         {
-            OIC_LOG (INFO, ES_RH_TAG, "Received OC_OBSERVE_REGISTER from Mediator");
+            OIC_LOG(DEBUG, ES_RH_TAG, "Received OC_OBSERVE_REGISTER from Mediator");
         }
         else if (OC_OBSERVE_DEREGISTER == entityHandlerRequest->obsInfo.action)
         {
-            OIC_LOG (INFO, ES_RH_TAG, "Received OC_OBSERVE_DEREGISTER from Mediator");
+            OIC_LOG(DEBUG, ES_RH_TAG, "Received OC_OBSERVE_DEREGISTER from Mediator");
         }
     }
     return ehRet;
@@ -1445,70 +1580,66 @@ OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag,
 
 OCStackResult SetDeviceProperty(ESDeviceProperty *deviceProperty)
 {
-    OIC_LOG(INFO, ES_RH_TAG, "SetDeviceProperty IN");
+    OIC_LOG(DEBUG, ES_RH_TAG, "SetDeviceProperty IN");
 
-    gWiFiResource.supportedFreq = (deviceProperty->WiFi).freq;
-    OIC_LOG_V(INFO, ES_RH_TAG, "WiFi Freq : %d", gWiFiResource.supportedFreq);
+    g_ESWiFiConfResource.supportedFreq = (deviceProperty->WiFi).freq;
+    OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "WiFi Freq : %d", g_ESWiFiConfResource.supportedFreq);
 
     int modeIdx = 0;
     while((deviceProperty->WiFi).mode[modeIdx] != WiFi_EOF)
     {
-        gWiFiResource.supportedMode[modeIdx] = (deviceProperty->WiFi).mode[modeIdx];
-        OIC_LOG_V(INFO, ES_RH_TAG, "WiFi Mode : %d", gWiFiResource.supportedMode[modeIdx]);
+        g_ESWiFiConfResource.supportedMode[modeIdx] = (deviceProperty->WiFi).mode[modeIdx];
+        OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "WiFi Mode : %d", g_ESWiFiConfResource.supportedMode[modeIdx]);
         modeIdx ++;
     }
-    gWiFiResource.numMode = modeIdx;
-
-    OICStrcpy(gDevConfResource.devName, OIC_STRING_MAX_VALUE, (deviceProperty->DevConf).deviceName);
-    OIC_LOG_V(INFO, ES_RH_TAG, "Device Name : %s", gDevConfResource.devName);
+    g_ESWiFiConfResource.numMode = modeIdx;
 
-    OICStrcpy(gDevConfResource.modelNumber, OIC_STRING_MAX_VALUE,
-                                                            (deviceProperty->DevConf).modelNumber);
-    OIC_LOG_V(INFO, ES_RH_TAG, "Model Number : %s", gDevConfResource.modelNumber);
+    OICStrcpy(g_ESDevConfResource.devName, OIC_STRING_MAX_VALUE, (deviceProperty->DevConf).deviceName);
+    OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "Device Name : %s", g_ESDevConfResource.devName);
 
-    if(OC_STACK_NO_OBSERVERS == OCNotifyAllObservers(gWiFiResource.handle, OC_HIGH_QOS))
+    if (OC_STACK_NO_OBSERVERS == OCNotifyAllObservers(g_ESWiFiConfResource.handle, OC_HIGH_QOS))
     {
-        OIC_LOG(INFO, ES_RH_TAG, "wifiResource doesn't have any observers.");
+        OIC_LOG(DEBUG, ES_RH_TAG, "wifiResource doesn't have any observers.");
     }
 
-    if(OC_STACK_NO_OBSERVERS == OCNotifyAllObservers(gDevConfResource.handle, OC_HIGH_QOS))
+    if(OC_STACK_NO_OBSERVERS == OCNotifyAllObservers(g_ESDevConfResource.handle, OC_HIGH_QOS))
     {
-        OIC_LOG(INFO, ES_RH_TAG, "devConfResource doesn't have any observers.");
+        OIC_LOG(DEBUG, ES_RH_TAG, "devConfResource doesn't have any observers.");
     }
 
-    OIC_LOG(INFO, ES_RH_TAG, "SetDeviceProperty OUT");
+    OIC_LOG(DEBUG, ES_RH_TAG, "SetDeviceProperty OUT");
     return OC_STACK_OK;
 }
 
 OCStackResult SetEnrolleeState(ESEnrolleeState esState)
 {
-    OIC_LOG(INFO, ES_RH_TAG, "SetEnrolleeState IN");
+    OIC_LOG(DEBUG, ES_RH_TAG, "SetEnrolleeState IN");
 
-    gProvResource.status = esState;
-    OIC_LOG_V(INFO, ES_RH_TAG, "Enrollee Status : %d", gProvResource.status);
+    g_ESEasySetupResource.status = esState;
+    OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "Enrollee Status : %d", g_ESEasySetupResource.status);
 
-    if(OC_STACK_NO_OBSERVERS == OCNotifyAllObservers(gProvResource.handle, OC_HIGH_QOS))
+    if(OC_STACK_NO_OBSERVERS == OCNotifyAllObservers(g_ESEasySetupResource.handle, OC_HIGH_QOS))
     {
-        OIC_LOG(INFO, ES_RH_TAG, "provResource doesn't have any observers.");
+        OIC_LOG(DEBUG, ES_RH_TAG, "provResource doesn't have any observers.");
     }
 
-    OIC_LOG(INFO, ES_RH_TAG, "SetEnrolleeState OUT");
+    OIC_LOG(DEBUG, ES_RH_TAG, "SetEnrolleeState OUT");
     return OC_STACK_OK;
 }
 
 OCStackResult SetEnrolleeErrCode(ESErrorCode esErrCode)
 {
-    OIC_LOG(INFO, ES_RH_TAG, "SetEnrolleeErrCode IN");
+    OIC_LOG(DEBUG, ES_RH_TAG, "SetEnrolleeErrCode IN");
 
-    gProvResource.lastErrCode = esErrCode;
-    OIC_LOG_V(INFO, ES_RH_TAG, "Enrollee ErrorCode : %d", gProvResource.lastErrCode);
+    g_ESEasySetupResource.lastErrCode = esErrCode;
+    OIC_LOG_V(INFO_PRIVATE, ES_RH_TAG, "Enrollee ErrorCode : %d", g_ESEasySetupResource.lastErrCode);
 
-    if(OC_STACK_NO_OBSERVERS == OCNotifyAllObservers(gProvResource.handle, OC_HIGH_QOS))
+    if(OC_STACK_NO_OBSERVERS == OCNotifyAllObservers(g_ESEasySetupResource.handle, OC_HIGH_QOS))
     {
-        OIC_LOG(INFO, ES_RH_TAG, "provResource doesn't have any observers.");
+        OIC_LOG(DEBUG, ES_RH_TAG, "provResource doesn't have any observers.");
     }
 
-    OIC_LOG(INFO, ES_RH_TAG, "SetEnrolleeErrCode OUT");
+    OIC_LOG(DEBUG, ES_RH_TAG, "SetEnrolleeErrCode OUT");
     return OC_STACK_OK;
 }
 
index 03a6a05..851f047 100755 (executable)
 extern "C" {
 #endif
 
-typedef void (*ESWiFiCB) (ESResult, ESWiFiProvData *);
-typedef void (*ESCloudCB) (ESResult, ESCloudProvData *);
-typedef void (*ESDevConfCB) (ESResult, ESDevConfProvData *);
+typedef void (*ESConnectRequestCB) (ESResult, ESConnectRequest *);
+typedef void (*ESWiFiConfCB) (ESResult, ESWiFiConfData *);
+typedef void (*ESCoapCloudConfCB) (ESResult, ESCoapCloudConfData *);
+typedef void (*ESDevConfCB) (ESResult, ESDevConfData *);
 
 typedef void (*ESWriteUserdataCb)(OCRepPayload* payload, char* resourceType);
 typedef void (*ESReadUserdataCb)(OCRepPayload* payload, char* resourceType, void** userdata);
 
 /* Structure to represent a Light resource */
-typedef struct PROVRESOURCE
+typedef struct
 {
     OCResourceHandle handle;
     ProvStatus status; // provisiong status
     ESErrorCode lastErrCode;
-} ProvResource;
+    ES_CONNECT_TYPE connectRequest[NUM_CONNECT_TYPE];
+    int numRequest;
+} EasySetupResource;
 
 typedef struct
 {
@@ -59,15 +62,17 @@ typedef struct
     char cred[OIC_STRING_MAX_VALUE]; // credential information.
     WIFI_AUTHTYPE authType;
     WIFI_ENCTYPE encType;
-} WiFiResource;
+} WiFiConfResource;
 
 typedef struct
 {
     OCResourceHandle handle;
     char authCode[OIC_STRING_MAX_VALUE];
+    char accessToken[OIC_STRING_MAX_VALUE];
+    OAUTH_TOKENTYPE accessTokenType;
     char authProvider[OIC_STRING_MAX_VALUE];
     char ciServer[OIC_STRING_MAX_VALUE];
-} CloudResource;
+} CoapCloudConfResource;
 
 typedef struct
 {
@@ -79,6 +84,12 @@ typedef struct
     char country[OIC_STRING_MAX_VALUE];
 } DevConfResource;
 
+/* Note: These values of structures are not thread-safety */
+extern EasySetupResource g_ESEasySetupResource;
+extern WiFiConfResource g_ESWiFiConfResource;
+extern CoapCloudConfResource g_ESCoapCloudConfResource;
+extern DevConfResource g_ESDevConfResource;
+
 OCStackResult CreateEasySetupResources(bool isSecured, ESResourceMask resourceMask);
 OCStackResult DeleteEasySetupResources();
 
@@ -87,8 +98,8 @@ OCStackResult SetEnrolleeState(ESEnrolleeState esState);
 OCStackResult SetEnrolleeErrCode(ESErrorCode esErrCode);
 OCEntityHandlerResult CheckEhRequestPayload(OCEntityHandlerRequest *ehRequest);
 
-void RegisterWifiRsrcEventCallBack(ESWiFiCB);
-void RegisterCloudRsrcEventCallBack(ESCloudCB);
+void RegisterWifiRsrcEventCallBack(ESWiFiConfCB);
+void RegisterCloudRsrcEventCallBack(ESCoapCloudConfCB);
 void RegisterDevConfRsrcEventCallBack(ESDevConfCB);
 void UnRegisterResourceEventCallBack(void);
 ESResult SetCallbackForUserData(ESReadUserdataCb readCb, ESWriteUserdataCb writeCb);
diff --git a/service/easy-setup/enrollee/src/samsung/sc_easysetup.c b/service/easy-setup/enrollee/src/samsung/sc_easysetup.c
new file mode 100755 (executable)
index 0000000..98e1eb8
--- /dev/null
@@ -0,0 +1,579 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+
+#include "samsung/sc_easysetup.h"
+#include "string.h"
+#include "oic_malloc.h"
+#include "logger.h"
+#include "stdio.h"
+
+#include "ocpayload.h"
+#include "oic_string.h"
+#include "oic_malloc.h"
+
+#include "resourcehandler.h"
+
+/**
+ * @var SC_ENROLLEE_TAG
+ * @brief Logging tag for module name.
+ */
+#define SC_ENROLLEE_TAG "ES_SC_ENROLLEE"
+
+EasySetupResource g_ESEasySetupResource;
+WiFiConfResource g_ESWiFiConfResource;
+CoapCloudConfResource g_ESCoapCloudConfResource;
+DevConfResource g_ESDevConfResource;
+
+SCProperties g_SCProperties;
+
+static void ReadAccountData(OCRepPayload* payload,void** userdata);
+static void ReadTnCdata(OCRepPayload* payload,void** userdata);
+static void WriteTnCdata(OCRepPayload* payload, char* resourceType);
+static void WriteWifiData(OCRepPayload* payload, char* resourceType);
+
+ESResult SetSCProperties(const SCProperties *prop)
+{
+    OIC_LOG(INFO, SC_ENROLLEE_TAG, "SetSCProperties IN");
+    if(prop != NULL)
+    {
+        memcpy(&g_SCProperties, prop, sizeof(SCProperties));
+        OIC_LOG(INFO, SC_ENROLLEE_TAG, "SetSCProperties OUT");
+        return ES_OK;
+    }
+    OIC_LOG(INFO, SC_ENROLLEE_TAG, "SetSCProperties OUT");
+    return ES_ERROR;
+}
+
+static void ReadAccountData(OCRepPayload* payload,void** userdata)
+{
+    OIC_LOG(INFO, SC_ENROLLEE_TAG, "ReadAccountData IN");
+
+    char* account = NULL;
+
+    if(OCRepPayloadGetPropString(payload, SC_RSRVD_ES_VENDOR_ACCOUNT, &account))
+    {
+        if(*userdata == NULL)
+        {
+            *userdata = (void*)OICMalloc(sizeof(SCDevConfProperties));
+            if( *userdata == NULL )
+            {
+                OIC_LOG(ERROR, SC_ENROLLEE_TAG, "OICMalloc for SCDevConfProperties is failed");
+                return ;
+            }
+        }
+
+        SCDevConfProperties *pDevConfProp = (SCDevConfProperties*)(*userdata);
+        OICStrcpy(pDevConfProp->account, MAXLEN_STRING, account);
+        OICStrcpy(g_SCProperties.account, MAXLEN_STRING, account);
+
+        OIC_LOG_V(INFO_PRIVATE, SC_ENROLLEE_TAG, "[User specific property] %s : %s",
+                SC_RSRVD_ES_VENDOR_ACCOUNT, pDevConfProp->account);
+
+    }
+    OIC_LOG(INFO, SC_ENROLLEE_TAG, "ReadAccountData OUT");
+
+}
+
+ESResult SetSCTncInfo(SCTncInfo *tncInfo)
+{
+    if(tncInfo == NULL)
+    {
+        return ES_ERROR;
+    }
+    g_SCProperties.tncInfo = *tncInfo;
+    return ES_OK;
+}
+
+ESResult SetSCTncStatus(int status)
+{
+    g_SCProperties.tncStatus = status;
+    return ES_OK;
+}
+
+ESResult SetSCNetConnectionState(NETCONNECTION_STATE netConnectionState)
+{
+    OIC_LOG(INFO, SC_ENROLLEE_TAG, "SetSCNetConnectionState IN");
+
+    OIC_LOG_V(INFO_PRIVATE, SC_ENROLLEE_TAG, "SetSCNetConnectionState: %d", netConnectionState);
+    g_SCProperties.netConnectionState = netConnectionState;
+
+    if(OC_STACK_NO_OBSERVERS == OCNotifyAllObservers(g_ESEasySetupResource.handle, OC_HIGH_QOS))
+    {
+        OIC_LOG(DEBUG, SC_ENROLLEE_TAG, "provResource doesn't have any observers.");
+    }
+
+    OIC_LOG(INFO, SC_ENROLLEE_TAG, "SetSCNetConnectionState OUT");
+    return ES_OK;
+}
+
+static void ReadTnCdata(OCRepPayload* payload,void** userdata)
+{
+    OIC_LOG(INFO, SC_ENROLLEE_TAG, "ReadTnCdata IN");
+
+    char* tncResult = NULL;
+
+    if (OCRepPayloadGetPropString(payload, SC_RSRVD_ES_VENDOR_TNC_RESULT, &tncResult))
+    {
+        if(*userdata == NULL)
+        {
+            *userdata = (void*)OICMalloc(sizeof(SCCoapCloudServerConfProperties));
+            if( *userdata == NULL )
+            {
+                OIC_LOG(ERROR, SC_ENROLLEE_TAG, "OICMalloc for SCCoapCloudServerConfProperties is failed");
+                return ;
+            }
+        }
+
+        SCCoapCloudServerConfProperties *pProp = (SCCoapCloudServerConfProperties*)(*userdata);
+        OICStrcpy(pProp->tncResult, MAXLEN_STRING, tncResult);
+        OICStrcpy(g_SCProperties.tncResult, MAXLEN_STRING, tncResult);
+
+        OIC_LOG_V(INFO_PRIVATE, SC_ENROLLEE_TAG, "[User specific property] %s : %s",
+                SC_RSRVD_ES_VENDOR_TNC_RESULT, pProp->tncResult);
+    }
+
+    OIC_LOG(INFO, SC_ENROLLEE_TAG, "ReadTnCdata OUT");
+}
+
+void WriteTnCdata(OCRepPayload* payload, char* resourceType)
+{
+    OIC_LOG(INFO, SC_ENROLLEE_TAG, "WriteTnCdata IN");
+
+    if(payload == NULL || resourceType == NULL)
+    {
+        OIC_LOG(DEBUG, SC_ENROLLEE_TAG, "Invalid Params payload or resourceType is NULL");
+        OIC_LOG(DEBUG, SC_ENROLLEE_TAG, "WriteTnCdata OUT");
+        return;
+    }
+    if(strstr(resourceType, OC_RSRVD_ES_RES_TYPE_EASYSETUP))
+    {
+        OCRepPayloadSetPropInt(payload, SC_RSRVD_ES_VENDOR_TNC_STATUS, g_SCProperties.tncStatus);
+    }
+    else if(strstr(resourceType, OC_RSRVD_ES_RES_TYPE_DEVCONF))
+    {
+        OCRepPayloadSetPropString(payload, SC_RSRVD_ES_VENDOR_TNC_HEADER,
+                g_SCProperties.tncInfo.header);
+        OCRepPayloadSetPropString(payload, SC_RSRVD_ES_VENDOR_TNC_VERSION,
+                g_SCProperties.tncInfo.version);
+    }
+    else if(strstr(resourceType, OC_RSRVD_ES_RES_TYPE_COAPCLOUDCONF))
+    {
+        OCRepPayloadSetPropString(payload, SC_RSRVD_ES_VENDOR_TNC_RESULT,
+                g_SCProperties.tncResult);
+    }
+    OIC_LOG(INFO, SC_ENROLLEE_TAG, "WriteTnCdata OUT");
+}
+
+void WriteWifiData(OCRepPayload* payload, char* resourceType)
+{
+    OIC_LOG(INFO, SC_ENROLLEE_TAG, "WriteWifiData IN");
+
+    if(payload == NULL || resourceType == NULL)
+    {
+        OIC_LOG(DEBUG, SC_ENROLLEE_TAG, "Invalid Params payload or resourceType is NULL");
+        OIC_LOG(DEBUG, SC_ENROLLEE_TAG, "WriteWifiData OUT");
+        return;
+    }
+
+    if(strstr(resourceType, OC_RSRVD_ES_RES_TYPE_WIFICONF))
+    {
+        OCRepPayloadSetPropString(payload, SC_RSRVD_ES_VENDOR_BSSID,
+                g_SCProperties.bssid);
+    }
+    OIC_LOG(INFO, SC_ENROLLEE_TAG, "WriteWifiData OUT");
+}
+
+ESResult SetRegisterSetDevice(const char *regSetDevice)
+{
+    if(regSetDevice != NULL)
+    {
+        OICStrcpy(g_SCProperties.regSetDev, sizeof(g_SCProperties.regSetDev), regSetDevice);
+        return ES_OK;
+    }
+    return ES_ERROR;
+}
+
+ESResult SetNetworkProvInfo(const char *nwProvInfo)
+{
+    if(nwProvInfo != NULL)
+    {
+        OICStrcpy(g_SCProperties.nwProvInfo, sizeof(g_SCProperties.nwProvInfo), nwProvInfo);
+        return ES_OK;
+    }
+    return ES_ERROR;
+}
+
+ESResult SetSCPnPPin(const char *pnp)
+{
+    if(pnp != NULL)
+    {
+        OICStrcpy(g_SCProperties.pnpPin, sizeof(g_SCProperties.pnpPin), pnp);
+        return ES_OK;
+    }
+    return ES_ERROR;
+}
+
+ESResult SetESVersionInfo(const char *esProtocolVersion)
+{
+    if(esProtocolVersion != NULL)
+    {
+        OICStrcpy(g_SCProperties.esProtocolVersion, sizeof(g_SCProperties.esProtocolVersion), esProtocolVersion);
+        return ES_OK;
+    }
+    return ES_ERROR;
+}
+
+void ReadUserdataCb(OCRepPayload* payload, char* resourceType, void** userdata)
+{
+    OIC_LOG(INFO, SC_ENROLLEE_TAG, "ReadUserdataCb IN");
+
+    if(payload != NULL)
+    {
+        if(strstr(resourceType, OC_RSRVD_ES_RES_TYPE_WIFICONF))
+        {
+            int64_t channel = -1;
+            char *bssid = NULL;
+            if (OCRepPayloadGetPropInt(payload, SC_RSRVD_ES_VENDOR_DISCOVERY_CHANNEL, &channel))
+            {
+                if(*userdata == NULL)
+                {
+                    *userdata = (void*)OICMalloc(sizeof(SCWiFiConfProperties));
+                    if( *userdata == NULL )
+                    {
+                        OIC_LOG(ERROR, SC_ENROLLEE_TAG, "OICMalloc for SCWiFiConfProperties is failed");
+                        return ;
+                    }
+                    memset(*userdata, 0, sizeof(SCWiFiConfProperties));
+                }
+                OIC_LOG_V(INFO_PRIVATE, SC_ENROLLEE_TAG, "[User specific property] %s : [%" PRId64 "]",
+                                                            SC_RSRVD_ES_VENDOR_DISCOVERY_CHANNEL, channel);
+                ((SCWiFiConfProperties*)(*userdata))->discoveryChannel = (int) channel;
+                g_SCProperties.discoveryChannel = channel;
+            }
+            if (OCRepPayloadGetPropString(payload, SC_RSRVD_ES_VENDOR_BSSID, &bssid))
+            {
+                if(*userdata == NULL)
+                {
+                    *userdata = (void*) OICMalloc(sizeof(SCWiFiConfProperties));
+                    if( *userdata == NULL )
+                    {
+                        OIC_LOG(ERROR, SC_ENROLLEE_TAG, "OICMalloc for SCWiFiConfProperties is failed");
+                        return ;
+                    }
+                    memset(*userdata, 0, sizeof(SCWiFiConfProperties));
+                }
+                if (*userdata != NULL)
+                {
+                    OIC_LOG_V(INFO_PRIVATE, SC_ENROLLEE_TAG, "[User specific property] %s : %s",
+                            SC_RSRVD_ES_VENDOR_BSSID, bssid);
+                    SCWiFiConfProperties* pWifiConfProp = (SCWiFiConfProperties*)(*userdata);
+                    OICStrcpy(pWifiConfProp->bssid, sizeof(pWifiConfProp->bssid), bssid);
+                    OICStrcpy(g_SCProperties.bssid, sizeof(g_SCProperties.bssid), bssid);
+                    OICFree(bssid);
+                }
+            }
+        }
+        else if(strstr(resourceType, OC_RSRVD_ES_RES_TYPE_DEVCONF))
+        {
+            if(*userdata == NULL)
+            {
+                *userdata = (void*)OICMalloc(sizeof(SCDevConfProperties));
+                if( *userdata == NULL )
+                {
+                    OIC_LOG(ERROR, SC_ENROLLEE_TAG, "OICMalloc for SCDevConfProperties is failed");
+                    return ;
+                }
+                memset(*userdata, 0, sizeof(SCDevConfProperties));
+            }
+
+            SCDevConfProperties *pDevConfProp = (SCDevConfProperties*)(*userdata);
+
+            char**locationList = NULL;
+            size_t dimensions[MAX_REP_ARRAY_DEPTH] = {0};
+            if(OCRepPayloadGetStringArray(payload, SC_RSRVD_ES_VENDOR_LOCATION, &locationList, dimensions))
+            {
+                for(size_t idx = 0; idx < dimensions[0]; idx++)
+                {
+                    OICStrcpy(pDevConfProp->location[idx], strlen(locationList[idx])+1, locationList[idx]);
+                    OICStrcpy(g_SCProperties.location[idx], strlen(locationList[idx])+1, locationList[idx]);
+
+                    OIC_LOG_V(INFO_PRIVATE, SC_ENROLLEE_TAG, "[User specific property] %s : %s",
+                                        SC_RSRVD_ES_VENDOR_LOCATION, pDevConfProp->location[idx]);
+                }
+
+                ((SCDevConfProperties*)(*userdata))->numLocation = (int)dimensions[0];
+                g_SCProperties.numLocation = (int)dimensions[0];
+            }
+
+            ReadAccountData(payload,userdata);
+
+            char *regMobileDev = NULL;
+            if (OCRepPayloadGetPropString(payload, SC_RSRVD_ES_VENDOR_REGISTER_MOBILE_DEV, &regMobileDev))
+            {
+                OICStrcpy(pDevConfProp->regMobileDev, strlen(regMobileDev)+1, regMobileDev);
+                OICStrcpy(g_SCProperties.regMobileDev, strlen(regMobileDev)+1, regMobileDev);
+                OIC_LOG_V(INFO_PRIVATE, SC_ENROLLEE_TAG, "pDevConfProp.regMobileDev %s", g_SCProperties.regMobileDev);
+            }
+
+            char *country = NULL;
+            if (OCRepPayloadGetPropString(payload, SC_RSRVD_ES_VENDOR_COUNTRY, &country))
+            {
+                OICStrcpy(pDevConfProp->country, strlen(country)+1, country);
+                OICStrcpy(g_SCProperties.country, strlen(country)+1, country);
+                OIC_LOG_V(INFO_PRIVATE, SC_ENROLLEE_TAG, "pDevConfProp.country %s", g_SCProperties.country);
+            }
+
+            char *language = NULL;
+            if (OCRepPayloadGetPropString(payload, SC_RSRVD_ES_VENDOR_LANGUAGE, &language))
+            {
+                OICStrcpy(pDevConfProp->language, strlen(language)+1, language);
+                OICStrcpy(g_SCProperties.language, strlen(language)+1, language);
+                OIC_LOG_V(INFO_PRIVATE, SC_ENROLLEE_TAG, "pDevConfProp.language %s", g_SCProperties.language);
+            }
+
+            char *gpsLocation = NULL;
+            if (OCRepPayloadGetPropString(payload, SC_RSRVD_ES_VENDOR_GPSLOCATION, &gpsLocation))
+            {
+                OICStrcpy(pDevConfProp->gpsLocation, strlen(gpsLocation)+1, gpsLocation);
+                OICStrcpy(g_SCProperties.gpsLocation, strlen(gpsLocation)+1, gpsLocation);
+                OIC_LOG_V(INFO_PRIVATE, SC_ENROLLEE_TAG, "pDevConfProp.gpsLocation %s", g_SCProperties.gpsLocation);
+            }
+
+            char *utcDateTime = NULL;
+            if (OCRepPayloadGetPropString(payload, SC_RSRVD_ES_VENDOR_UTC_DATE_TIME, &utcDateTime))
+            {
+                OICStrcpy(pDevConfProp->utcDateTime, strlen(utcDateTime)+1, utcDateTime);
+                OICStrcpy(g_SCProperties.utcDateTime, strlen(utcDateTime)+1, utcDateTime);
+                OIC_LOG_V(INFO_PRIVATE, SC_ENROLLEE_TAG, "pDevConfProp.utcDateTime %s", g_SCProperties.utcDateTime);
+            }
+
+            char *regionalDateTime = NULL;
+            if (OCRepPayloadGetPropString(payload, SC_RSRVD_ES_VENDOR_REGIONAL_DATE_TIME, &regionalDateTime))
+            {
+                OICStrcpy(pDevConfProp->regionalDateTime, strlen(regionalDateTime)+1, regionalDateTime);
+                OICStrcpy(g_SCProperties.regionalDateTime, strlen(regionalDateTime)+1, regionalDateTime);
+                OIC_LOG_V(INFO_PRIVATE, SC_ENROLLEE_TAG, "pDevConfProp.regionalDateTime %s", g_SCProperties.regionalDateTime);
+            }
+        }
+        else if(strstr(resourceType, OC_RSRVD_ES_RES_TYPE_COAPCLOUDCONF))
+        {
+            char* clientID = NULL;
+            if(OCRepPayloadGetPropString(payload, SC_RSRVD_ES_VENDOR_CLIENTID, &clientID))
+            {
+                if(*userdata == NULL)
+                {
+                    *userdata = (void*)OICMalloc(sizeof(SCCoapCloudServerConfProperties));
+                    if( *userdata == NULL )
+                    {
+                        OIC_LOG(ERROR, SC_ENROLLEE_TAG, "OICMalloc for SCCoapCloudServerConfProperties is failed");
+                        return ;
+                    }
+                    memset(*userdata, 0, sizeof(SCCoapCloudServerConfProperties));
+                }
+
+                SCCoapCloudServerConfProperties *pCloudProp =
+                                                    (SCCoapCloudServerConfProperties*)(*userdata);
+
+                OICStrcpy(pCloudProp->clientID, strlen(clientID)+1, clientID);
+                OICStrcpy(g_SCProperties.clientID, strlen(clientID)+1, clientID);
+
+                OIC_LOG_V(INFO_PRIVATE, SC_ENROLLEE_TAG, "[User specific property] %s : %s",
+                                        SC_RSRVD_ES_VENDOR_CLIENTID, pCloudProp->clientID);
+            }
+
+            //SC_RSRVD_ES_VENDOR_AAC
+            char *aac = NULL;
+            if (OCRepPayloadGetPropString(payload, SC_RSRVD_ES_VENDOR_AAC, &aac))
+            {
+                if(*userdata == NULL)
+                {
+                    *userdata = (void*)OICMalloc(sizeof(SCCoapCloudServerConfProperties));
+                    if( *userdata == NULL )
+                    {
+                        OIC_LOG(ERROR, SC_ENROLLEE_TAG, "OICMalloc for SCCoapCloudServerConfProperties is failed");
+                        return ;
+                    }
+                    memset(*userdata, 0, sizeof(SCCoapCloudServerConfProperties));
+                }
+
+                if (*userdata != NULL)
+                {
+                    SCCoapCloudServerConfProperties *pCloudProp =
+                                                    (SCCoapCloudServerConfProperties*) (*userdata);
+                    pCloudProp->aac[0] = '\0';
+
+                    OICStrcpy(pCloudProp->aac, MAXLEN_STRING, aac);
+                    OICStrcpy(g_SCProperties.aac, MAXLEN_STRING, aac);
+                    OICFree(aac);
+
+                    OIC_LOG_V(INFO_PRIVATE, SC_ENROLLEE_TAG, "[User specific property] %s : %s",
+                            SC_RSRVD_ES_VENDOR_AAC, pCloudProp->aac);
+                }
+            }
+
+            //SC_RSRVD_ES_VENDOR_UID
+            char *uid = NULL;
+            if (OCRepPayloadGetPropString(payload, SC_RSRVD_ES_VENDOR_UID, &uid))
+            {
+                if(*userdata == NULL)
+                {
+                    *userdata = (void*)OICMalloc(sizeof(SCCoapCloudServerConfProperties));
+                    if( *userdata == NULL )
+                    {
+                        OIC_LOG(ERROR, SC_ENROLLEE_TAG, "OICMalloc for SCCoapCloudServerConfProperties is failed");
+                        return ;
+                    }
+                    memset(*userdata, 0, sizeof(SCCoapCloudServerConfProperties));
+                }
+
+                if (*userdata != NULL)
+                {
+                    SCCoapCloudServerConfProperties *pCloudProp =
+                                                    (SCCoapCloudServerConfProperties*) (*userdata);
+                    pCloudProp->uid[0] = '\0';
+
+                    OICStrcpy(pCloudProp->uid, MAXLEN_STRING, uid);
+                    OICStrcpy(g_SCProperties.uid, MAXLEN_STRING, uid);
+                    OICFree(uid);
+
+                    OIC_LOG_V(INFO_PRIVATE, SC_ENROLLEE_TAG, "[User specific property] %s : %s",
+                            SC_RSRVD_ES_VENDOR_UID, pCloudProp->uid);
+                }
+            }
+
+            //SC_RSRVD_ES_VENDOR_REFRESH_TOKEN
+            char *refreshToken = NULL;
+            if (OCRepPayloadGetPropString(payload, SC_RSRVD_ES_VENDOR_REFRESH_TOKEN, &refreshToken))
+            {
+                if(*userdata == NULL)
+                {
+                    *userdata = (void*)OICMalloc(sizeof(SCCoapCloudServerConfProperties));
+                    if( *userdata == NULL )
+                    {
+                        OIC_LOG(ERROR, SC_ENROLLEE_TAG, "OICMalloc for SCCoapCloudServerConfProperties is failed");
+                        return ;
+                    }
+                    memset(*userdata, 0, sizeof(SCCoapCloudServerConfProperties));
+                }
+
+                if (*userdata != NULL)
+                {
+                    SCCoapCloudServerConfProperties *pCloudProp =
+                                                    (SCCoapCloudServerConfProperties*) (*userdata);
+                    pCloudProp->refreshToken[0] = '\0';
+
+                    OICStrcpy(pCloudProp->refreshToken, MAXLEN_STRING, refreshToken);
+                    OICStrcpy(g_SCProperties.refreshToken, MAXLEN_STRING, refreshToken);
+                    OICFree(refreshToken);
+
+                    OIC_LOG_V(INFO_PRIVATE, SC_ENROLLEE_TAG, "[User specific property] %s : %s",
+                            SC_RSRVD_ES_VENDOR_REFRESH_TOKEN, pCloudProp->refreshToken);
+                }
+            }
+
+            ReadTnCdata(payload,userdata);
+        }
+    }
+
+    OIC_LOG(INFO, SC_ENROLLEE_TAG, "ReadUserdataCb OUT");
+}
+
+void WriteUserdataCb(OCRepPayload* payload, char* resourceType)
+{
+    OIC_LOG(INFO, SC_ENROLLEE_TAG, "WriteUserdataCb IN");
+
+    if(payload != NULL)
+    {
+        if(strstr(resourceType, OC_RSRVD_ES_RES_TYPE_EASYSETUP))
+        {
+            OCRepPayloadSetPropInt(payload, SC_RSRVD_ES_VENDOR_NETCONNECTION_STATE, (int) g_SCProperties.netConnectionState);
+        }
+
+        if(strstr(resourceType, OC_RSRVD_ES_RES_TYPE_DEVCONF))
+        {
+#ifndef __TIZENRT__
+            OCRepPayloadSetPropString(payload, SC_RSRVD_ES_VENDOR_DEVICE_TYPE, g_SCProperties.deviceType);
+            OCRepPayloadSetPropString(payload, SC_RSRVD_ES_VENDOR_DEVICE_SUBTYPE, g_SCProperties.deviceSubType);
+            OCRepPayloadSetPropString(payload, SC_RSRVD_ES_VENDOR_REGISTER_SET_DEV, g_SCProperties.regSetDev);
+            OCRepPayloadSetPropString(payload, SC_RSRVD_ES_VENDOR_REGISTER_MOBILE_DEV, g_SCProperties.regMobileDev);
+            OCRepPayloadSetPropString(payload, SC_RSRVD_ES_VENDOR_NETWORK_PROV_INFO, g_SCProperties.nwProvInfo);
+            OCRepPayloadSetPropString(payload, SC_RSRVD_ES_VENDOR_PNP_PIN, g_SCProperties.pnpPin);
+            OCRepPayloadSetPropString(payload, SC_RSRVD_ES_VENDOR_MODEL_NUMBER, g_SCProperties.modelNumber);
+            OCRepPayloadSetPropString(payload, SC_RSRVD_ES_VENDOR_COUNTRY, g_SCProperties.country);
+            OCRepPayloadSetPropString(payload, SC_RSRVD_ES_VENDOR_LANGUAGE, g_SCProperties.language);
+            OCRepPayloadSetPropString(payload, SC_RSRVD_ES_VENDOR_GPSLOCATION, g_SCProperties.gpsLocation);
+            OCRepPayloadSetPropString(payload, SC_RSRVD_ES_VENDOR_UTC_DATE_TIME, g_SCProperties.utcDateTime);
+            OCRepPayloadSetPropString(payload, SC_RSRVD_ES_VENDOR_REGIONAL_DATE_TIME, g_SCProperties.regionalDateTime);
+            OCRepPayloadSetPropString(payload, SC_RSRVD_ES_VENDOR_ES_PROTOCOL_VERSION, g_SCProperties.esProtocolVersion);
+#else
+            if(g_SCProperties.deviceType != NULL)
+            {
+                OCRepPayloadSetPropString(payload, SC_RSRVD_ES_VENDOR_DEVICE_TYPE, g_SCProperties.deviceType);
+            }
+            if(g_SCProperties.deviceSubType != NULL)
+            {
+                OCRepPayloadSetPropString(payload, SC_RSRVD_ES_VENDOR_DEVICE_SUBTYPE, g_SCProperties.deviceSubType);
+            }
+            if(g_SCProperties.regSetDev != NULL)
+            {
+                OCRepPayloadSetPropString(payload, SC_RSRVD_ES_VENDOR_REGISTER_SET_DEV, g_SCProperties.regSetDev);
+            }
+            if(g_SCProperties.regMobileDev != NULL)
+            {
+                OCRepPayloadSetPropString(payload, SC_RSRVD_ES_VENDOR_REGISTER_MOBILE_DEV, g_SCProperties.regMobileDev);
+            }
+            if(g_SCProperties.nwProvInfo!= NULL)
+            {
+                OCRepPayloadSetPropString(payload, SC_RSRVD_ES_VENDOR_NETWORK_PROV_INFO, g_SCProperties.nwProvInfo);
+            }
+            if(g_SCProperties.pnpPin != NULL)
+            {
+               OCRepPayloadSetPropString(payload, SC_RSRVD_ES_VENDOR_PNP_PIN, g_SCProperties.pnpPin);
+            }
+            if(g_SCProperties.modelNumber != NULL)
+            {
+               OCRepPayloadSetPropString(payload, SC_RSRVD_ES_VENDOR_MODEL_NUMBER, g_SCProperties.modelNumber);
+            }
+            if(g_SCProperties.country != NULL)
+            {
+               OCRepPayloadSetPropString(payload, SC_RSRVD_ES_VENDOR_COUNTRY, g_SCProperties.country);
+            }
+            if(g_SCProperties.language != NULL)
+            {
+               OCRepPayloadSetPropString(payload, SC_RSRVD_ES_VENDOR_LANGUAGE, g_SCProperties.language);
+            }
+            if(g_SCProperties.gpsLocation != NULL)
+            {
+               OCRepPayloadSetPropString(payload, SC_RSRVD_ES_VENDOR_GPSLOCATION, g_SCProperties.gpsLocation);
+            }
+            if(g_SCProperties.esProtocolVersion != NULL)
+            {
+                OCRepPayloadSetPropString(payload, SC_RSRVD_ES_VENDOR_ES_PROTOCOL_VERSION, g_SCProperties.esProtocolVersion);
+            }
+#endif
+        }
+    }
+
+    WriteTnCdata(payload, resourceType);
+    WriteWifiData(payload, resourceType);
+
+    OIC_LOG(INFO, SC_ENROLLEE_TAG, "WriteUserdataCb OUT");
+}
index 6ebe826..b041d1f 100755 (executable)
@@ -118,30 +118,30 @@ public:
         std::cout << __func__ << std::endl;
     }
 
-    static void WiFiProvCbInApp(ESWiFiProvData *)
+    static void WiFiConfProvCbInApp(ESWiFiConfData *)
     {
         std::cout << __func__ << std::endl;
     }
 
-    static void DevConfProvCbInApp(ESDevConfProvData *)
+    static void DevConfProvCbInApp(ESDevConfData *)
     {
         std::cout << __func__ << std::endl;
     }
 
-    static void CloudDataCbInApp(ESCloudProvData *)
+    static void CoapCloudConfCbInApp(ESCoapCloudConfData *)
     {
         std::cout << __func__ << std::endl;
     }
 
     ESResult startEnrollee()
     {
-        ESResourceMask resourcemMask = (ESResourceMask)(ES_WIFI_RESOURCE |
-                                                    ES_CLOUD_RESOURCE |
+        ESResourceMask resourcemMask = (ESResourceMask)(ES_WIFICONF_RESOURCE |
+                                                    ES_COAPCLOUDCONF_RESOURCE |
                                                     ES_DEVCONF_RESOURCE);
         ESProvisioningCallbacks callbacks;
-        callbacks.WiFiProvCb = &EasysetupEnrolleeTest::WiFiProvCbInApp;
+        callbacks.WiFiConfProvCb = &EasysetupEnrolleeTest::WiFiConfProvCbInApp;
         callbacks.DevConfProvCb = &EasysetupEnrolleeTest::DevConfProvCbInApp;
-        callbacks.CloudDataProvCb = &EasysetupEnrolleeTest::CloudDataCbInApp;
+        callbacks.CoapCloudConfProvCb = &EasysetupEnrolleeTest::CoapCloudConfCbInApp;
 
         return ESInitEnrollee(false, resourcemMask, callbacks);
     }
@@ -149,9 +149,9 @@ public:
     ESResult startEnrolleeWithInvalidRsrcMask()
     {
         ESProvisioningCallbacks callbacks;
-        callbacks.WiFiProvCb = &EasysetupEnrolleeTest::WiFiProvCbInApp;
+        callbacks.WiFiConfProvCb = &EasysetupEnrolleeTest::WiFiConfProvCbInApp;
         callbacks.DevConfProvCb = &EasysetupEnrolleeTest::DevConfProvCbInApp;
-        callbacks.CloudDataProvCb = &EasysetupEnrolleeTest::CloudDataCbInApp;
+        callbacks.CoapCloudConfProvCb = &EasysetupEnrolleeTest::CoapCloudConfCbInApp;
 
         return ESInitEnrollee(false, (ESResourceMask)0, callbacks);
     }
@@ -159,7 +159,7 @@ public:
     ESResult setDeviceProperty()
     {
         ESDeviceProperty deviceProperty = {
-            {{WIFI_11G, WiFi_EOF}, WIFI_5G}, {"Test Device", "Test Model Number"}
+            {{WIFI_11G, WiFi_EOF}, WIFI_5G}, {"Test Device"}
         };
 
         return ESSetDeviceProperty(&deviceProperty);
@@ -211,13 +211,13 @@ TEST_F(EasysetupEnrolleeTest, ESInitEnrolleeFailedInvalidRsrcMask)
 
 TEST_F(EasysetupEnrolleeTest, ESInitEnrolleeFailedByWiFiCbIsNull)
 {
-    ESResourceMask resourcemMask = (ESResourceMask)(ES_WIFI_RESOURCE |
-                                                    ES_CLOUD_RESOURCE |
+    ESResourceMask resourcemMask = (ESResourceMask)(ES_WIFICONF_RESOURCE |
+                                                    ES_COAPCLOUDCONF_RESOURCE |
                                                     ES_DEVCONF_RESOURCE);
     ESProvisioningCallbacks callbacks;
-    callbacks.WiFiProvCb = NULL;
+    callbacks.WiFiConfProvCb = NULL;
     callbacks.DevConfProvCb = &EasysetupEnrolleeTest::DevConfProvCbInApp;
-    callbacks.CloudDataProvCb = &EasysetupEnrolleeTest::CloudDataCbInApp;
+    callbacks.CoapCloudConfProvCb = &EasysetupEnrolleeTest::CoapCloudConfCbInApp;
 
     ESResult ret = ESInitEnrollee(false, resourcemMask, callbacks);
     EXPECT_EQ(ret, ES_ERROR);
@@ -226,13 +226,13 @@ TEST_F(EasysetupEnrolleeTest, ESInitEnrolleeFailedByWiFiCbIsNull)
 
 TEST_F(EasysetupEnrolleeTest, ESInitEnrolleeFailedByDevConfCbIsNull)
 {
-    ESResourceMask resourcemMask = (ESResourceMask)(ES_WIFI_RESOURCE |
-                                                    ES_CLOUD_RESOURCE |
+    ESResourceMask resourcemMask = (ESResourceMask)(ES_WIFICONF_RESOURCE |
+                                                    ES_COAPCLOUDCONF_RESOURCE |
                                                     ES_DEVCONF_RESOURCE);
     ESProvisioningCallbacks callbacks;
-    callbacks.WiFiProvCb = &EasysetupEnrolleeTest::WiFiProvCbInApp;
+    callbacks.WiFiConfProvCb = &EasysetupEnrolleeTest::WiFiConfProvCbInApp;
     callbacks.DevConfProvCb = NULL;
-    callbacks.CloudDataProvCb = &EasysetupEnrolleeTest::CloudDataCbInApp;
+    callbacks.CoapCloudConfProvCb = &EasysetupEnrolleeTest::CoapCloudConfCbInApp;
 
     ESResult ret = ESInitEnrollee(false, resourcemMask, callbacks);
     EXPECT_EQ(ret, ES_ERROR);
@@ -241,13 +241,13 @@ TEST_F(EasysetupEnrolleeTest, ESInitEnrolleeFailedByDevConfCbIsNull)
 
 TEST_F(EasysetupEnrolleeTest, ESInitEnrolleeFailedByCloudCbIsNull)
 {
-    ESResourceMask resourcemMask = (ESResourceMask)(ES_WIFI_RESOURCE |
-                                                    ES_CLOUD_RESOURCE |
+    ESResourceMask resourcemMask = (ESResourceMask)(ES_WIFICONF_RESOURCE |
+                                                    ES_COAPCLOUDCONF_RESOURCE |
                                                     ES_DEVCONF_RESOURCE);
     ESProvisioningCallbacks callbacks;
-    callbacks.WiFiProvCb = &EasysetupEnrolleeTest::WiFiProvCbInApp;
+    callbacks.WiFiConfProvCb = &EasysetupEnrolleeTest::WiFiConfProvCbInApp;
     callbacks.DevConfProvCb = &EasysetupEnrolleeTest::DevConfProvCbInApp;
-    callbacks.CloudDataProvCb = NULL;
+    callbacks.CoapCloudConfProvCb = NULL;
 
     ESResult ret = ESInitEnrollee(false, resourcemMask, callbacks);
     EXPECT_EQ(ret, ES_ERROR);
@@ -382,8 +382,8 @@ TEST_F(EasysetupEnrolleeTest, WiFiAndDevConfProperiesProvisionedWithSuccess)
                cntForReceivedCallbackWithSuccess++;
         });
 
-    mocks.OnCallFunc(WiFiProvCbInApp).Do(
-        [& cntForReceivedCallbackWithSuccess](ESWiFiProvData *data)
+    mocks.OnCallFunc(WiFiConfProvCbInApp).Do(
+        [& cntForReceivedCallbackWithSuccess](ESWiFiConfData *data)
         {
             if(!strcmp(data->ssid, "Iotivity_SSID") &&
                 !strcmp(data->pwd, "Iotivity_PWD") &&
@@ -393,15 +393,6 @@ TEST_F(EasysetupEnrolleeTest, WiFiAndDevConfProperiesProvisionedWithSuccess)
                 cntForReceivedCallbackWithSuccess++;
             }
         });
-    mocks.OnCallFunc(DevConfProvCbInApp).Do(
-        [& cntForReceivedCallbackWithSuccess](ESDevConfProvData *data)
-        {
-            if(!strcmp(data->language, "korean") &&
-                !strcmp(data->country, "Korea"))
-            {
-                cntForReceivedCallbackWithSuccess++;
-            }
-        });
 
     startEnrollee();
 
@@ -410,7 +401,7 @@ TEST_F(EasysetupEnrolleeTest, WiFiAndDevConfProperiesProvisionedWithSuccess)
     std::unique_lock< std::mutex > lock{ mutexForCondition };
     responseCon.wait_for(lock, g_waitForResponse);
 
-    EXPECT_EQ(cntForReceivedCallbackWithSuccess, 3);
+    EXPECT_EQ(cntForReceivedCallbackWithSuccess, 2);
 
     ESTerminateEnrollee();
 }
@@ -428,8 +419,8 @@ TEST_F(EasysetupEnrolleeTest, CloudServerProperiesProvisionedWithSuccess)
             }
         });
 
-    mocks.OnCallFunc(CloudDataCbInApp).Do(
-        [& cntForReceivedCallbackWithSuccess](ESCloudProvData *data)
+    mocks.OnCallFunc(CoapCloudConfCbInApp).Do(
+        [& cntForReceivedCallbackWithSuccess](ESCoapCloudConfData *data)
         {
             if(!strcmp(data->authCode, "authCode") &&
                 !strcmp(data->authProvider, "authProvider") &&
index 392cf6c..ee8f1ff 100755 (executable)
@@ -68,7 +68,7 @@ public:
     void discoverRemoteEnrollee(std::function<void(std::shared_ptr<OC::OCResource> resource)> cb)
     {
         m_discoveryCb = cb;
-        std::string uri = std::string("/oic/res?rt=") + OC_RSRVD_ES_RES_TYPE_PROV;
+        std::string uri = std::string("/oic/res?rt=") + OC_RSRVD_ES_RES_TYPE_EASYSETUP;
         OC::OCPlatform::findResource("", uri,
                 OCConnectivityType::CT_DEFAULT,
                 std::bind(&ESMediatorSimulator::discoverRemoteEnrolleeCb,
@@ -80,7 +80,7 @@ public:
     {
         m_getConfigurationCb = cb;
         m_remoteEnrollee = NULL;
-        std::string uri = std::string("/oic/res?rt=") + OC_RSRVD_ES_RES_TYPE_PROV;
+        std::string uri = std::string("/oic/res?rt=") + OC_RSRVD_ES_RES_TYPE_EASYSETUP;
         OC::OCPlatform::findResource("", uri,
                 OCConnectivityType::CT_DEFAULT,
                 std::bind(&ESMediatorSimulator::discoverRemoteEnrolleeCbToGetConfiguration,
@@ -90,7 +90,7 @@ public:
     void getWifiRsrc(std::function<void(const OCRepresentation& rep)> cb)
     {
         m_getWifiCb = cb;
-        std::string uri = std::string("/oic/res?rt=") + OC_RSRVD_ES_RES_TYPE_WIFI;
+        std::string uri = std::string("/oic/res?rt=") + OC_RSRVD_ES_RES_TYPE_WIFICONF;
         OC::OCPlatform::findResource("", uri,
                 OCConnectivityType::CT_DEFAULT,
                 std::bind(&ESMediatorSimulator::discoverRemoteEnrolleeCbToGetWifiRsrc,
@@ -100,7 +100,7 @@ public:
     void getCloudRsrc(std::function<void(const OCRepresentation& rep)> cb)
     {
         m_getCloudCb = cb;
-        std::string uri = std::string("/oic/res?rt=") + OC_RSRVD_ES_RES_TYPE_CLOUDSERVER;
+        std::string uri = std::string("/oic/res?rt=") + OC_RSRVD_ES_RES_TYPE_COAPCLOUDCONF;
         OC::OCPlatform::findResource("", uri,
                 OCConnectivityType::CT_DEFAULT,
                 std::bind(&ESMediatorSimulator::discoverRemoteEnrolleeCbToGetCloudRsrc,
@@ -121,7 +121,7 @@ public:
     {
         m_getStatusCb = cb;
         m_remoteEnrollee = NULL;
-        std::string uri = std::string("/oic/res?rt=") + OC_RSRVD_ES_RES_TYPE_PROV;
+        std::string uri = std::string("/oic/res?rt=") + OC_RSRVD_ES_RES_TYPE_EASYSETUP;
         OC::OCPlatform::findResource("", uri,
                 OCConnectivityType::CT_DEFAULT,
                 std::bind(&ESMediatorSimulator::discoverRemoteEnrolleeCbToGetStatus,
@@ -132,7 +132,7 @@ public:
     {
         m_DevicePropProvisioningCb = cb;
         m_remoteEnrollee = NULL;
-        std::string uri = std::string("/oic/res?rt=") + OC_RSRVD_ES_RES_TYPE_PROV;
+        std::string uri = std::string("/oic/res?rt=") + OC_RSRVD_ES_RES_TYPE_EASYSETUP;
         OC::OCPlatform::findResource("", uri,
                 OCConnectivityType::CT_DEFAULT,
                 std::bind(&ESMediatorSimulator::discoverRemoteEnrolleeCbToProvisionDeviceProperties,
@@ -143,7 +143,7 @@ public:
     {
         m_CloudPropProvisioningCb = cb;
         m_remoteEnrollee = NULL;
-        std::string uri = std::string("/oic/res?rt=") + OC_RSRVD_ES_RES_TYPE_PROV;
+        std::string uri = std::string("/oic/res?rt=") + OC_RSRVD_ES_RES_TYPE_EASYSETUP;
         OC::OCPlatform::findResource("", uri,
                 OCConnectivityType::CT_DEFAULT,
                 std::bind(&ESMediatorSimulator::discoverRemoteEnrolleeCbToProvisionCloudProperties,
@@ -154,7 +154,7 @@ public:
     {
         m_provPutCb = cb;
         m_remoteEnrollee = NULL;
-        std::string uri = std::string("/oic/res?rt=") + OC_RSRVD_ES_RES_TYPE_PROV;
+        std::string uri = std::string("/oic/res?rt=") + OC_RSRVD_ES_RES_TYPE_EASYSETUP;
         OC::OCPlatform::findResource("", uri,
                 OCConnectivityType::CT_DEFAULT,
                 std::bind(&ESMediatorSimulator::discoverRemoteEnrolleeCbToPutProvRsrc,
@@ -201,7 +201,7 @@ private:
             return ;
         }
 
-        if(!resource->getResourceTypes().at(0).compare(OC_RSRVD_ES_RES_TYPE_PROV) && m_discoveryCb)
+        if(!resource->getResourceTypes().at(0).compare(OC_RSRVD_ES_RES_TYPE_EASYSETUP) && m_discoveryCb)
         {
             m_discoveryCb(resource);
             m_discoveryCb = NULL;
@@ -224,7 +224,7 @@ private:
             return ;
         }
 
-        if(!resource->getResourceTypes().at(0).compare(OC_RSRVD_ES_RES_TYPE_PROV) && m_getConfigurationCb
+        if(!resource->getResourceTypes().at(0).compare(OC_RSRVD_ES_RES_TYPE_EASYSETUP) && m_getConfigurationCb
                                                                            && !m_remoteEnrollee)
         {
             m_remoteEnrollee = EasySetup::getInstance()->createRemoteEnrollee(resource);
@@ -271,7 +271,7 @@ private:
             return ;
         }
 
-        if(!resource->getResourceTypes().at(0).compare(OC_RSRVD_ES_RES_TYPE_WIFI) && m_getWifiCb)
+        if(!resource->getResourceTypes().at(0).compare(OC_RSRVD_ES_RES_TYPE_WIFICONF) && m_getWifiCb)
         {
             QueryParamsMap test;
             resource->get(test, std::bind(
@@ -314,7 +314,7 @@ private:
             return ;
         }
 
-        if(!resource->getResourceTypes().at(0).compare(OC_RSRVD_ES_RES_TYPE_CLOUDSERVER) && m_getCloudCb)
+        if(!resource->getResourceTypes().at(0).compare(OC_RSRVD_ES_RES_TYPE_COAPCLOUDCONF) && m_getCloudCb)
         {
             QueryParamsMap test;
             resource->get(test, std::bind(
@@ -381,7 +381,7 @@ private:
             return ;
         }
 
-        if(!resource->getResourceTypes().at(0).compare(OC_RSRVD_ES_RES_TYPE_PROV) && m_getStatusCb
+        if(!resource->getResourceTypes().at(0).compare(OC_RSRVD_ES_RES_TYPE_EASYSETUP) && m_getStatusCb
                                                                             && !m_remoteEnrollee)
         {
             m_remoteEnrollee = EasySetup::getInstance()->createRemoteEnrollee(resource);
@@ -411,7 +411,7 @@ private:
             return ;
         }
 
-        if(!resource->getResourceTypes().at(0).compare(OC_RSRVD_ES_RES_TYPE_PROV) &&
+        if(!resource->getResourceTypes().at(0).compare(OC_RSRVD_ES_RES_TYPE_EASYSETUP) &&
                                                 m_DevicePropProvisioningCb && !m_remoteEnrollee)
         {
             m_remoteEnrollee = EasySetup::getInstance()->createRemoteEnrollee(resource);
@@ -420,7 +420,6 @@ private:
             {
                 DeviceProp devProp;
                 devProp.setWiFiProp("Iotivity_SSID", "Iotivity_PWD", WPA2_PSK, TKIP_AES);
-                devProp.setDevConfProp("korean", "Korea", "Location");
 
                 m_remoteEnrollee->provisionDeviceProperties(devProp,
                     std::bind(&ESMediatorSimulator::deviceProvisioningStatusCallback,
@@ -449,7 +448,7 @@ private:
             return ;
         }
 
-        if(!resource->getResourceTypes().at(0).compare(OC_RSRVD_ES_RES_TYPE_PROV) &&
+        if(!resource->getResourceTypes().at(0).compare(OC_RSRVD_ES_RES_TYPE_EASYSETUP) &&
                                                 m_CloudPropProvisioningCb && !m_remoteEnrollee)
         {
             m_remoteEnrollee = EasySetup::getInstance()->createRemoteEnrollee(resource);
index c350109..e46664b 100755 (executable)
@@ -36,9 +36,10 @@ extern "C"
 
 
 
-#define OIC_STRING_MAX_VALUE    64
+#define OIC_STRING_MAX_VALUE    256
 #define MAX_WEBLINKLEN          3
-#define NUM_WIFIMODE            5
+#define NUM_WIFIMODE            10
+#define NUM_CONNECT_TYPE        3
 
 /**
  * Attributes used to form a proper easysetup conforming JSON message.
@@ -53,27 +54,26 @@ extern "C"
 #define OC_RSRVD_ES_AUTHTYPE               "wat"
 #define OC_RSRVD_ES_ENCTYPE                "wet"
 #define OC_RSRVD_ES_AUTHCODE               "ac"
+#define OC_RSRVD_ES_ACCESSTOKEN            "at"
+#define OC_RSRVD_ES_ACCESSTOKEN_TYPE       "att"
 #define OC_RSRVD_ES_AUTHPROVIDER           "apn"
 #define OC_RSRVD_ES_CISERVER               "cis"
 #define OC_RSRVD_ES_SERVERID               "sid"
 #define OC_RSRVD_ES_DEVNAME                "dn"
-#define OC_RSRVD_ES_LANGUAGE               "lang"
-#define OC_RSRVD_ES_COUNTRY                "ctry"
-#define OC_RSRVD_ES_MODELNUMBER            "mnmo"
-#define OC_RSRVD_ES_LOCATION               "loc"
 #define OC_RSRVD_ES_HREF                   "href"
+#define OC_RSRVD_ES_CONNECT                "cn"
 
 /**
  * Easysetup defined resoruce types and uris.
  */
-#define OC_RSRVD_ES_RES_TYPE_PROV         "oic.wk.prov"
-#define OC_RSRVD_ES_URI_PROV              "/ProvisioningResURI"
-#define OC_RSRVD_ES_RES_TYPE_WIFI         "oic.wk.wifi"
-#define OC_RSRVD_ES_URI_WIFI              "/WiFiProvisioningResURI"
-#define OC_RSRVD_ES_RES_TYPE_CLOUDSERVER  "oic.wk.cloudserver"
-#define OC_RSRVD_ES_URI_CLOUDSERVER       "/CloudServerProvisioningResURI"
-#define OC_RSRVD_ES_RES_TYPE_DEVCONF      "oic.wk.devconf"
-#define OC_RSRVD_ES_URI_DEVCONF           "/DevConfProvisioningResURI"
+#define OC_RSRVD_ES_RES_TYPE_EASYSETUP          "oic.r.easysetup"
+#define OC_RSRVD_ES_URI_EASYSETUP               "/EasySetupResURI"
+#define OC_RSRVD_ES_RES_TYPE_WIFICONF           "oic.r.wificonf"
+#define OC_RSRVD_ES_URI_WIFICONF                "/WiFiConfResURI"
+#define OC_RSRVD_ES_RES_TYPE_COAPCLOUDCONF      "oic.r.coapcloudconf"
+#define OC_RSRVD_ES_URI_COAPCLOUDCONF           "/CoapCloudConfResURI"
+#define OC_RSRVD_ES_RES_TYPE_DEVCONF            "oic.r.devconf"
+#define OC_RSRVD_ES_URI_DEVCONF                 "/DevConfResURI"
 
 
 /**
@@ -126,6 +126,26 @@ typedef enum
 } WIFI_ENCTYPE;
 
 /**
+ * @brief OAuth Access Token Types. "bearer" and "mac" types are supported.
+ */
+typedef enum
+{
+    NONE_OAUTH_TOKENTYPE = 0,
+    OAUTH_TOKENTYPE_BEARER,
+    OAUTH_TOKENTYPE_MAC
+} OAUTH_TOKENTYPE;
+
+/**
+ * @brief  A target configuration type to be connected (or executed)
+ */
+typedef enum
+{
+    ES_CONNECT_NONE = 0,        /**< Init value **/
+    ES_CONNECT_WIFI = 1,        /**< WiFi Conf resource **/
+    ES_CONNECT_COAPCLOUD = 2    /**< Coap Cloud Conf resource **/
+} ES_CONNECT_TYPE;
+
+/**
  * @brief A result of Easy Setup
  */
 typedef enum
@@ -136,6 +156,11 @@ typedef enum
     ES_OK = 0,
 
     /**
+     * Secure resource is discovered.
+     */
+    ES_SECURE_RESOURCE_IS_DISCOVERED = 1,
+
+    /**
      * Enrollee discovery fails in cloud provisioning
      */
     ES_ENROLLEE_DISCOVERY_FAILURE = 11,
@@ -149,7 +174,7 @@ typedef enum
     /**
      * Security opertion is not supported because Mediator is built as unsecured mode.
      */
-    ES_SEC_OPERATION_IS_NOT_SUPPORTED = 20,
+    ES_SEC_OPERATION_IS_NOT_SUPPORTED,
 
     /**
      * Security resource discovery fails due to loss of discovery packet or absence of the resource in a network
@@ -157,16 +182,81 @@ typedef enum
     ES_SECURE_RESOURCE_DISCOVERY_FAILURE,
 
     /**
-     * Ownership transfer fails because DTLS handshake failure happens
+     * Ownership transfer fails due to one of unexpected reasons.
+     * E.g. A packet loss even with retransmission happens during ownership transfer.
+     * E.g. Mediator's owned status is 'unowned'
+     * E.g. A user confirmation for random pin-based or certificate-based OT fails
+     */
+    ES_OWNERSHIP_TRANSFER_FAILURE = 20,
+
+    /**
+     * Ownership transfer which is cert-based method fails due to user confirmation is denied.
      */
-    ES_OWNERSHIP_TRANSFER_FAILURE,
+    ES_USER_DENIED_CONFIRMATION_REQ,
+
+    /**
+     * Ownership transfer which is cert-based method fails due to wrong certificate.
+     */
+    ES_AUTHENTICATION_FAILURE_WITH_WRONG_CERT,
+
+    /**
+     * Ownership transfer which is random-pin method fails due to wrong pin.
+     */
+    ES_AUTHENTICATION_FAILURE_WITH_WRONG_PIN,
+
+    /**
+     * Ownership information is not synchronized between Mediator and Enrollee.
+     * e.g. A mediator's PDM DB has an ownership information to the found enrollee
+     *      but it is actually owned by other mediator.
+     *      That can happen where the found enrollee is reset and performed in easy setup without any inform to the first mediator.
+     * e.g. A list of owned devices managed in mediator's PMD db has no element for the found enrollee.
+     *      That can happen where only mediator is reset without any inform to the enrollee.
+     * To proceed an ownership transfer to the enrollee, it needs to reset the enrollee's SVR DB for its owner, i.e. the mediator
+     */
+    ES_OWNERSHIP_IS_NOT_SYNCHRONIZED,
+
+    /**
+     * MOT is not supported at the target Enrollee device.
+     *
+     * @note This ESResult values will be returned ONLY IF a mediator is a first owner to an Enrollee.
+     * @note If the mediator gets this values, it means OT has been successfully done
+     * (or already took an ownership, before), but failed MOT configuration.
+     */
+    ES_MOT_NOT_SUPPORTED = 30,
+
+    /**
+     * MOT enabling is failed.
+     *
+     * @note This ESResult values will be returned ONLY IF a mediator is a first owner to an Enrollee.
+     * @note If the mediator gets this values, it means OT has been successfully done
+     * (or already took an ownership, before), but failed MOT configuration.
+     */
+    ES_MOT_ENABLING_FAILURE,
+
+    /**
+     * MOT method selection is failed
+     *
+     * @note This ESResult values will be returned ONLY IF a mediator is a first owner to an Enrollee.
+     * @note If the mediator gets this values, it means OT has been successfully done
+     * (or already took an ownership, before), but failed MOT configuration.
+     */
+    ES_MOT_METHOD_SELECTION_FAILURE,
+
+    /**
+     * A provisioning of Pre-configured pin number for MOT is failed
+     *
+     * @note This ESResult values will be returned ONLY IF a mediator is a first owner to an Enrollee.
+     * @note If the mediator gets this values, it means OT has been successfully done
+     * (or already took an ownership, before), but failed MOT configuration.
+     */
+    ES_PRE_CONFIG_PIN_PROVISIONING_FAILURE,
 
     /**
      * ACL provisioning fails in cloud provisioning.
      * It could be that UUID format of cloud server is wrong.
      * Or any response for the provisioning request is not arrived at Mediator
      */
-    ES_ACL_PROVISIONING_FAILURE,
+    ES_ACL_PROVISIONING_FAILURE = 40,
 
     /**
      * Cert. provisioning fails in cloud provisioning.
@@ -178,6 +268,7 @@ typedef enum
     /**
      * Provisioning fails for some reason.
      */
+
     ES_ERROR = 255
 } ESResult;
 
@@ -186,14 +277,14 @@ typedef enum
  */
 typedef enum
 {
-    ES_WIFI_RESOURCE = 0x01,
-    ES_CLOUD_RESOURCE = 0x02,
+    ES_WIFICONF_RESOURCE = 0x01,
+    ES_COAPCLOUDCONF_RESOURCE = 0x02,
     ES_DEVCONF_RESOURCE = 0x04
 } ESResourceMask;
 
 /**
  * @brief Indicate enrollee and provisioning status. Provisioning status is shown in "provisioning
- *        status" property in provisioning resource.
+ *        status" property in easysetup resource.
  */
 typedef enum
 {
@@ -324,6 +415,12 @@ typedef enum
     ES_ERRCODE_FAILED_TO_FIND_REGISTERED_USER_IN_CLOUD,
 
     /**
+     * Error Code that an enrollee can not connect to a target WiFi AP because the AP resides in
+     * an unsupported WiFi frequency.
+     */
+    ES_ERRCODE_UNSUPPORTED_WIFI_FREQUENCY,
+
+    /**
      * Error Code that Unknown error occured
      */
     ES_ERRCODE_UNKNOWN = 255
old mode 100644 (file)
new mode 100755 (executable)
index b428dde..eaf5422
@@ -81,16 +81,15 @@ if target_os in ['linux', 'tizen']:
        easy_setup_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
        easy_setup_env.AppendUnique(RPATH = [env.get('BUILD_DIR')])
        easy_setup_env.AppendUnique(CXXFLAGS = ['-pthread'])
-       easy_setup_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger'])
+       easy_setup_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'connectivity_abstraction'])
        if env.get('SECURED') == '1':
                easy_setup_env.AppendUnique(LIBS = ['ocpmapi', 'ocprovision'])
 
-if target_os in ['android','ios','linux','tizen']:
+if target_os in ['android','linux','ios','tizen']:
        easy_setup_env.PrependUnique(CPPPATH = [
                env.get('SRC_DIR') + '/resource/c_common/oic_malloc/include',
                env.get('SRC_DIR') + '/resource/include',
                env.get('SRC_DIR') + '/resource/csdk/logger/include',
-               env.get('SRC_DIR') + '/resource/csdk/include',
                env.get('SRC_DIR') + '/resource/csdk/stack/include',
                env.get('SRC_DIR') + '/resource/csdk/logger/include',
                env.get('SRC_DIR') + '/resource/csdk/security/include',
@@ -162,17 +161,19 @@ if target_os in ['android']:
 ######################################################################
 # Build RichSDK Mediator Sample App
 ################################################ ######################
-if target_os in ['linux']:
-       SConscript('../../sampleapp/mediator/linux/richsdk_sample/SConscript')
+#if target_os in ['linux']:
+#    SConscript('../../sampleapp/mediator/linux/richsdk_sample/SConscript')
+#      SConscript('../../sampleapp/mediator/linux-samsung/richsdk_sample/SConscript')
 
-if target_os in ['android']:
-       SConscript('../../sampleapp/mediator/android/SConscript')
+#if target_os in ['android']:
+#      SConscript('../../sampleapp/mediator/android/SConscript')
+#      SConscript('../../sampleapp/mediator/android-samsung/SConscript')
 
 
 ######################################################################
 #Build UnitTestcases for Mediator[RichSDK]
 ################################################ ######################
-if env.get('SECURED') == '0':
-   if target_os == 'linux':
-       SConscript('unittests/SConscript')
+#if env.get('SECURED') == '0':
+#   if target_os == 'linux':
+#       SConscript('unittests/SConscript')
 
index 008828c..22a2acb 100755 (executable)
@@ -22,6 +22,8 @@ package org.iotivity.service.easysetup.mediator;
 
 import android.util.Log;
 
+import org.iotivity.service.easysetup.mediator.enums.OAUTH_TOKENTYPE;
+
 import org.iotivity.base.OcException;
 import org.iotivity.base.OcRepresentation;
 
@@ -65,6 +67,31 @@ public class CloudProp {
         }
     }
 
+    public void setCloudPropWithAccessToken(String accessToken, OAUTH_TOKENTYPE tokenType,
+                                        String authProvider, String ciServer)
+    {
+        if(accessToken == null)
+        {
+            accessToken = "";
+        }
+        if(authProvider == null)
+        {
+            authProvider = "";
+        }
+        if(ciServer == null)
+        {
+            ciServer = "";
+        }
+        try {
+            mRep.setValue(ESConstants.OC_RSRVD_ES_ACCESSTOKEN, accessToken);
+            mRep.setValue(ESConstants.OC_RSRVD_ES_ACCESSTOKEN_TYPE, tokenType.getValue());
+            mRep.setValue(ESConstants.OC_RSRVD_ES_AUTHPROVIDER, authProvider);
+            mRep.setValue(ESConstants.OC_RSRVD_ES_CISERVER, ciServer);
+        } catch (OcException e) {
+            Log.e(TAG, "setCloudPropWithAccessToken is failed.");
+        }
+    }
+
     public void setCloudID(String cloudID)
     {
         mCloudID = cloudID;
@@ -161,6 +188,52 @@ public class CloudProp {
         return mCredID;
     }
 
+    /**
+     * This method returns an accessToken used for the first registration to IoTivity cloud
+     * @return accessToken for sign-up to IoTivity cloud
+     */
+    public String getAccessToken()
+    {
+        if(mRep == null)
+        {
+            return null;
+        }
+
+        try
+        {
+            if (mRep.hasAttribute(ESConstants.OC_RSRVD_ES_ACCESSTOKEN))
+                return mRep.getValue(ESConstants.OC_RSRVD_ES_ACCESSTOKEN);
+        }
+        catch (OcException e)
+        {
+            Log.e(TAG, "getAccessToken is failed.");
+        }
+        return null;
+    }
+
+    /**
+     * This method returns an access token type
+     * @return tokenType of access token
+     */
+    public OAUTH_TOKENTYPE getAccessTokenType()
+    {
+        if(mRep == null)
+        {
+            return null;
+        }
+
+        try
+        {
+            if (mRep.hasAttribute(ESConstants.OC_RSRVD_ES_ACCESSTOKEN_TYPE))
+                return OAUTH_TOKENTYPE.fromInt((int)mRep.getValue(ESConstants.OC_RSRVD_ES_ACCESSTOKEN_TYPE));
+        }
+        catch (OcException e)
+        {
+            Log.e(TAG, "getAccessTokenType is failed.");
+        }
+        return OAUTH_TOKENTYPE.NONE_OAUTH_TOKENTYPE;
+    }
+
     public OcRepresentation toOCRepresentation()
     {
         return mRep;
index b023d6c..8463bc5 100755 (executable)
@@ -34,6 +34,8 @@ public class ESConstants {
     public static final String OC_RSRVD_ES_AUTHTYPE = "wat";
     public static final String OC_RSRVD_ES_ENCTYPE = "wet";
     public static final String OC_RSRVD_ES_AUTHCODE = "ac";
+    public static final String OC_RSRVD_ES_ACCESSTOKEN = "at";
+    public static final String OC_RSRVD_ES_ACCESSTOKEN_TYPE = "att";
     public static final String OC_RSRVD_ES_AUTHPROVIDER = "apn";
     public static final String OC_RSRVD_ES_CISERVER = "cis";
     public static final String OC_RSRVD_ES_SERVERID = "sid";
@@ -43,16 +45,21 @@ public class ESConstants {
     public static final String OC_RSRVD_ES_MODELNUMBER = "mnmo";
     public static final String OC_RSRVD_ES_LOCATION = "loc";
 
+    public static final String OC_RSRVD_ES_VENDOR_DEVTYPE = "x.com.samsung.dt";
+    public static final String OC_RSRVD_ES_VENDOR_DEVSUBTYPE = "x.com.samsung.sdt";
+    public static final String OC_RSRVD_ES_VENDOR_DISCOVERYCHANNEL = "x.com.samsung.chn";
+    public static final String SC_RSRVD_ES_VENDOR_LOCATION = "x.com.samsung.location";
+
 /**
 * Easysetup defined resoruce types and uris
 */
-    public static final String OC_RSRVD_ES_RES_TYPE_PROV = "oic.wk.prov";
-    public static final String OC_RSRVD_ES_URI_PROV = "/ProvisioningResURI";
-    public static final String OC_RSRVD_ES_RES_TYPE_WIFI = "oic.wk.wifi";
-    public static final String OC_RSRVD_ES_URI_WIFI = "/WiFiProvisioningResURI";
-    public static final String OC_RSRVD_ES_RES_TYPE_CLOUDSERVER = "oic.wk.cloudserver";
-    public static final String OC_RSRVD_ES_URI_CLOUDSERVER = "/CloudServerProvisioningResURI";
-    public static final String OC_RSRVD_ES_RES_TYPE_DEVCONF = "oic.wk.devconf";
-    public static final String OC_RSRVD_ES_URI_DEVCONF = "/DevConfProvisioningResURI";
+    public static final String OC_RSRVD_ES_RES_TYPE_EASYSETUP = "oic.r.easysetup";
+    public static final String OC_RSRVD_ES_URI_EASYSETUP = "/EasySetupResURI";
+    public static final String OC_RSRVD_ES_RES_TYPE_WIFICONF = "oic.r.wificonf";
+    public static final String OC_RSRVD_ES_URI_WIFICONF = "/WiFiConfResURI";
+    public static final String OC_RSRVD_ES_RES_TYPE_COAPCLOUDCONF = "oic.r.coapcloudconf";
+    public static final String OC_RSRVD_ES_URI_COAPCLOUDCONF = "/CoapCloudConfResURI";
+    public static final String OC_RSRVD_ES_RES_TYPE_DEVCONF = "oic.r.devconf";
+    public static final String OC_RSRVD_ES_URI_DEVCONF = "/DevConfResURI";
 
 }
index 5cea6d0..cece024 100755 (executable)
@@ -87,7 +87,7 @@ public class EasySetup {
      *        discovered in a network. The OcResource object can be obtained by calling
      *        OcPlatform.findResource() API. What resource you have to discover with
      *        the OcPlatform.findResource() API is a "provisioning" resource with a certain
-     *        resource type, i.e. oic.wk.prov
+     *        resource type, i.e. oic.r.easysetup
      *
      * @return Pointer to RemoteEnrollee instance
      */
index becbe52..fa4cfb2 100755 (executable)
@@ -39,7 +39,7 @@ import java.util.List;
 public class EnrolleeConf
 {
     private static final String TAG = EnrolleeConf.class.getName();
-    protected OcRepresentation mProvRep = null;
+    protected OcRepresentation mEasySetupRep = null;
     /**
      * Constructor
      *
@@ -48,12 +48,12 @@ public class EnrolleeConf
      */
     public EnrolleeConf(OcRepresentation rep)
     {
-        mProvRep = rep;
+        mEasySetupRep = rep;
     }
 
     public EnrolleeConf(EnrolleeConf enrolleeConf)
     {
-        mProvRep = enrolleeConf.getProvResRep();
+        mEasySetupRep = enrolleeConf.getEasySetupRep();
     }
 
     /**
@@ -63,12 +63,12 @@ public class EnrolleeConf
      */
     public String getDeviceName()
     {
-        if(mProvRep == null)
+        if(mEasySetupRep == null)
         {
             return null;
         }
 
-        List<OcRepresentation> children = mProvRep.getChildren();
+        List<OcRepresentation> children = mEasySetupRep.getChildren();
 
         for (OcRepresentation child : children) {
             if(child.getUri().indexOf(ESConstants.OC_RSRVD_ES_URI_DEVCONF) != -1)
@@ -103,12 +103,12 @@ public class EnrolleeConf
      */
     public String getModelNumber()
     {
-        if(mProvRep == null)
+        if(mEasySetupRep == null)
         {
             return null;
         }
 
-        List<OcRepresentation> children = mProvRep.getChildren();
+        List<OcRepresentation> children = mEasySetupRep.getChildren();
 
         for (OcRepresentation child : children) {
             if(child.getUri().indexOf(ESConstants.OC_RSRVD_ES_URI_DEVCONF) != -1)
@@ -143,15 +143,15 @@ public class EnrolleeConf
      */
     public ArrayList<WIFI_MODE> getWiFiModes()
     {
-        if(mProvRep == null)
+        if(mEasySetupRep == null)
         {
             return null;
         }
 
-        List<OcRepresentation> children = mProvRep.getChildren();
+        List<OcRepresentation> children = mEasySetupRep.getChildren();
         ArrayList<WIFI_MODE> modes = new ArrayList<WIFI_MODE>();
         for (OcRepresentation child : children) {
-            if(child.getUri().indexOf(ESConstants.OC_RSRVD_ES_URI_WIFI) != -1)
+            if(child.getUri().indexOf(ESConstants.OC_RSRVD_ES_URI_WIFICONF) != -1)
             {
                 try {
                     OcRepresentation rep;
@@ -185,15 +185,15 @@ public class EnrolleeConf
      */
     public WIFI_FREQ getWiFiFreq()
     {
-        if(mProvRep == null)
+        if(mEasySetupRep == null)
         {
             return WIFI_FREQ.WIFI_FREQ_NONE;
         }
 
-        List<OcRepresentation> children = mProvRep.getChildren();
+        List<OcRepresentation> children = mEasySetupRep.getChildren();
 
         for (OcRepresentation child : children) {
-            if(child.getUri().indexOf(ESConstants.OC_RSRVD_ES_URI_WIFI) != -1)
+            if(child.getUri().indexOf(ESConstants.OC_RSRVD_ES_URI_WIFICONF) != -1)
             {
                 try{
                     OcRepresentation rep;
@@ -225,15 +225,15 @@ public class EnrolleeConf
      */
     public boolean isCloudAccessible()
     {
-        if(mProvRep == null)
+        if(mEasySetupRep == null)
         {
             return false;
         }
 
-        List<OcRepresentation> children = mProvRep.getChildren();
+        List<OcRepresentation> children = mEasySetupRep.getChildren();
 
         for (OcRepresentation child : children) {
-            if(child.getUri().indexOf(ESConstants.OC_RSRVD_ES_URI_CLOUDSERVER) != -1)
+            if(child.getUri().indexOf(ESConstants.OC_RSRVD_ES_URI_COAPCLOUDCONF) != -1)
             {
                 return true;
             }
@@ -241,9 +241,9 @@ public class EnrolleeConf
         return false;
     }
 
-    public  OcRepresentation getProvResRep()
+    public  OcRepresentation getEasySetupRep()
     {
-        return mProvRep;
+        return mEasySetupRep;
     }
 }
 
index 913924c..d94edf2 100755 (executable)
@@ -91,6 +91,12 @@ public enum ESErrorCode {
     ES_ERRCODE_FAILED_TO_FIND_REGISTERED_USER_IN_CLOUD(12),
 
     /**
+     * Error Code that an enrollee can not connect to a target WiFi AP because the AP resides in
+     * an unsupported WiFi frequency.
+     */
+    ES_ERRCODE_UNSUPPORTED_WIFI_FREQUENCY(13),
+
+    /**
      * Error Code that Unknown error occured
      */
     ES_ERRCODE_UNKNOWN(255);
diff --git a/service/easy-setup/mediator/richsdk/android/EasySetupCore/src/main/java/org/iotivity/service/easysetup/mediator/enums/OAUTH_TOKENTYPE.java b/service/easy-setup/mediator/richsdk/android/EasySetupCore/src/main/java/org/iotivity/service/easysetup/mediator/enums/OAUTH_TOKENTYPE.java
new file mode 100755 (executable)
index 0000000..70dc519
--- /dev/null
@@ -0,0 +1,66 @@
+/**
+ * ***************************************************************
+ *
+ * Copyright 2016 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.
+ *
+ * ****************************************************************
+ */
+
+package org.iotivity.service.easysetup.mediator.enums;
+
+/**
+ * This enum class indicates an OAuth Token type like "bearer" and "mac"\r
+ */
+public enum OAUTH_TOKENTYPE\r
+{
+    NONE_OAUTH_TOKENTYPE(0),\r
+    OAUTH_TOKENTYPE_BEARER(1),\r
+    OAUTH_TOKENTYPE_MAC(2);\r
+\r
+    private int value;
+
+    private OAUTH_TOKENTYPE(int value)\r
+    {
+        this.value = value;
+    }
+
+    /**
+     * Get OAuth Token type as an integer value\r
+     *
+     * @return int OAuth Token type as an integer value\r
+     */
+    public int getValue()
+    {
+        return value;
+    }
+
+    /**
+     * Get OAuth Token type as OAUTH_TOKENTYPE type value\r
+     *
+     * @return OAuth Token type enum value corresponding to its integer value\r
+     */
+    public static OAUTH_TOKENTYPE fromInt(int i)\r
+    {
+        for (OAUTH_TOKENTYPE b : OAUTH_TOKENTYPE.values())\r
+        {
+            if (b.getValue() == i)
+                return b;
+        }
+        return null;
+    }
+}
+\r
diff --git a/service/easy-setup/mediator/richsdk/android/EasySetupCore/src/main/java/org/iotivity/service/easysetup/mediator/samsung/SCDeviceProp.java b/service/easy-setup/mediator/richsdk/android/EasySetupCore/src/main/java/org/iotivity/service/easysetup/mediator/samsung/SCDeviceProp.java
new file mode 100755 (executable)
index 0000000..31b273b
--- /dev/null
@@ -0,0 +1,87 @@
+/**
+ * ***************************************************************
+ *
+ * Copyright 2016 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.
+ *
+ * ****************************************************************
+ */
+
+package org.iotivity.service.easysetup.mediator.samsung;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import android.util.Log;
+
+import org.iotivity.service.easysetup.mediator.DeviceProp;
+import org.iotivity.service.easysetup.mediator.ESConstants;
+import org.iotivity.service.easysetup.mediator.enums.WIFI_AUTHTYPE;
+import org.iotivity.service.easysetup.mediator.enums.WIFI_ENCTYPE;
+
+import org.iotivity.base.OcException;
+import org.iotivity.base.OcRepresentation;
+
+/**
+ * This class contains device properties to be delivered to Enrollee
+ */
+public class SCDeviceProp extends DeviceProp {
+    private static final String TAG = SCDeviceProp.class.getName();
+    final int INVALID_DISCOVERY_CHANNEL = -1;
+
+    /**
+     * Set Channel of Enroller for fast discover
+     */
+    public void setDiscoveryChannel(int discoveryChannel)
+    {
+        try
+        {
+            mRep.setValue(ESConstants.OC_RSRVD_ES_VENDOR_DISCOVERYCHANNEL, discoveryChannel);
+        } catch (OcException e) {
+            Log.e(TAG, "setDiscoveryChannel is failed.");
+        }
+    }
+
+    /**
+     * Get Channel of Enroller for fast discover
+     *
+     * @return int Enroller's DiscoveryChannel
+     */
+    public int getDiscoveryChannel()
+    {
+        try {
+            if(mRep.hasAttribute(ESConstants.OC_RSRVD_ES_VENDOR_DISCOVERYCHANNEL))
+                return mRep.getValue(ESConstants.OC_RSRVD_ES_VENDOR_DISCOVERYCHANNEL);
+        } catch (OcException e) {
+            Log.e(TAG, "getDiscoveryChannel is failed.");
+        }
+        return INVALID_DISCOVERY_CHANNEL;
+    }
+
+     /**
+     * Set samsung-specific location property to be delivered to Enrollee
+     *
+     * @param locations a set of location information
+     */
+    public void setSCLocation(ArrayList<String> locations)
+    {
+        try
+        {
+            mRep.setValue(ESConstants.SC_RSRVD_ES_VENDOR_LOCATION, locations.toArray(new
+            String[locations.size()]));
+        } catch (OcException e) {
+            Log.e(TAG, "setSCLocation is failed.");
+        }
+    }
+}
diff --git a/service/easy-setup/mediator/richsdk/android/EasySetupCore/src/main/java/org/iotivity/service/easysetup/mediator/samsung/SCEnrolleeConf.java b/service/easy-setup/mediator/richsdk/android/EasySetupCore/src/main/java/org/iotivity/service/easysetup/mediator/samsung/SCEnrolleeConf.java
new file mode 100755 (executable)
index 0000000..2ec3bd4
--- /dev/null
@@ -0,0 +1,100 @@
+/**
+ * ***************************************************************
+ *
+ * Copyright 2016 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.
+ *
+ * ****************************************************************
+ */
+
+package org.iotivity.service.easysetup.mediator.samsung;
+
+import android.util.Log;
+
+import org.iotivity.base.OcException;
+import org.iotivity.base.OcRepresentation;
+import org.iotivity.service.easysetup.mediator.ESConstants;
+import org.iotivity.service.easysetup.mediator.EnrolleeConf;
+
+import java.util.List;
+
+/**
+ * This class stores Enrollee's configuration including WiFi and Device configuration
+ * including supported WiFi frequency and device name
+ */
+public class SCEnrolleeConf extends EnrolleeConf
+{
+    private static final String TAG = SCEnrolleeConf.class.getName();
+
+    /**
+     * Constructor
+     *
+     * @param rep received properties in a form of OcRepresentation
+     */
+    public SCEnrolleeConf(EnrolleeConf enrolleeConf) {
+        super(enrolleeConf);
+    }
+
+    /**
+     * Get Device type property in DevConf resource
+     *
+     * @return device type
+     */
+    public String getDeviceType()
+    {
+        List<OcRepresentation> children = mEasySetupRep.getChildren();
+
+        for (OcRepresentation child : children) {
+            if(child.getUri().indexOf(ESConstants.OC_RSRVD_ES_URI_DEVCONF) != -1)
+            {
+                try
+                {
+                    if(child.hasAttribute(ESConstants.OC_RSRVD_ES_VENDOR_DEVTYPE)) {
+                        return (String) child.getValue(ESConstants.OC_RSRVD_ES_VENDOR_DEVTYPE);
+                    }
+                } catch (OcException e) {
+                    Log.e(TAG, "getDeviceType is failed.");
+                }
+            }
+        }
+        return new String("");
+    }
+
+    /**
+     * Get Device sub-type property in DevConf resource
+     *
+     * @return device sub-type
+     */
+    public String getDeviceSubType()
+    {
+        List<OcRepresentation> children = mEasySetupRep.getChildren();
+
+        for (OcRepresentation child : children) {
+            if(child.getUri().indexOf(ESConstants.OC_RSRVD_ES_URI_DEVCONF) != -1)
+            {
+                try
+                {
+                    if(child.hasAttribute(ESConstants.OC_RSRVD_ES_VENDOR_DEVSUBTYPE)) {
+                        return (String) child.getValue(ESConstants.OC_RSRVD_ES_VENDOR_DEVSUBTYPE);
+                    }
+                } catch (OcException e) {
+                    Log.e(TAG, "getDeviceType is failed.");
+                }
+            }
+        }
+        return new String("");
+    }
+}
+
+
index e9cebf6..4332919 100755 (executable)
@@ -40,8 +40,8 @@ Java_org_iotivity_service_easysetup_mediator_EasySetup_nativeCreateRemoteEnrolle
 {
     ES_LOGI("JniEasySetup::nativeCreateRemoteEnrollee enter");
 
-    std::shared_ptr<RemoteEnrollee> nativeRemoteEnrollee;
-    jobject jRemoteEnrollee;
+    std::shared_ptr<RemoteEnrollee> nativeRemoteEnrollee = NULL;
+    jobject jRemoteEnrollee = NULL;
 
     if(!jResource)
     {
index 98daf1d..bd7021f 100755 (executable)
@@ -74,13 +74,14 @@ class JniEsListenerManager
                     m_listenerMap.insert(
                         std::pair < jobject,
                         std::pair<T *, int >> (jgListener, std::pair<T *, int>(onEventListener, 1)));
+                    ES_LOGD("OnEventListener: new listener");
                 }
                 else
                 {
                     ES_LOGD("OnEventListener: Failed to create global listener ref.");
                     delete onEventListener;
+                    onEventListener = NULL;
                 }
-                ES_LOGD("OnEventListener: new listener");
             }
             m_mapMutex.unlock();
             return onEventListener;
index ac02811..3de688e 100755 (executable)
@@ -81,7 +81,7 @@ void JniGetConfigurationStatusListener::getConfigurationStatusCallback (
     }
 
     EnrolleeConf enrolleeConf = getConfigurationStatusCb->getEnrolleeConf();
-    OCRepresentation m_ProvRep = enrolleeConf.getProvResRep();
+    OCRepresentation m_ProvRep = enrolleeConf.getEasySetupRep();
 
     OCRepresentation* rep = new OCRepresentation(m_ProvRep);
     jlong handle = reinterpret_cast<jlong>(rep);
index 41fc10c..48584d1 100755 (executable)
 #include "OCPlatform.h"
 #include "ocstack.h"
 #include "octypes.h"
+#ifdef __WITH_DTLS__
+#include "securevirtualresourcetypes.h"
+#include "OCProvisioningManager.hpp"
+#include "ocrandom.h"
+#endif
 
 #include "escommon.h"
 
@@ -43,7 +48,7 @@ namespace OIC
     namespace Service
     {
         /**
-         * @brief Properties of provisioning resource. It includes a provisioning status and last
+         * @brief Properties of easysetup resource. It includes a provisioning status and last
          *        error code.
          */
         class EnrolleeStatus
@@ -73,7 +78,7 @@ namespace OIC
              *
              * @return a provisioning status property of Enrollee
              */
-            ProvStatus getProvStatus()
+            ProvStatus getProvStatus() const
             {
                 if(m_rep.hasAttribute(OC_RSRVD_ES_PROVSTATUS))
                 {
@@ -88,7 +93,7 @@ namespace OIC
              *
              * @return a last error code property of Enrollee.
              */
-            ESErrorCode getLastErrCode()
+            ESErrorCode getLastErrCode() const
             {
                 if(m_rep.hasAttribute(OC_RSRVD_ES_LAST_ERRORCODE))
                 {
@@ -112,7 +117,7 @@ namespace OIC
         };
 
         /**
-         * @brief Data class stored for Cloud server property provisioning
+         * @brief Data class stored for provisioning of coap cloud server properties
          */
         class CloudProp
         {
@@ -152,7 +157,7 @@ namespace OIC
             }
 
             /**
-             * Set CloudServer resource properties to be delivered to Enrollee
+             * Set CoapCloudConf resource properties to be delivered to Enrollee
              *
              * @param authCode  Auth code issued by OAuth2.0-compatible account server
              * @param authProvider Auth provider ID
@@ -166,6 +171,26 @@ namespace OIC
             }
 
             /**
+             * Set CoapCloudConf resource properties with Access token to be delivered to Enrollee
+             *
+             * @param accessToken  Access token which is given in a return of auth code issued by
+             *                     OAuth2.0-compatible account server
+             * @param tokenType Access token type, i.e. "bearer"
+             * @param authProvider Auth provider ID
+             * @param ciServer Cloud interface server URL which an Enrollee is going to registered
+             *
+             * @see OAUTH_TOKENTYPE
+             */
+            void setCloudPropWithAccessToken(string accessToken, OAUTH_TOKENTYPE tokenType,
+                                                string authProvider, string ciServer)
+            {
+                m_rep.setValue(OC_RSRVD_ES_ACCESSTOKEN, accessToken);
+                m_rep.setValue(OC_RSRVD_ES_ACCESSTOKEN_TYPE, tokenType);
+                m_rep.setValue(OC_RSRVD_ES_AUTHPROVIDER, authProvider);
+                m_rep.setValue(OC_RSRVD_ES_CISERVER, ciServer);
+            }
+
+            /**
              * Set CloudServer's UUID
              *
              * @param cloudID Cloud Interface server's UUID
@@ -248,6 +273,36 @@ namespace OIC
             }
 
             /**
+             * Get an access token to be delivered.
+             *
+             * @return an access token to be delivered.
+             */
+            std::string getAccessToken() const
+            {
+                if(m_rep.hasAttribute(OC_RSRVD_ES_ACCESSTOKEN))
+                {
+                    return m_rep.getValue<std::string>(OC_RSRVD_ES_ACCESSTOKEN);
+                }
+                return std::string("");
+            }
+
+            /**
+             * Get an access token type to be delivered.
+             *
+             * @return an access token type to be delivered.
+             */
+            OAUTH_TOKENTYPE getAccessTokenType() const
+            {
+
+                if(m_rep.hasAttribute(OC_RSRVD_ES_ACCESSTOKEN_TYPE))
+                {
+                    return static_cast<OAUTH_TOKENTYPE>(
+                                m_rep.getValue<int>(OC_RSRVD_ES_ACCESSTOKEN_TYPE));
+                }
+                return NONE_OAUTH_TOKENTYPE;
+            }
+
+            /**
              * Get OCRepresentation object
              *
              * @return OCRepresentation object
@@ -263,8 +318,8 @@ namespace OIC
         };
 
         /**
-         * @brief Data class stored for Device property provisioning which includes a WiFi
-         *        and device configuration provisioning
+         * @brief Data class stored for provisioning of Device properties which includes
+         *        properties of WiFiConf resource and DevConf resource
          */
         class DeviceProp
         {
@@ -296,7 +351,7 @@ namespace OIC
             }
 
             /**
-             * Set WiFi resource properties to be delivered to Enrollee
+             * Set WiFiConf resource properties to be delivered to Enrollee
              *
              * @param ssid Ssid of the Enroller
              * @param pwd Pwd of the Enrolle
@@ -315,19 +370,6 @@ namespace OIC
             }
 
             /**
-             * Set DevConf resource properties to be delivered to Enrollee
-             *
-             * @param language IETF language tag using ISO 639X
-             * @param country ISO Country Code (ISO 3166-1 Alpha-2)
-             */
-            void setDevConfProp(string language, string country, string location)
-            {
-                m_rep.setValue(OC_RSRVD_ES_LANGUAGE, language);
-                m_rep.setValue(OC_RSRVD_ES_COUNTRY, country);
-                m_rep.setValue(OC_RSRVD_ES_LOCATION, location);
-            }
-
-            /**
              * Get a SSID of Enroller
              *
              * @return a SSID of enroller
@@ -388,50 +430,6 @@ namespace OIC
             }
 
             /**
-             * Get a language to be set. A language is expressed in IETF language tag
-             * using ISO 639X.
-             *
-             * @return a language to be set
-             */
-            std::string getLanguage() const
-            {
-                if(m_rep.hasAttribute(OC_RSRVD_ES_LANGUAGE))
-                {
-                    return m_rep.getValue<std::string>(OC_RSRVD_ES_LANGUAGE);
-                }
-                return std::string("");
-            }
-
-            /**
-             * Get a country to be set. A country is expressed in ISO Country Code
-             * (ISO 3166-1 Alpha-2)
-             *
-             * @return a country to be set
-             */
-            std::string getCountry() const
-            {
-                if(m_rep.hasAttribute(OC_RSRVD_ES_COUNTRY))
-                {
-                    return m_rep.getValue<std::string>(OC_RSRVD_ES_COUNTRY);
-                }
-                return std::string("");
-            }
-
-            /**
-             * Get a location to be set. A location is GPS information
-             *
-             * @return a country to be set
-             */
-            std::string getLocation() const
-            {
-                if(m_rep.hasAttribute(OC_RSRVD_ES_LOCATION))
-                {
-                    return m_rep.getValue<std::string>(OC_RSRVD_ES_LOCATION);
-                }
-                return std::string("");
-            }
-
-            /**
              * Get OCRepresentation object
              *
              * @return OCRepresentation object
@@ -454,13 +452,70 @@ namespace OIC
             SecProvisioningStatus(string deviceUUID, ESResult result) :
                 m_devUUID(deviceUUID), m_result(result)
             {
+#ifdef __WITH_DTLS__
+                m_selectedOTMethod = OIC_JUST_WORKS;
+                m_isMOTEnabled = false;
+                m_isOwned = false;
+                m_ownerID = {};
+#endif
+            }
+#ifdef __WITH_DTLS__
+            SecProvisioningStatus(std::shared_ptr<OCSecureResource> resource, ESResult result) :
+                m_result(result)
+            {
+                m_isMOTEnabled = false;
+                if(resource.get() != nullptr)
+                {
+                    m_devUUID = resource->getDeviceID();
+                    m_isOwned = resource->getOwnedStatus();
+#ifdef MULTIPLE_OWNER
+                    m_isMOTEnabled = resource->isMOTEnabled();
+#endif
+
+                    if( OC_STACK_OK != resource->getOTMethod(&m_selectedOTMethod) )
+                    {
+                        m_selectedOTMethod = OIC_OXM_COUNT; // Out-of-range
+                    }
+
+                    if(resource->getOwnedStatus())
+                    {
+                        char uuidString[UUID_STRING_SIZE] = {};
+                        if(RAND_UUID_OK == OCConvertUuidToString(resource->getDevPtr()->doxm->owner.id, uuidString))
+                        {
+                            m_ownerID = uuidString;
+                        }
+                        else
+                        {
+                            m_ownerID = {};
+                        }
+                    }
+                }
+            }
+
+            OicSecOxm_t getSelectedOTMethod() const
+            {
+                return m_selectedOTMethod;
             }
 
-            const string getDeviceUUID()
+            bool isMOTEnabled() const
             {
-                return m_devUUID;
+                return m_isMOTEnabled;
             }
 
+            bool isOwnedDevice() const
+            {
+                return m_isOwned;
+            }
+
+            const std::string getOwnerID()
+            {
+                return m_ownerID;
+            }
+#endif
+            const std::string getDeviceUUID()
+            {
+                return m_devUUID;
+            }
             /**
              * Get a result for about security provisioning is success or not.
              *
@@ -477,6 +532,12 @@ namespace OIC
         private:
             string m_devUUID;
             ESResult m_result;
+#ifdef __WITH_DTLS__
+            OicSecOxm_t m_selectedOTMethod;
+            bool m_isMOTEnabled;
+            bool m_isOwned;
+            std::string m_ownerID;
+#endif
         };
 
         /**
@@ -491,21 +552,21 @@ namespace OIC
             /**
              * Constructor
              * The expected OCRepresentation is one for collection resource and has several child
-             * OCRepresentation object corresponding to WiFi, DevConf, and CloudServer resource's
-             * representation.
+             * OCRepresentation object corresponding to WiFiConf, DevConf, and CoapCloudConf
+             * resources' representations.
              */
             EnrolleeConf(const OCRepresentation& rep) :
-                m_ProvRep(rep)
+                m_EasySetupRep(rep)
             {
             }
 
             EnrolleeConf(const EnrolleeConf& enrolleeConf) :
-                m_ProvRep(enrolleeConf.getProvResRep())
+                m_EasySetupRep(enrolleeConf.getEasySetupRep())
             {
             }
 
             EnrolleeConf(const EnrolleeConf&& enrolleeConf) :
-                m_ProvRep(std::move(enrolleeConf.getProvResRep()))
+                m_EasySetupRep(std::move(enrolleeConf.getEasySetupRep()))
             {
             }
 
@@ -517,7 +578,7 @@ namespace OIC
              */
             std::string getDeviceName() const
             {
-                std::vector<OCRepresentation> children = m_ProvRep.getChildren();
+                std::vector<OCRepresentation> children = m_EasySetupRep.getChildren();
                 for(auto child = children.begin(); child != children.end(); ++child)
                 {
                     if(child->getUri().find(OC_RSRVD_ES_URI_DEVCONF) != std::string::npos)
@@ -542,37 +603,6 @@ namespace OIC
             }
 
             /**
-             * Get a model number of Enrollee.
-             *
-             * @return a model number of Enrollee
-             */
-            std::string getModelNumber() const
-            {
-                std::vector<OCRepresentation> children = m_ProvRep.getChildren();
-                for(auto child = children.begin(); child != children.end(); ++child)
-                {
-                    if(child->getUri().find(OC_RSRVD_ES_URI_DEVCONF) != std::string::npos)
-                    {
-                        OCRepresentation rep;
-                        if(child->hasAttribute(OC_RSRVD_REPRESENTATION))
-                        {
-                            rep = child->getValue<OCRepresentation>(OC_RSRVD_REPRESENTATION);
-                        }
-                        else
-                        {
-                            return std::string("");
-                        }
-
-                        if(rep.hasAttribute(OC_RSRVD_ES_MODELNUMBER))
-                        {
-                            return rep.getValue<std::string>(OC_RSRVD_ES_MODELNUMBER);
-                        }
-                    }
-                }
-                return std::string("");
-            }
-
-            /**
              * Get a set of WiFi supported modes of Enrollee
              *
              * @return a set of WiFi supported modes of Enrollee
@@ -584,10 +614,10 @@ namespace OIC
                 vector<WIFI_MODE> modes;
                 modes.clear();
 
-                std::vector<OCRepresentation> children = m_ProvRep.getChildren();
+                std::vector<OCRepresentation> children = m_EasySetupRep.getChildren();
                 for(auto child = children.begin(); child != children.end(); ++child)
                 {
-                    if(child->getUri().find(OC_RSRVD_ES_URI_WIFI) != std::string::npos)
+                    if(child->getUri().find(OC_RSRVD_ES_URI_WIFICONF) != std::string::npos)
                     {
                         OCRepresentation rep;
                         if(child->hasAttribute(OC_RSRVD_REPRESENTATION))
@@ -621,10 +651,10 @@ namespace OIC
              */
             WIFI_FREQ getWiFiFreq() const
             {
-                std::vector<OCRepresentation> children = m_ProvRep.getChildren();
+                std::vector<OCRepresentation> children = m_EasySetupRep.getChildren();
                 for(auto child = children.begin(); child != children.end(); ++child)
                 {
-                    if(child->getUri().find(OC_RSRVD_ES_URI_WIFI) != std::string::npos)
+                    if(child->getUri().find(OC_RSRVD_ES_URI_WIFICONF) != std::string::npos)
                     {
                         OCRepresentation rep;
                         if(child->hasAttribute(OC_RSRVD_REPRESENTATION))
@@ -647,18 +677,68 @@ namespace OIC
             }
 
             /**
+             * Get a provisioning status property of Enrollee.
+             *
+             * @return a provisioning status property of Enrollee
+             */
+            ProvStatus getProvStatus() const
+            {
+                OCRepresentation rep;
+                if(m_EasySetupRep.hasAttribute(OC_RSRVD_REPRESENTATION))
+                {
+                    rep = m_EasySetupRep.getValue<OCRepresentation>(OC_RSRVD_REPRESENTATION);
+                }
+                else
+                {
+                    return ES_STATE_INIT;
+                }
+
+                if(rep.hasAttribute(OC_RSRVD_ES_PROVSTATUS))
+                {
+                    return static_cast<ProvStatus>(
+                                        rep.getValue<int>(OC_RSRVD_ES_PROVSTATUS));
+                }
+                return ES_STATE_INIT;
+            }
+
+            /**
+             * Get a last error code property of Enrollee.
+             *
+             * @return a last error code property of Enrollee.
+             */
+            ESErrorCode getLastErrCode() const
+            {
+                OCRepresentation rep;
+                if(m_EasySetupRep.hasAttribute(OC_RSRVD_REPRESENTATION))
+                {
+                    rep = m_EasySetupRep.getValue<OCRepresentation>(OC_RSRVD_REPRESENTATION);
+                }
+                else
+                {
+                    return ES_ERRCODE_NO_ERROR;
+                }
+
+                if(rep.hasAttribute(OC_RSRVD_ES_LAST_ERRORCODE))
+                {
+                    return static_cast<ESErrorCode>(
+                                        rep.getValue<int>(OC_RSRVD_ES_LAST_ERRORCODE));
+                }
+                return ES_ERRCODE_NO_ERROR;
+            }
+
+            /**
              * Get an accessibility to cloud server of an Enrollee
              *
              * @return an accessibility to cloud server of an Enrollee
              */
             bool isCloudAccessible() const
             {
-                std::vector<OCRepresentation> children = m_ProvRep.getChildren();
+                std::vector<OCRepresentation> children = m_EasySetupRep.getChildren();
                 for(auto child = children.begin(); child != children.end(); ++child)
                 {
                     for(auto rt : child->getResourceTypes())
                     {
-                        if(0 == rt.compare(OC_RSRVD_ES_RES_TYPE_CLOUDSERVER))
+                        if(0 == rt.compare(OC_RSRVD_ES_RES_TYPE_COAPCLOUDCONF))
                         {
                             return true;
                         }
@@ -672,13 +752,13 @@ namespace OIC
              *
              * @return OCRepresentation object
              */
-            const OCRepresentation& getProvResRep() const
+            const OCRepresentation& getEasySetupRep() const
             {
-                return m_ProvRep;
+                return m_EasySetupRep;
             }
 
         protected:
-            OCRepresentation m_ProvRep;
+            OCRepresentation m_EasySetupRep;
         };
 
         /**
@@ -855,6 +935,106 @@ namespace OIC
         };
 
         /**
+         * Status object for connect API. This object is given to application
+         * when a response for 'Connect' request from Enrollee is arrived.
+         */
+        class ConnectRequestStatus
+        {
+        public:
+            /**
+             * Constructor
+             */
+            ConnectRequestStatus(ESResult result) :
+                    m_result(result)
+            {
+            }
+
+            /**
+             * Get a result of Connect request
+             *
+             * @return ::ES_OK\n
+             *         ::ES_COMMUNICATION_ERROR\n
+             *         ::ES_ERROR\n
+             *
+             * @see ESResult
+             */
+            ESResult getESResult()
+            {
+                return m_result;
+            }
+
+        private:
+            ESResult m_result;
+        };
+
+        class ESOwnershipTransferData
+        {
+        public:
+#ifdef __WITH_DTLS__
+            ESOwnershipTransferData() :
+                m_MOTMethod(OIC_OXM_COUNT), m_preconfiguredPin("")
+            {
+            }
+
+            ESOwnershipTransferData(const ESOwnershipTransferData& data) :
+                m_MOTMethod(data.getMOTMethod()),
+                m_preconfiguredPin(data.getPreConfiguredPin())
+            {
+            }
+
+            ESResult setMOTMethod(OicSecOxm_t method)
+            {
+#ifdef MULTIPLE_OWNER
+                if(OIC_RANDOM_DEVICE_PIN != method)
+                {
+                    return ES_ERROR;
+                }
+
+                m_MOTMethod = method;
+                return ES_OK;
+#else
+                (void) method;
+
+                return ES_ERROR;
+#endif
+            }
+
+            ESResult setMOTMethod(OicSecOxm_t method, const std::string& pin)
+            {
+#ifdef MULTIPLE_OWNER
+                if(OIC_PRECONFIG_PIN != method || pin.empty())
+                {
+                    return ES_ERROR;
+                }
+
+                m_preconfiguredPin = pin;
+                m_MOTMethod = method;
+                return ES_OK;
+#else
+                (void) method;
+                (void) pin;
+
+                return ES_ERROR;
+#endif
+            }
+
+            OicSecOxm_t getMOTMethod() const
+            {
+                return m_MOTMethod;
+            }
+
+            std::string getPreConfiguredPin() const
+            {
+                return m_preconfiguredPin;
+            }
+
+        private:
+            OicSecOxm_t m_MOTMethod;
+            std::string m_preconfiguredPin;
+#endif
+        };
+
+        /**
          * Callback function definition for providing Enrollee status
          */
         typedef function< void(shared_ptr< GetEnrolleeStatus >) > GetStatusCb;
@@ -875,11 +1055,25 @@ namespace OIC
         typedef function< void(shared_ptr< CloudPropProvisioningStatus >) > CloudPropProvStatusCb;
 
         /**
+         * Callback function definition for providing 'Connect' request status
+         */
+        typedef function< void(shared_ptr< ConnectRequestStatus >) > ConnectRequestStatusCb;
+
+
+        /**
          * Callback function definition for providing Enrollee security provisioning status
          */
         typedef function< void(shared_ptr<SecProvisioningStatus>) > SecurityProvStatusCb;
 
         /**
+         * Callback function definition for providing Enrollee security provisioning status.
+         * This callback is an overloaded version of SecurityProvStatusCb, which has
+         * ESOwnershipTransferData as a return value.
+         */
+        typedef function< ESOwnershipTransferData(shared_ptr<SecProvisioningStatus>) >
+                                                                    SecurityProvStatusCbWithOption;
+
+        /**
          * Callback definition to be invoked when the security stack expects a pin from application
          */
         typedef function< void(string&) > SecurityPinCb;
diff --git a/service/easy-setup/mediator/richsdk/inc/ESSCCommon.h b/service/easy-setup/mediator/richsdk/inc/ESSCCommon.h
new file mode 100755 (executable)
index 0000000..3253de2
--- /dev/null
@@ -0,0 +1,913 @@
+//******************************************************************
+//
+// Copyright 2016 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 ESSC_COMMON_RICH_H_
+#define ESSC_COMMON_RICH_H_
+
+#include "ESRichCommon.h"
+
+using namespace OC;
+using namespace std;
+
+#define SC_RSRVD_ES_VENDOR_NETCONNECTION_STATE  "x.com.samsung.ncs"
+#define SC_RSRVD_ES_VENDOR_DISCOVERY_CHANNEL    "x.com.samsung.chn"
+#define SC_RSRVD_ES_VENDOR_DEVICE_TYPE          "x.com.samsung.dt"
+#define SC_RSRVD_ES_VENDOR_DEVICE_SUBTYPE       "x.com.samsung.sdt"
+#define SC_RSRVD_ES_VENDOR_LOCATION             "x.com.samsung.location"
+#define SC_RSRVD_ES_VENDOR_CLIENTID             "x.com.samsung.clientid"
+#define SC_RSRVD_ES_VENDOR_ACCOUNT              "x.com.samsung.account"
+#define SC_RSRVD_ES_VENDOR_ADDITIONAL_AUTH_CODE "x.com.samsung.aac"
+#define SC_RSRVD_ES_VENDOR_ACCESS_TOKEN         "x.com.samsung.accesstoken"
+#define SC_RSRVD_ES_VENDOR_REFRESH_TOKEN        "x.com.samsung.refreshtoken"
+#define SC_RSRVD_ES_VENDOR_UTC_DATE_TIME        "x.com.samsung.datetime"
+#define SC_RSRVD_ES_VENDOR_REGIONAL_DATE_TIME   "x.com.samsung.regionaldatetime"
+#define SC_RSRVD_ES_VENDOR_BSSID                "x.com.samsung.bssid"
+#define SC_RSRVD_ES_VENDOR_USERID               "x.com.samsung.uid"
+#define SC_RSRVD_ES_VENDOR_REGISTER_MOBILE_DEV  "x.com.samsung.rmd"
+#define SC_RSRVD_ES_VENDOR_REGISTER_SET_DEV     "x.com.samsung.rsd"
+#define SC_RSRVD_ES_VENDOR_NETWORK_PROV_INFO    "x.com.samsung.npi"
+#define SC_RSRVD_ES_VENDOR_TC_STATUS            "x.com.samsung.tcstatus"
+#define SC_RSRVD_ES_VENDOR_TC_HEADER            "x.com.samsung.tcheader"
+#define SC_RSRVD_ES_VENDOR_TC_VERSION           "x.com.samsung.tcversion"
+#define SC_RSRVD_ES_VENDOR_TC_RESULT            "x.com.samsung.tcresult"
+#define SC_RSRVD_ES_VENDOR_PNP_PIN              "x.com.samsung.pnppin"
+#define SC_RSRVD_ES_VENDOR_MODEL_NUMBER         "x.com.samsung.modelnumber"
+#define SC_RSRVD_ES_VENDOR_LANGUAGE             "x.com.samsung.language"
+#define SC_RSRVD_ES_VENDOR_COUNTRY              "x.com.samsung.country"
+#define SC_RSRVD_ES_VENDOR_GPSLOCATION          "x.com.samsung.gpslocation"
+#define SC_RSRVD_ES_VENDOR_ES_PROTOCOL_VERSION  "x.com.samsung.espv"
+
+
+namespace OIC
+{
+    namespace Service
+    {
+
+        #define INVALID_DISCOVERY_CHANNEL -1
+
+        typedef enum
+        {
+            NET_STATE_INIT = -1,                /**< Init state **/
+            NET_STATE_WIRED_CONNECTED = 0,      /**< Wired connected **/
+            NET_STATE_WIRELESS_CONNECTED,       /**< Wireless connected **/
+            NET_STATE_NOT_CONNECTED             /**< Not connected, at all **/
+        } NETCONNECTION_STATE;
+
+        typedef enum
+        {
+            TC_STATUS_NOT_SUPPORTED = 0,
+            TC_STATUS_ALREADY_AGREED,
+            TC_STATUS_NEED_TO_AGREE,
+            TC_STATUS_DOWNLOADING_TC,
+            TC_STATUS_SUCCESS_TO_DOWNLOAD_TC,
+            TC_STATUS_FAIL_TO_DOWNLOAD_TC,
+            TC_STATUS_DISAGREED_WITH_TC,
+            TC_STATUS_GEO_BLOCKED,
+            TC_STATUS_TIMEOUT_TO_AGREE
+        } TC_STATUS;
+
+        /**
+         * @brief Properties of provisioning resource. It includes a provisioning status and last
+         *        error code.
+         */
+        class SCEnrolleeStatus : public EnrolleeStatus
+        {
+        public:
+            SCEnrolleeStatus(const EnrolleeStatus&& parent) : EnrolleeStatus(parent)
+            {
+            }
+
+            /**
+             * Get a network connection state property of Enrollee.
+             *
+             * @return a network connection state property of Enrollee.
+             */
+            NETCONNECTION_STATE getNetConnectionState() const
+            {
+                if(m_rep.hasAttribute(SC_RSRVD_ES_VENDOR_NETCONNECTION_STATE))
+                {
+                    return static_cast<NETCONNECTION_STATE>
+                                    (m_rep.getValue<int>(SC_RSRVD_ES_VENDOR_NETCONNECTION_STATE));
+                }
+                return NETCONNECTION_STATE::NET_STATE_INIT;
+            }
+
+            /**
+             * Get T&C status
+             *
+             * @return T&C Status
+             *
+             * @see TC_STATUS
+             */
+            TC_STATUS getTCStatus()
+            {
+                if(m_rep.hasAttribute(SC_RSRVD_ES_VENDOR_TC_STATUS))
+                {
+                    return static_cast<TC_STATUS>
+                            (m_rep.getValue<int>(SC_RSRVD_ES_VENDOR_TC_STATUS));
+                }
+
+                return TC_STATUS::TC_STATUS_NOT_SUPPORTED;
+            }
+        };
+
+        /**
+         * @brief Data class stored for Device property provisioning which includes a WiFi
+         *        and device configuration provisioning
+         */
+        class SCDeviceProp : public DeviceProp
+        {
+        public:
+
+            /**
+             * Set DevConf resource properties to be delivered to Enrollee
+             *
+             * @param language IETF language tag using ISO 639X
+             * @param country ISO Country Code (ISO 3166-1 Alpha-2)
+             * @param location location information
+             */
+            void setDevConfProp(string language, string country, string location)
+            {
+                m_rep.setValue(SC_RSRVD_ES_VENDOR_LANGUAGE, language);
+                m_rep.setValue(SC_RSRVD_ES_VENDOR_COUNTRY, country);
+                m_rep.setValue(SC_RSRVD_ES_VENDOR_GPSLOCATION, location);
+            }
+
+            /**
+             * Get a language to be set. A language is expressed in IETF language tag
+             * using ISO 639X.
+             *
+             * @return a language to be set
+             */
+            std::string getLanguage() const
+            {
+                if(m_rep.hasAttribute(SC_RSRVD_ES_VENDOR_LANGUAGE))
+                {
+                    return m_rep.getValue<std::string>(SC_RSRVD_ES_VENDOR_LANGUAGE);
+                }
+                return std::string("");
+            }
+
+            /**
+             * Get a country to be set. A country is expressed in ISO Country Code
+             * (ISO 3166-1 Alpha-2)
+             *
+             * @return a country to be set
+             */
+            std::string getCountry() const
+            {
+                if(m_rep.hasAttribute(SC_RSRVD_ES_VENDOR_COUNTRY))
+                {
+                    return m_rep.getValue<std::string>(SC_RSRVD_ES_VENDOR_COUNTRY);
+                }
+                return std::string("");
+            }
+
+            /**
+             * Get a location to be set. A location is GPS information
+             *
+             * @return a country to be set
+             */
+            std::string getLocation() const
+            {
+                if(m_rep.hasAttribute(SC_RSRVD_ES_VENDOR_GPSLOCATION))
+                {
+                    return m_rep.getValue<std::string>(SC_RSRVD_ES_VENDOR_GPSLOCATION);
+                }
+                return std::string("");
+            }
+
+            /**
+             * Set discoveryChannel properties to be delivered to Enrollee
+             *
+             * @param discoveryChannel Channel of the Enroller for fast discover
+             */
+            void setDiscoveryChannel(int discoveryChannel)
+            {
+                m_rep.setValue(SC_RSRVD_ES_VENDOR_DISCOVERY_CHANNEL, discoveryChannel);
+            }
+
+            /**
+             * Get an channel of Enroller
+             *
+             * @return an channel of enroller
+             */
+            int getDiscoveryChannel()
+            {
+                if(m_rep.hasAttribute(SC_RSRVD_ES_VENDOR_DISCOVERY_CHANNEL))
+                {
+                    return m_rep.getValue<int>(SC_RSRVD_ES_VENDOR_DISCOVERY_CHANNEL);
+                }
+                return INVALID_DISCOVERY_CHANNEL;
+            }
+
+            /**
+             * Set samsung-specific location property to be delivered to Enrollee
+             *
+             * @param locations a set of location information
+             */
+            void setSCLocation(const std::vector<std::string> &locations)
+            {
+                m_rep.setValue(SC_RSRVD_ES_VENDOR_LOCATION, locations);
+            }
+
+            /**
+             * Set samsung account property to be delivered to Enrollee (for TV)
+             *
+             * @param account a samsung account ID information (for TV)
+             */
+            void setSCAccount(const std::string &account)
+            {
+                m_rep.setValue(SC_RSRVD_ES_VENDOR_ACCOUNT, account);
+            }
+
+            /**
+             * Set UTC date time property to be delivered to Enrollee.
+             * The format is "[yyyy]-[mm]-[dd]T[hh]:[mm]:[ss]Z"
+             *
+             * @param datetime UTC date time
+             */
+            void setUTCDatetime(const std::string &datetime)
+            {
+                m_rep.setValue(SC_RSRVD_ES_VENDOR_UTC_DATE_TIME, datetime);
+            }
+
+            /**
+             * Get UTC date time property
+             *
+             * @return UTC date time
+             */
+            std::string getUTCDatetime()
+            {
+                if(m_rep.hasAttribute(SC_RSRVD_ES_VENDOR_UTC_DATE_TIME))
+                {
+                    return m_rep.getValue<std::string>(SC_RSRVD_ES_VENDOR_UTC_DATE_TIME);
+                }
+                return {};
+            }
+
+            /**
+             * Set regional date time property to be delivered to Enrollee.
+             * The format is "[yyyy]-[mm]-[dd]T[hh]:[mm]:[ss]Z"
+             *
+             * @param datetime Regional date time
+             */
+            void setRegionalDatetime(const std::string &datetime)
+            {
+                m_rep.setValue(SC_RSRVD_ES_VENDOR_REGIONAL_DATE_TIME, datetime);
+            }
+
+            /**
+             * Get regional date time property
+             *
+             * @return Date time
+             */
+            std::string getRegionalDatetime()
+            {
+                if(m_rep.hasAttribute(SC_RSRVD_ES_VENDOR_REGIONAL_DATE_TIME))
+                {
+                    return m_rep.getValue<std::string>(SC_RSRVD_ES_VENDOR_REGIONAL_DATE_TIME);
+                }
+                return {};
+            }
+
+            /**
+             * Set Mobile device information used for 'register TV'
+             * The format is in json. The key indicates the meaning of value and the value is a
+             * corresponding information. Supported keys include: wm(Wifi MAC), pm(P2P MAC),
+             * bm(BT MAC), dn(device name), dt(device type), it(icon type).
+             *
+             * @param regMobileDev register mobile device
+             */
+            void setRegisterMobileDevice(const std::string &regMobileDev)
+            {
+                m_rep.setValue(SC_RSRVD_ES_VENDOR_REGISTER_MOBILE_DEV, regMobileDev);
+            }
+
+            /**
+             * Get Mobile device information used for 'register TV'
+             *
+             * @return register mobile device
+             */
+            std::string getRegisterMobileDevice()
+            {
+                if(m_rep.hasAttribute(SC_RSRVD_ES_VENDOR_REGISTER_MOBILE_DEV))
+                {
+                    return m_rep.getValue<std::string>(SC_RSRVD_ES_VENDOR_REGISTER_MOBILE_DEV);
+                }
+                return {};
+            }
+
+            /**
+             * Set a BSSID of Enroller
+             *
+             * @param a BSSID of enroller
+             */
+            void setBSSID(const std::string &bssid)
+            {
+                m_rep.setValue(SC_RSRVD_ES_VENDOR_BSSID, bssid);
+            }
+
+            /**
+             * Get a BSSID of Enroller
+             *
+             * @return a BSSID of enroller
+             */
+            std::string getBSSID()
+            {
+                if(m_rep.hasAttribute(SC_RSRVD_ES_VENDOR_BSSID))
+                {
+                    return m_rep.getValue<std::string>(SC_RSRVD_ES_VENDOR_BSSID);
+                }
+                return {};
+            }
+        };
+
+        class SCCloudProp : public CloudProp
+        {
+            public:
+            /**
+             * Set samsung-specific client service ID property to be delivered to Enrollee
+             *
+             * @param clientID - Client service ID
+             */
+            void setClientID(const std::string &clientID)
+            {
+                m_rep.setValue(SC_RSRVD_ES_VENDOR_CLIENTID, clientID);
+            }
+
+            /**
+             * Get samsung-specific client service ID property.
+             *
+             * @return Client service ID.
+             */
+            std::string getClientID()
+            {
+                if(m_rep.hasAttribute(SC_RSRVD_ES_VENDOR_CLIENTID))
+                {
+                    return m_rep.getValue<std::string>(SC_RSRVD_ES_VENDOR_CLIENTID);
+                }
+                return {};
+            }
+
+            /**
+             * Set samsung-specific additional AuthCode property to be delivered to Enrollee (for TV/AV sign up VD SSO)
+             *
+             * @param additionalAuthcode - additional AuthCode (for TV/AV sign up VD SSO)
+             */
+            void setAdditionalAuthCode(const std::string &additionalAuthcode)
+            {
+                m_rep.setValue(SC_RSRVD_ES_VENDOR_ADDITIONAL_AUTH_CODE, additionalAuthcode);
+            }
+
+            /**
+             * Set samsung-specific refresh token property to be delivered to Enrollee
+             *
+             * @param refreshtoken - Refresh token.
+             */
+            void setRefreshToken(const std::string &refreshtoken)
+            {
+                m_rep.setValue(SC_RSRVD_ES_VENDOR_REFRESH_TOKEN, refreshtoken);
+            }
+
+            /**
+             * Get samsung-specific refresh token property.
+             *
+             * @return refreshtoken - Refresh token.
+             */
+            std::string getRefreshToken()
+            {
+                if(m_rep.hasAttribute(SC_RSRVD_ES_VENDOR_REFRESH_TOKEN))
+                {
+                    return m_rep.getValue<std::string>(SC_RSRVD_ES_VENDOR_REFRESH_TOKEN);
+                }
+                return {};
+            }
+
+            /**
+             * Set samsung-specific user ID property to be delivered to Enrollee
+             *
+             * @param uid - user ID.
+             */
+            void setUserID(const std::string &uid)
+            {
+                m_rep.setValue(SC_RSRVD_ES_VENDOR_USERID, uid);
+            }
+
+            /**
+             * Get samsung-specific user ID property
+             *
+             * @return uid - user ID.
+             */
+            std::string getUserID()
+            {
+                if(m_rep.hasAttribute(SC_RSRVD_ES_VENDOR_USERID))
+                {
+                    return m_rep.getValue<std::string>(SC_RSRVD_ES_VENDOR_USERID);
+                }
+                return {};
+            }
+
+            /**
+             * Set T&C Result
+             * Indicates T&C result by mobile user in json format.
+             *
+             * @param uid - user ID.
+             */
+            void setTCResult(const std::string &result)
+            {
+                m_rep.setValue(SC_RSRVD_ES_VENDOR_TC_RESULT, result);
+            }
+
+            /**
+             * Get T&C Result
+             *
+             * @return uid - user ID.
+             */
+            std::string getTCResult()
+            {
+                if(m_rep.hasAttribute(SC_RSRVD_ES_VENDOR_TC_RESULT))
+                {
+                    return m_rep.getValue<std::string>(SC_RSRVD_ES_VENDOR_TC_RESULT);
+                }
+                return {};
+            }
+        };
+
+        /**
+         * @breif This provide a set of getter APIs from received response for getConfiguration().
+         *        Received information includes a device name, WiFi supported mode, and frequency.
+         *        Additionally, you can know if Enrollee can be access to cloud server with this
+         *        object.
+         */
+        class SCEnrolleeConf : public EnrolleeConf
+        {
+        public:
+            SCEnrolleeConf(const EnrolleeConf&& parent) : EnrolleeConf(parent)
+            {
+            }
+
+            /**
+             * Get a model number of Enrollee.
+             *
+             * @return a model number of Enrollee
+             */
+            std::string getModelNumber() const
+            {
+                std::vector<OCRepresentation> children = m_EasySetupRep.getChildren();
+                for(auto child = children.begin(); child != children.end(); ++child)
+                {
+                    if(child->getUri().find(OC_RSRVD_ES_URI_DEVCONF) != std::string::npos)
+                    {
+                        OCRepresentation rep;
+                        if(child->hasAttribute(OC_RSRVD_REPRESENTATION))
+                        {
+                            rep = child->getValue<OCRepresentation>(OC_RSRVD_REPRESENTATION);
+                        }
+                        else
+                        {
+                            return std::string("");
+                        }
+
+                        if(rep.hasAttribute(SC_RSRVD_ES_VENDOR_MODEL_NUMBER))
+                        {
+                            return rep.getValue<std::string>(SC_RSRVD_ES_VENDOR_MODEL_NUMBER);
+                        }
+                    }
+                }
+                return std::string("");
+            }
+
+            /**
+             * Get a device type of Enrollee.
+             * It is Device's human-friendly name like device model name.
+             *
+             * @return a device type of Enrollee
+             */
+            std::string getDeviceType() const
+            {
+                std::vector<OCRepresentation> children = m_EasySetupRep.getChildren();
+                for(auto child = children.begin(); child != children.end(); ++child)
+                {
+                    if(child->getUri().find(OC_RSRVD_ES_URI_DEVCONF) != std::string::npos)
+                    {
+                        OCRepresentation rep;
+                        if(child->hasAttribute(OC_RSRVD_REPRESENTATION))
+                        {
+                            rep = child->getValue<OCRepresentation>(OC_RSRVD_REPRESENTATION);
+                        }
+                        else
+                        {
+                            return std::string("");
+                        }
+
+                        if(rep.hasAttribute(SC_RSRVD_ES_VENDOR_DEVICE_TYPE))
+                        {
+                            return rep.getValue<std::string>(SC_RSRVD_ES_VENDOR_DEVICE_TYPE);
+                        }
+                    }
+                }
+                return std::string("");
+            }
+
+            /**
+             * Get a device sub-type of Enrollee.
+             * It is Device's human-friendly name like device model name.
+             *
+             * @return a device sub-type of Enrollee
+             */
+            std::string getDeviceSubType() const
+            {
+                std::vector<OCRepresentation> children = m_EasySetupRep.getChildren();
+                for(auto child = children.begin(); child != children.end(); ++child)
+                {
+                    if(child->getUri().find(OC_RSRVD_ES_URI_DEVCONF) != std::string::npos)
+                    {
+                        OCRepresentation rep;
+                        if(child->hasAttribute(OC_RSRVD_REPRESENTATION))
+                        {
+                            rep = child->getValue<OCRepresentation>(OC_RSRVD_REPRESENTATION);
+                        }
+                        else
+                        {
+                            return std::string("");
+                        }
+
+                        if(rep.hasAttribute(SC_RSRVD_ES_VENDOR_DEVICE_SUBTYPE))
+                        {
+                            return rep.getValue<std::string>(SC_RSRVD_ES_VENDOR_DEVICE_SUBTYPE);
+                        }
+                    }
+                }
+                return std::string("");
+            }
+
+            /**
+             * Get Set device information used for 'register TV'
+             * The format is in json. The key indicates the meaning of value and the value is a
+             * corresponding information. Supported keys include: wm(Wifi MAC), pm(P2P MAC),
+             * bm(BT MAC), rt(Remote Type)
+             *
+             * @return Register Set Device
+             */
+            std::string getRegisterSetDevice() const
+            {
+                std::vector<OCRepresentation> children = m_EasySetupRep.getChildren();
+                for(auto child = children.begin(); child != children.end(); ++child)
+                {
+                    if(child->getUri().find(OC_RSRVD_ES_URI_DEVCONF) != std::string::npos)
+                    {
+                        OCRepresentation rep;
+                        if(child->hasAttribute(OC_RSRVD_REPRESENTATION))
+                        {
+                            rep = child->getValue<OCRepresentation>(OC_RSRVD_REPRESENTATION);
+                        }
+                        else
+                        {
+                            return std::string("");
+                        }
+
+                        if(rep.hasAttribute(SC_RSRVD_ES_VENDOR_REGISTER_SET_DEV))
+                        {
+                            return rep.getValue<std::string>(SC_RSRVD_ES_VENDOR_REGISTER_SET_DEV);
+                        }
+                    }
+                }
+                return std::string("");
+            }
+
+            /**
+             * Get network provisioning information for the device.
+             * Mediator can use this information to enquire & validate registration status with corresponding Network Vendor.
+             * The format is in JSON. The key indicates the meaning of value and the value is a
+             * corresponding information. Supported keys include: IMEI (IMEI Number), IMSI (IMSI Number),
+             * MCC_MNC(MCC & MNC Number), SN(Serial Number)
+             *
+             * @return Network Provisioning Information String.
+             */
+            std::string getNetworkProvisioningInfo() const
+            {
+                std::vector<OCRepresentation> children = m_EasySetupRep.getChildren();
+                for(auto child = children.begin(); child != children.end(); ++child)
+                {
+                    if(child->getUri().find(OC_RSRVD_ES_URI_DEVCONF) != std::string::npos)
+                    {
+                        OCRepresentation rep;
+                        if(child->hasAttribute(OC_RSRVD_REPRESENTATION))
+                        {
+                            rep = child->getValue<OCRepresentation>(OC_RSRVD_REPRESENTATION);
+                        }
+                        else
+                        {
+                            return std::string("");
+                        }
+
+                        if(rep.hasAttribute(SC_RSRVD_ES_VENDOR_NETWORK_PROV_INFO))
+                        {
+                            return rep.getValue<std::string>(SC_RSRVD_ES_VENDOR_NETWORK_PROV_INFO);
+                        }
+                    }
+                }
+                return std::string("");
+            }
+
+            /**
+             * Get T&C status
+             * Indicates T&C is already agreed or not.
+             *
+             * @return T&C Status
+             *
+             * @see TC_STATUS
+             */
+            TC_STATUS getTCStatus()
+            {
+                OCRepresentation rep;
+                if(m_EasySetupRep.hasAttribute(OC_RSRVD_REPRESENTATION))
+                {
+                    rep = m_EasySetupRep.getValue<OCRepresentation>(OC_RSRVD_REPRESENTATION);
+                }
+                else
+                {
+                    return TC_STATUS::TC_STATUS_NOT_SUPPORTED;
+                }
+
+                if(rep.hasAttribute(SC_RSRVD_ES_VENDOR_TC_STATUS))
+                {
+                    return static_cast<TC_STATUS>
+                            (rep.getValue<int>(SC_RSRVD_ES_VENDOR_TC_STATUS));
+                }
+
+                return TC_STATUS::TC_STATUS_NOT_SUPPORTED;
+            }
+
+            /**
+             * Get T&C Header
+             * T&C Header Information in json format
+             *
+             * @return T&C Header
+             */
+            std::string getTCHeader()
+            {
+                std::vector<OCRepresentation> children = m_EasySetupRep.getChildren();
+                for(auto child = children.begin(); child != children.end(); ++child)
+                {
+                    if(child->getUri().find(OC_RSRVD_ES_URI_DEVCONF) != std::string::npos)
+                    {
+                        OCRepresentation rep;
+                        if(child->hasAttribute(OC_RSRVD_REPRESENTATION))
+                        {
+                            rep = child->getValue<OCRepresentation>(OC_RSRVD_REPRESENTATION);
+                        }
+                        else
+                        {
+                            return std::string("");
+                        }
+
+                        if(rep.hasAttribute(SC_RSRVD_ES_VENDOR_TC_HEADER))
+                        {
+                            return rep.getValue<std::string>(SC_RSRVD_ES_VENDOR_TC_HEADER);
+                        }
+                    }
+                }
+                return std::string("");
+            }
+
+            /**
+             * Get T&C Version
+             *
+             * @return T&C Version
+             */
+            std::string getTCVersion()
+            {
+                std::vector<OCRepresentation> children = m_EasySetupRep.getChildren();
+                for(auto child = children.begin(); child != children.end(); ++child)
+                {
+                    if(child->getUri().find(OC_RSRVD_ES_URI_DEVCONF) != std::string::npos)
+                    {
+                        OCRepresentation rep;
+                        if(child->hasAttribute(OC_RSRVD_REPRESENTATION))
+                        {
+                            rep = child->getValue<OCRepresentation>(OC_RSRVD_REPRESENTATION);
+                        }
+                        else
+                        {
+                            return std::string("");
+                        }
+
+                        if(rep.hasAttribute(SC_RSRVD_ES_VENDOR_TC_VERSION))
+                        {
+                            return rep.getValue<std::string>(SC_RSRVD_ES_VENDOR_TC_VERSION);
+                        }
+                    }
+                }
+                return std::string("");
+            }
+
+            /**
+             * Get PnP Pin
+             *
+             * @return PnP Pin
+             */
+            std::string getPnpPin() const
+            {
+                std::vector<OCRepresentation> children = m_EasySetupRep.getChildren();
+                for(auto child = children.begin(); child != children.end(); ++child)
+                {
+                    if(child->getUri().find(OC_RSRVD_ES_URI_DEVCONF) != std::string::npos)
+                    {
+                        OCRepresentation rep;
+                        if(child->hasAttribute(OC_RSRVD_REPRESENTATION))
+                        {
+                            rep = child->getValue<OCRepresentation>(OC_RSRVD_REPRESENTATION);
+                        }
+                        else
+                        {
+                            return std::string("");
+                        }
+
+                        if(rep.hasAttribute(SC_RSRVD_ES_VENDOR_PNP_PIN))
+                        {
+                            return rep.getValue<std::string>(SC_RSRVD_ES_VENDOR_PNP_PIN);
+                        }
+                    }
+                }
+                return std::string("");
+            }
+
+            /**
+             * Get a network connection state property of Enrollee.
+             *
+             * @return a network connection state property of Enrollee.
+             */
+            NETCONNECTION_STATE getNetConnectionState() const
+            {
+                OCRepresentation rep;
+                if(m_EasySetupRep.hasAttribute(OC_RSRVD_REPRESENTATION))
+                {
+                    rep = m_EasySetupRep.getValue<OCRepresentation>(OC_RSRVD_REPRESENTATION);
+                }
+                else
+                {
+                    return NETCONNECTION_STATE::NET_STATE_INIT;
+                }
+
+                if(rep.hasAttribute(SC_RSRVD_ES_VENDOR_NETCONNECTION_STATE))
+                {
+                    return static_cast<NETCONNECTION_STATE>
+                                    (rep.getValue<int>(SC_RSRVD_ES_VENDOR_NETCONNECTION_STATE));
+                }
+
+                return NETCONNECTION_STATE::NET_STATE_INIT;
+            }
+
+            /**
+             * Get a BSSID of Enroller
+             *
+             * @return a BSSID of enroller
+             */
+            std::string getBSSID() const
+            {
+                std::vector<OCRepresentation> children = m_EasySetupRep.getChildren();
+                for(auto child = children.begin(); child != children.end(); ++child)
+                {
+                    if(child->getUri().find(OC_RSRVD_ES_URI_WIFICONF) != std::string::npos)
+                    {
+                        OCRepresentation rep;
+                        if(child->hasAttribute(OC_RSRVD_REPRESENTATION))
+                        {
+                            rep = child->getValue<OCRepresentation>(OC_RSRVD_REPRESENTATION);
+                        }
+                        else
+                        {
+                            return std::string("");
+                        }
+
+                        if(rep.hasAttribute(SC_RSRVD_ES_VENDOR_BSSID))
+                        {
+                            return rep.getValue<std::string>(SC_RSRVD_ES_VENDOR_BSSID);
+                        }
+                    }
+                }
+                return {};
+            }
+
+            /**
+             * Get UTC date time
+             *
+             * @return UTC date time
+             */
+            std::string getUTCDatetime() const
+            {
+                std::vector<OCRepresentation> children = m_EasySetupRep.getChildren();
+                for(auto child = children.begin(); child != children.end(); ++child)
+                {
+                    if(child->getUri().find(OC_RSRVD_ES_URI_DEVCONF) != std::string::npos)
+                    {
+                        OCRepresentation rep;
+                        if(child->hasAttribute(OC_RSRVD_REPRESENTATION))
+                        {
+                            rep = child->getValue<OCRepresentation>(OC_RSRVD_REPRESENTATION);
+                        }
+                        else
+                        {
+                            return std::string("");
+                        }
+
+                        if(rep.hasAttribute(SC_RSRVD_ES_VENDOR_UTC_DATE_TIME))
+                        {
+                            return rep.getValue<std::string>(SC_RSRVD_ES_VENDOR_UTC_DATE_TIME);
+                        }
+                    }
+                }
+                return {};
+            }
+
+            /**
+             * Get regional date time
+             *
+             * @return date time
+             */
+            std::string getRegionalDatetime() const
+            {
+                std::vector<OCRepresentation> children = m_EasySetupRep.getChildren();
+                for(auto child = children.begin(); child != children.end(); ++child)
+                {
+                    if(child->getUri().find(OC_RSRVD_ES_URI_DEVCONF) != std::string::npos)
+                    {
+                        OCRepresentation rep;
+                        if(child->hasAttribute(OC_RSRVD_REPRESENTATION))
+                        {
+                            rep = child->getValue<OCRepresentation>(OC_RSRVD_REPRESENTATION);
+                        }
+                        else
+                        {
+                            return std::string("");
+                        }
+
+                        if(rep.hasAttribute(SC_RSRVD_ES_VENDOR_REGIONAL_DATE_TIME))
+                        {
+                            return rep.getValue<std::string>(SC_RSRVD_ES_VENDOR_REGIONAL_DATE_TIME);
+                        }
+                    }
+                }
+                return {};
+            }
+
+            /**
+             * Get Samsung Easy Setup Protocol Version.
+             *
+             * Mediator can use this API to differentiate between Easy Setup Protcol supported by
+             * Samsung Enrollee Devices.
+             *
+             * Example: Version Value for Tizen4.0: [\932.0\94]
+             *
+             * @return Easy Setup Protocol Version String.
+             */
+            std::string getESProtocolVersion() const
+            {
+                std::vector<OCRepresentation> children = m_EasySetupRep.getChildren();
+                for(auto child = children.begin(); child != children.end(); ++child)
+                {
+                    if(child->getUri().find(OC_RSRVD_ES_URI_DEVCONF) != std::string::npos)
+                    {
+                        OCRepresentation rep;
+                        if(child->hasAttribute(OC_RSRVD_REPRESENTATION))
+                        {
+                            rep = child->getValue<OCRepresentation>(OC_RSRVD_REPRESENTATION);
+                        }
+                        else
+                        {
+                            return std::string("");
+                        }
+
+                        if(rep.hasAttribute(SC_RSRVD_ES_VENDOR_ES_PROTOCOL_VERSION))
+                        {
+                            return rep.getValue<std::string>(SC_RSRVD_ES_VENDOR_ES_PROTOCOL_VERSION);
+                        }
+                    }
+                }
+                return std::string("");
+            }
+
+        };
+    }
+}
+
+#endif //ESSC_COMMON_RICH_H_
index 5cfe9f5..82163bf 100755 (executable)
@@ -53,8 +53,8 @@ namespace OIC
              * @param enrolleeResource an OCResource object corresponding to enrollee resource
              *        discovered in a network. The OCResource object can be obtained by calling
              *        OCPlatform.findResource() API. What resource you have to discover with
-             *        the OCPlatform.findResource() API is a "provisioning" resource with a certain
-             *        resource type, i.e. oic.wk.prov
+             *        the OCPlatform.findResource() API is a "easysetup" resource with a certain
+             *        resource type, i.e. oic.r.easysetup
              *
              * @throws ESBadRequestException If createEnrolleeDevice is invoked with the same
              *         provisioning information.
index 30ef55c..76ce155 100755 (executable)
@@ -59,6 +59,7 @@ namespace OIC
              *
              * @param callback will give the requested status
              *
+             * @throws ESInvalidParameterException If callback is null.
              * @throws ESBadRequestException If RemoteEnrollee device not created prior to this call.
              *
              * @see GetStatusCb
@@ -70,17 +71,19 @@ namespace OIC
              *
              * @param callback will give the requested configuration
              *
+             * @throws ESInvalidParameterException If callback is null.
              * @throws ESBadRequestException If RemoteEnrollee device not created prior to this call.
              *
              * @see GetConfigurationStatusCb
              */
             void getConfiguration(const GetConfigurationStatusCb callback);
 
-             /**
+            /**
              * Do security provisioning such as ownership tranfer to Enrollee.
              *
              * @param callback will give the result if the security provisioning succeeds or fails for some reasons
              *
+             * @throws ESInvalidParameterException If callback is null.
              * @throws ESBadRequestException If RemoteEnrollee device not created prior to this call.
              *
              * @see SecurityProvStatusCb
@@ -88,6 +91,20 @@ namespace OIC
             void provisionSecurity(const SecurityProvStatusCb callback);
 
             /**
+             * Do security provisioning such as ownership tranfer to Enrollee which may require more
+             * specific user selections like a type of ownership transfer method or pre-configured
+             * pin number used to Pre-configured pin-based MOT.
+             *
+             * @param callback will give the result if the security provisioning succeeds or fails for some reasons.
+             *
+             * @throws ESInvalidParameterException If callback is null.
+             * @throws ESBadRequestException If RemoteEnrollee device not created prior to this call.
+             *
+             * @see SecurityProvStatusCb
+             */
+            void provisionSecurity(const SecurityProvStatusCbWithOption callback);
+
+            /**
              * Provision WiFi AP information and device configuration to Enrollee
              * 1. WiFi AP information includes a SSID, password, auth type, and encryption type.
              * 2. Device configuration includes a language (IETF language tags) and country (ISO 3166-1 Alpha-2)
@@ -95,6 +112,7 @@ namespace OIC
              * @param devProp a data structure storing the above information to be delivered
              * @param callback will give the result if the provisioning succeeds or fails
              *
+             * @throws ESInvalidParameterException If callback is null.
              * @throws ESBadRequestException If RemoteEnrollee device not created prior to this call.
              *
              * @see DeviceProp
@@ -114,6 +132,7 @@ namespace OIC
              * @param cloudProp a data structure storing the above information to be delivered
              * @param callback will give the result if the provisioning succeeds or fails
              *
+             * @throws ESInvalidParameterException If callback is null.
              * @throws ESBadRequestException If RemoteEnrollee device not created prior to this call.
              *
              * @see CloudProp
@@ -122,13 +141,72 @@ namespace OIC
             void provisionCloudProperties(const CloudProp& cloudProp,
                                               const CloudPropProvStatusCb callback);
 
+            /**
+             * Provision Cloud information to Enrollee, which includes Auth code, auth provider,
+             * Cloud interface server URL, and etc.
+             * Note that, this API is skipping finding Enrollee in a given network. Instead, an OCResource
+             * given as a first parameter will be considered to the Enrollee for cloud provisioning.
+             *
+             * @param resource an OCResource corresponding to a target Enrollee for cloud provisioning
+             * @param cloudProp a data structure storing the above information to be delivered
+             * @param callback will give the result if the provisioning succeeds or fails
+             *
+             * @throws ESInvalidParameterException If callback is null.
+             * @throws ESBadRequestException If RemoteEnrollee device not created prior to this call.
+             *
+             * @see CloudProp
+             * @see CloudPropProvStatusCb
+             */
+            void provisionCloudProperties(const std::shared_ptr< OC::OCResource > resource,
+                                            const CloudProp& cloudProp,
+                                            const CloudPropProvStatusCb callback);
+
+            /**
+             * Notify an Enrollee to Connect WiFi/Cloud
+             *
+             * @param connectTypes Target configurations to be connected. E.g. WiFi and coap cloud server
+             * @param callback will give the result if the connect request succeeds or fails
+             *
+             * @see ES_CONNECT_TYPE
+             * @see ConnectRequestStatusCb
+             */
+            void requestToConnect(const std::vector<ES_CONNECT_TYPE> &connectTypes, const ConnectRequestStatusCb callback);
+
         private:
             RemoteEnrollee(const std::shared_ptr< OC::OCResource > resource);
 
             ESResult discoverResource();
 
             static void onDiscoveredCallback(const std::shared_ptr<OC::OCResource> resource,
-            std::weak_ptr<RemoteEnrollee> this_ptr);
+                std::weak_ptr<RemoteEnrollee> this_ptr);
+
+            static void onGetStatusHandlerCallback(
+                const std::shared_ptr< GetEnrolleeStatus > status,
+                std::weak_ptr<RemoteEnrollee> this_ptr);
+
+            static void onGetConfigurationStatusHandlerCallback(
+                const std::shared_ptr< GetConfigurationStatus > status,
+                std::weak_ptr<RemoteEnrollee> this_ptr);
+
+            static void onDevicePropProvisioningStatusHandlerCallback(
+                const std::shared_ptr< DevicePropProvisioningStatus > status,
+                std::weak_ptr<RemoteEnrollee> this_ptr);
+
+            static void onCloudPropProvisioningStatusHandlerCallback(
+                const std::shared_ptr< CloudPropProvisioningStatus > status,
+                std::weak_ptr<RemoteEnrollee> this_ptr);
+
+            static void onConnectRequestStatusHandlerCallback(
+                const std::shared_ptr< ConnectRequestStatus > status,
+                std::weak_ptr<RemoteEnrollee> this_ptr);
+
+            static void onSecurityStatusHandlerCallback(
+                const std::shared_ptr< SecProvisioningStatus > status,
+                std::weak_ptr<RemoteEnrollee> this_ptr);
+
+            static ESOwnershipTransferData onSecurityStatusWithOptionHandlerCallback(
+                const std::shared_ptr< SecProvisioningStatus > status,
+                std::weak_ptr<RemoteEnrollee> this_ptr);
 
             void onDeviceDiscovered(const std::shared_ptr<OC::OCResource> resource);
             void initCloudResource();
@@ -141,13 +219,18 @@ namespace OIC
                 (const std::shared_ptr< DevicePropProvisioningStatus > status) const;
             void cloudPropProvisioningStatusHandler
                 (const std::shared_ptr< CloudPropProvisioningStatus > status) const;
+            void connectRequestStatusHandler(
+                const std::shared_ptr< ConnectRequestStatus > status) const;
             void securityStatusHandler
                 (const std::shared_ptr< SecProvisioningStatus > status) const;
+            ESOwnershipTransferData securityStatusWithOptionHandler
+                (const std::shared_ptr< SecProvisioningStatus > status) const;
 
         private:
             std::shared_ptr< OC::OCResource > m_ocResource;
             std::shared_ptr< EnrolleeResource > m_enrolleeResource;
-            std::shared_ptr< EnrolleeSecurity > m_enrolleeSecurity;
+            std::shared_ptr< EnrolleeSecurity > m_localEnrolleeSecurity;
+            std::shared_ptr< EnrolleeSecurity > m_cloudEnrolleeSecurity;
             std::shared_ptr< CloudResource > m_cloudResource;
 
             std::string  m_deviceId;
@@ -157,12 +240,14 @@ namespace OIC
             std::condition_variable m_cond;
 
             SecurityProvStatusCb m_securityProvStatusCb;
+            SecurityProvStatusCbWithOption m_securityProvStatusCbWithOption;
             GetStatusCb m_getStatusCb;
             GetConfigurationStatusCb m_getConfigurationStatusCb;
             SecurityPinCb m_securityPinCb;
             SecProvisioningDbPathCb m_secProvisioningDbPathCb;
             DevicePropProvStatusCb m_devicePropProvStatusCb;
             CloudPropProvStatusCb m_cloudPropProvStatusCb;
+            ConnectRequestStatusCb m_connectRequestStatusCb;
 
             friend class EasySetup;
         };
index ea760ee..70b99cc 100755 (executable)
@@ -40,28 +40,44 @@ namespace OIC
             m_ocResource = resource;
         }
 
+        void CloudResource::onCloudProvResponseSafetyCb(const HeaderOptions& headerOptions,
+                                                                const OCRepresentation& rep,
+                                                                const int eCode,
+                                                                ESCloudResourceCb cb,
+                                                                std::weak_ptr<CloudResource> this_ptr)
+        {
+            OIC_LOG(DEBUG, ES_CLOUD_RES_TAG, "onCloudProvResponseSafetyCb");
+            std::shared_ptr<CloudResource> Ptr = this_ptr.lock();
+            if(Ptr)
+            {
+                cb(headerOptions, rep, eCode);
+            }
+        }
+
+
         void CloudResource::provisionProperties(const CloudProp& cloudProp)
         {
-            OIC_LOG (DEBUG, ES_CLOUD_RES_TAG, "provisionProperties IN");
+            OIC_LOG(DEBUG, ES_CLOUD_RES_TAG, "provisionProperties IN");
 
             OCRepresentation provisioningRepresentation = cloudProp.toOCRepresentation();
 
-            m_ocResource->post(OC_RSRVD_ES_RES_TYPE_PROV, BATCH_INTERFACE,
-                        provisioningRepresentation, QueryParamsMap(),
-                        std::function<
-                                void(const HeaderOptions& headerOptions,
-                                        const OCRepresentation& rep, const int eCode) >(
-                        std::bind(&CloudResource::onCloudProvResponse, this,
-                        std::placeholders::_1, std::placeholders::_2,
-                        std::placeholders::_3)), OC::QualityOfService::HighQos);
+            ESCloudResourceCb cb = std::bind(&CloudResource::onCloudProvResponseSafetyCb,
+                            std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
+                            static_cast<ESCloudResourceCb>(
+                            std::bind(&CloudResource::onCloudProvResponse, this,
+                            std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)),
+                            shared_from_this());
+
+            m_ocResource->post(OC_RSRVD_ES_RES_TYPE_EASYSETUP, BATCH_INTERFACE,
+                        provisioningRepresentation, QueryParamsMap(), cb, OC::QualityOfService::HighQos);
 
-            OIC_LOG (DEBUG, ES_CLOUD_RES_TAG, "provisionProperties OUT");
+            OIC_LOG(DEBUG, ES_CLOUD_RES_TAG, "provisionProperties OUT");
         }
 
         void CloudResource::onCloudProvResponse(const HeaderOptions& /*headerOptions*/,
                 const OCRepresentation& /*rep*/, const int eCode)
         {
-            OIC_LOG_V (DEBUG, ES_CLOUD_RES_TAG, "onCloudProvResponse : eCode = %d",
+            OIC_LOG_V(DEBUG, ES_CLOUD_RES_TAG, "onCloudProvResponse : eCode = %d",
                         eCode);
 
             if (eCode > OCStackResult::OC_STACK_RESOURCE_CHANGED)
@@ -72,7 +88,7 @@ namespace OIC
 
                 if(eCode == OCStackResult::OC_STACK_COMM_ERROR)
                 {
-                    OIC_LOG_V (DEBUG, ES_CLOUD_RES_TAG,
+                    OIC_LOG(DEBUG, ES_CLOUD_RES_TAG,
                             "can't receive any response from Enrollee by a timeout threshold.");
                     result = ESResult::ES_COMMUNICATION_ERROR;
                 }
old mode 100644 (file)
new mode 100755 (executable)
index 6a0c5bd..9f116fb
@@ -35,12 +35,15 @@ namespace OIC
     namespace Service
     {
         class OCResource;
+        typedef std::function<void(const HeaderOptions& headerOptions,
+                                   const OCRepresentation& rep,
+                                   const int eCode)> ESCloudResourceCb;
         /**
          * This class contains the resource discovery methods.
          *
          * @see CloudResource
          */
-        class CloudResource
+        class CloudResource : public std::enable_shared_from_this<CloudResource>
         {
         public:
             CloudResource(std::shared_ptr< OC::OCResource > resource);
@@ -51,6 +54,11 @@ namespace OIC
             void provisionProperties(const CloudProp& CloudProp);
 
         private:
+            static void onCloudProvResponseSafetyCb(const HeaderOptions& headerOptions,
+                                                    const OCRepresentation& rep,
+                                                    const int eCode,
+                                                    ESCloudResourceCb cb,
+                                                    std::weak_ptr<CloudResource> this_ptr);
             void onCloudProvResponse(const HeaderOptions& headerOptions,
                                                 const OCRepresentation& rep,
                                                 const int eCode);
index a579a0f..ef1a06a 100755 (executable)
@@ -31,7 +31,7 @@ namespace OIC
 {
     namespace Service
     {
-        #define EASYSETUP_TAG "EASY_SETUP"
+        #define EASYSETUP_TAG "ES_EASY_SETUP"
 
         EasySetup * EasySetup::s_instance = nullptr;
 
@@ -50,11 +50,11 @@ namespace OIC
 
         std::shared_ptr<RemoteEnrollee> EasySetup::createRemoteEnrollee (std::shared_ptr< OC::OCResource > resource)
         {
-            OIC_LOG(DEBUG, EASYSETUP_TAG, "createRemoteEnrollee IN");
+            OIC_LOG(INFO, EASYSETUP_TAG, "createRemoteEnrollee IN");
 
             if(resource)
             {
-                if(resource->getResourceTypes().at(0) != OC_RSRVD_ES_RES_TYPE_PROV ||
+                if(resource->getResourceTypes().at(0) != OC_RSRVD_ES_RES_TYPE_EASYSETUP ||
                    resource->connectivityType() & CT_ADAPTER_TCP)
                 {
                     OIC_LOG (ERROR, EASYSETUP_TAG, "Given resource is not valid due to wrong rt or conntype");
@@ -66,10 +66,11 @@ namespace OIC
                 {
                     if(interface.compare(BATCH_INTERFACE) == 0)
                     {
-                        OIC_LOG (DEBUG, EASYSETUP_TAG, "RemoteEnrollee object is succeessfully created");
-                        OIC_LOG_V (DEBUG, EASYSETUP_TAG, "HOST: %s", resource->host().c_str());
-                        OIC_LOG_V (DEBUG, EASYSETUP_TAG, "URI: %s", resource->uri().c_str());
-                        OIC_LOG_V (DEBUG, EASYSETUP_TAG, "SID: %s", resource->sid().c_str());
+                        OIC_LOG (INFO, EASYSETUP_TAG, "RemoteEnrollee object is succeessfully created");
+                        OIC_LOG_V (INFO_PRIVATE, EASYSETUP_TAG, "HOST: %s", resource->host().c_str());
+                        OIC_LOG_V (INFO_PRIVATE, EASYSETUP_TAG, "URI: %s", resource->uri().c_str());
+                        OIC_LOG_V (INFO_PRIVATE, EASYSETUP_TAG, "SID: %s", resource->sid().c_str());
+                        OIC_LOG_V (INFO_PRIVATE, EASYSETUP_TAG, "CONNECTIVITY: %d", resource->connectivityType());
                         return std::shared_ptr< RemoteEnrollee > (new RemoteEnrollee(resource));
                     }
                 }
index 17862a1..a1e35e9 100755 (executable)
@@ -36,24 +36,42 @@ namespace OIC
         EnrolleeResource::EnrolleeResource(std::shared_ptr< OC::OCResource > resource)
         {
             m_ocResource = resource;
+            m_getStatusCb = nullptr;
+            m_getConfigurationStatusCb = nullptr;
+            m_devicePropProvStatusCb = nullptr;
+            m_connectRequestStatusCb = nullptr;
+        }
+
+        void EnrolleeResource::onEnrolleeResourceSafetyCB(const HeaderOptions& headerOptions,
+                                                        const OCRepresentation& rep,
+                                                        const int eCode,
+                                                        ESEnrolleeResourceCb cb,
+                                                        std::weak_ptr<EnrolleeResource> this_ptr)
+        {
+            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "onEnrolleeResourceSafetyCB");
+            std::shared_ptr<EnrolleeResource> Ptr = this_ptr.lock();
+            if(Ptr)
+            {
+                cb(headerOptions, rep, eCode);
+            }
         }
 
         void EnrolleeResource::onProvisioningResponse(const HeaderOptions& /*headerOptions*/,
                 const OCRepresentation& /*rep*/, const int eCode)
         {
-            OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "onProvisioningResponse : eCode = %d",
+            OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "onProvisioningResponse : eCode = %d",
                         eCode);
 
             if (eCode > OCStackResult::OC_STACK_RESOURCE_CHANGED)
             {
                 ESResult result = ESResult::ES_ERROR;
 
-                OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
+                OIC_LOG(ERROR, ES_REMOTE_ENROLLEE_RES_TAG,
                             "onProvisioningResponse : Provisioning is failed ");
 
                 if(eCode == OCStackResult::OC_STACK_COMM_ERROR)
                 {
-                    OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
+                    OIC_LOG(ERROR, ES_REMOTE_ENROLLEE_RES_TAG,
                         "can't receive any response from Enrollee by a timeout threshold.");
                     result = ESResult::ES_COMMUNICATION_ERROR;
                 }
@@ -64,7 +82,7 @@ namespace OIC
                 return;
             }
 
-            OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
+            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
                     "onProvisioningResponse : Provisioning is success. ");
 
             std::shared_ptr< DevicePropProvisioningStatus > provStatus = std::make_shared<
@@ -75,19 +93,19 @@ namespace OIC
         void EnrolleeResource::onGetStatusResponse(const HeaderOptions& /*headerOptions*/,
                 const OCRepresentation& rep, const int eCode)
         {
-            OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "onGetStatusResponse : eCode = %d",
+            OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "onGetStatusResponse : eCode = %d",
                         eCode);
 
             if (eCode > OCStackResult::OC_STACK_RESOURCE_CHANGED)
             {
                 ESResult result = ESResult::ES_ERROR;
 
-                OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
+                OIC_LOG(ERROR, ES_REMOTE_ENROLLEE_RES_TAG,
                             "onGetStatusResponse : onGetStatusResponse is failed ");
 
                 if(eCode == OCStackResult::OC_STACK_COMM_ERROR)
                 {
-                    OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
+                    OIC_LOG(ERROR, ES_REMOTE_ENROLLEE_RES_TAG,
                         "can't receive any response from Enrollee by a timeout threshold.");
                     result = ESResult::ES_COMMUNICATION_ERROR;
                 }
@@ -111,19 +129,19 @@ namespace OIC
         void EnrolleeResource::onGetConfigurationResponse(const HeaderOptions& /*headerOptions*/,
                 const OCRepresentation& rep, const int eCode)
         {
-            OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "onGetConfigurationResponse : eCode = %d",
+            OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "onGetConfigurationResponse : eCode = %d",
                         eCode);
 
             if (eCode > OCStackResult::OC_STACK_RESOURCE_CHANGED)
             {
                 ESResult result = ESResult::ES_ERROR;
 
-                OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
+                OIC_LOG(ERROR, ES_REMOTE_ENROLLEE_RES_TAG,
                             "onGetConfigurationResponse : onGetConfigurationResponse is failed ");
 
                 if(eCode == OCStackResult::OC_STACK_COMM_ERROR)
                 {
-                    OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
+                    OIC_LOG(ERROR, ES_REMOTE_ENROLLEE_RES_TAG,
                         "can't receive any response from Enrollee by a timeout threshold.");
                     result = ESResult::ES_COMMUNICATION_ERROR;
                 }
@@ -143,6 +161,41 @@ namespace OIC
             }
         }
 
+         void EnrolleeResource::onConnectRequestResponse(const HeaderOptions& /*headerOptions*/,
+                const OCRepresentation& /*rep*/, const int eCode)
+        {
+            OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "onConnectRequestResponse : eCode = %d",
+                        eCode);
+
+            if (eCode > OCStackResult::OC_STACK_RESOURCE_CHANGED)
+            {
+                ESResult result = ESResult::ES_ERROR;
+
+                OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
+                            "onConnectRequestResponse : onConnectRequestResponse is failed ");
+
+                if(eCode == OCStackResult::OC_STACK_COMM_ERROR)
+                {
+                    OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
+                        "can't receive any response from Enrollee by a timeout threshold.");
+                    result = ESResult::ES_COMMUNICATION_ERROR;
+                }
+
+                std::shared_ptr< ConnectRequestStatus > connectRequestStatus = std::make_shared<
+                        ConnectRequestStatus >(result);
+                m_connectRequestStatusCb(connectRequestStatus);
+                return;
+            }
+
+            OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG,
+                    "onConnectRequestResponse : Provisioning is success. ");
+
+            std::shared_ptr< ConnectRequestStatus > connectRequestStatus = std::make_shared<
+                    ConnectRequestStatus >(ESResult::ES_OK);
+            m_connectRequestStatusCb(connectRequestStatus);
+        }
+
+
         void EnrolleeResource::registerGetStatusCallback(
             const GetStatusCb callback)
         {
@@ -161,9 +214,15 @@ namespace OIC
             m_devicePropProvStatusCb = callback;
         }
 
+        void EnrolleeResource::registerConnectRequestStatusCallback(
+            const ConnectRequestStatusCb callback)
+        {
+            m_connectRequestStatusCb = callback;
+        }
+
         void EnrolleeResource::getStatus()
         {
-            OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "getStatus IN");
+            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "getStatus IN");
 
             if (m_ocResource == nullptr)
             {
@@ -175,12 +234,15 @@ namespace OIC
 
             std::function< OCStackResult(void) > getStatus = [&]
             {
-                return m_ocResource->get(m_ocResource->getResourceTypes().at(0),
-                        DEFAULT_INTERFACE, query, std::function<void(const HeaderOptions& headerOptions,
-                        const OCRepresentation& rep, const int eCode) >(
+                ESEnrolleeResourceCb cb = std::bind(&EnrolleeResource::onEnrolleeResourceSafetyCB,
+                                std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
+                                static_cast<ESEnrolleeResourceCb>(
                                 std::bind(&EnrolleeResource::onGetStatusResponse, this,
-                                        std::placeholders::_1, std::placeholders::_2,
-                                        std::placeholders::_3)), OC::QualityOfService::HighQos);
+                                std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)),
+                                shared_from_this());
+
+                return m_ocResource->get(m_ocResource->getResourceTypes().at(0),
+                        DEFAULT_INTERFACE, query, cb, OC::QualityOfService::HighQos);
             };
 
             OCStackResult result = getStatus();
@@ -195,12 +257,12 @@ namespace OIC
 
                 return;
             }
-            OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "getStatus OUT");
+            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "getStatus OUT");
         }
 
         void EnrolleeResource::getConfiguration()
         {
-            OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "getConfiguration IN");
+            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "getConfiguration IN");
 
             if (m_ocResource == nullptr)
             {
@@ -212,12 +274,15 @@ namespace OIC
 
             std::function< OCStackResult(void) > getConfigurationStatus = [&]
             {
-                return m_ocResource->get(m_ocResource->getResourceTypes().at(0),
-                        BATCH_INTERFACE, query, std::function<void(const HeaderOptions& headerOptions,
-                        const OCRepresentation& rep, const int eCode) >(
+                ESEnrolleeResourceCb cb = std::bind(&EnrolleeResource::onEnrolleeResourceSafetyCB,
+                                std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
+                                static_cast<ESEnrolleeResourceCb>(
                                 std::bind(&EnrolleeResource::onGetConfigurationResponse, this,
-                                        std::placeholders::_1, std::placeholders::_2,
-                                        std::placeholders::_3)), OC::QualityOfService::HighQos);
+                                std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)),
+                                shared_from_this());
+
+                return m_ocResource->get(m_ocResource->getResourceTypes().at(0),
+                        BATCH_INTERFACE, query, cb, OC::QualityOfService::HighQos);
             };
 
             OCStackResult result = getConfigurationStatus();
@@ -231,12 +296,12 @@ namespace OIC
                 return;
             }
 
-            OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "getConfiguration OUT");
+            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "getConfiguration OUT");
         }
 
         void EnrolleeResource::provisionProperties(const DeviceProp& deviceProp)
         {
-            OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "provisionProperties IN");
+            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "provisionProperties IN");
             if (m_ocResource == nullptr)
             {
                 throw ESBadRequestException("Resource is not initialized");
@@ -245,16 +310,50 @@ namespace OIC
             OC::QueryParamsMap query;
             OC::OCRepresentation provisioningRepresentation = deviceProp.toOCRepresentation();
 
-            m_ocResource->post(OC_RSRVD_ES_RES_TYPE_PROV, BATCH_INTERFACE,
-                    provisioningRepresentation, QueryParamsMap(),
-                    std::function<
-                            void(const HeaderOptions& headerOptions,
-                                    const OCRepresentation& rep, const int eCode) >(
-                    std::bind(&EnrolleeResource::onProvisioningResponse, this,
-                    std::placeholders::_1, std::placeholders::_2,
-                    std::placeholders::_3)), OC::QualityOfService::HighQos);
+            ESEnrolleeResourceCb cb = std::bind(&EnrolleeResource::onEnrolleeResourceSafetyCB,
+                            std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
+                            static_cast<ESEnrolleeResourceCb>(
+                            std::bind(&EnrolleeResource::onProvisioningResponse, this,
+                            std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)),
+                            shared_from_this());
+
+            m_ocResource->post(OC_RSRVD_ES_RES_TYPE_EASYSETUP, BATCH_INTERFACE,
+                    provisioningRepresentation, QueryParamsMap(), cb, OC::QualityOfService::HighQos);
+
+            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "provisionProperties OUT");
+        }
+
+        void EnrolleeResource::requestToConnect(const std::vector<ES_CONNECT_TYPE> &connectTypes)
+        {
+            OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "requestToConnect IN");
+            if (m_ocResource == nullptr)
+            {
+                throw ESBadRequestException("Resource is not initialized");
+            }
+
+            OC::QueryParamsMap query;
+            OC::OCRepresentation requestRepresentation;
+            std::vector<int> connectTypes_int;
+            connectTypes_int.clear();
+
+            for(auto it : connectTypes)
+            {
+                connectTypes_int.push_back(static_cast<int>(it));
+            }
+
+            requestRepresentation.setValue<std::vector<int>>(OC_RSRVD_ES_CONNECT, connectTypes_int);
+
+            ESEnrolleeResourceCb cb = std::bind(&EnrolleeResource::onEnrolleeResourceSafetyCB,
+                            std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
+                            static_cast<ESEnrolleeResourceCb>(
+                            std::bind(&EnrolleeResource::onConnectRequestResponse, this,
+                            std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)),
+                            shared_from_this());
+
+            m_ocResource->post(OC_RSRVD_ES_RES_TYPE_EASYSETUP, OC_RSRVD_INTERFACE_DEFAULT,
+                    requestRepresentation, QueryParamsMap(), cb, OC::QualityOfService::HighQos);
 
-            OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "provisionProperties OUT");
+            OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_RES_TAG, "requestToConnect OUT");
         }
     }
 }
old mode 100644 (file)
new mode 100755 (executable)
index f194b45..f345a91
@@ -37,12 +37,15 @@ namespace OIC
         class OCResource;
         class EnrolleeSecurity;
 
+        typedef std::function<void(const HeaderOptions& headerOptions,
+                                   const OCRepresentation& rep,
+                                   const int eCode)> ESEnrolleeResourceCb;
         /**
          * This class contains the resource discovery methods.
          *
          * @see EnrolleeResource
          */
-        class EnrolleeResource
+        class EnrolleeResource : public std::enable_shared_from_this<EnrolleeResource>
         {
             friend class EnrolleeSecurity;
 
@@ -56,11 +59,13 @@ namespace OIC
                 const GetConfigurationStatusCb callback);
             void registerDevicePropProvStatusCallback(
                 const DevicePropProvStatusCb callback);
+            void registerConnectRequestStatusCallback(
+                const ConnectRequestStatusCb callback);
 
             void getConfiguration();
             void getStatus();
-
             void provisionProperties(const DeviceProp& deviceProp);
+            void requestToConnect(const std::vector<ES_CONNECT_TYPE> &connectTypes);
 
         private:
             std::shared_ptr< OC::OCResource > m_ocResource;
@@ -68,8 +73,16 @@ namespace OIC
             GetStatusCb m_getStatusCb;
             GetConfigurationStatusCb m_getConfigurationStatusCb;
             DevicePropProvStatusCb m_devicePropProvStatusCb;
+            ConnectRequestStatusCb m_connectRequestStatusCb;
 
         private:
+            static void onEnrolleeResourceSafetyCB(const HeaderOptions& headerOptions,
+                                    const OCRepresentation& rep,
+                                    const int eCode,
+                                    ESEnrolleeResourceCb cb,
+                                    std::weak_ptr<EnrolleeResource> this_ptr);
+
+
             void onGetStatusResponse(const HeaderOptions& headerOptions,
                                                 const OCRepresentation& rep,
                                                 const int eCode);
@@ -79,6 +92,9 @@ namespace OIC
             void onProvisioningResponse(const HeaderOptions& headerOptions,
                                                     const OCRepresentation& rep,
                                                     const int eCode);
+            void onConnectRequestResponse(const HeaderOptions& headerOptions,
+                                                    const OCRepresentation& rep,
+                                                    const int eCode);
         };
     }
 }
index a266426..03689cf 100755 (executable)
 #include "oic_string.h"
 #include "utlist.h"
 #include "srmutility.h"
+#include "aclresource.h"
+#include "internal/doxmresource.h"
+#include "ocrandom.h"
 
 namespace OIC
 {
     namespace Service
     {
+        namespace
+        {
+            static const char COAP[] = "coap://";
+            static const char COAPS[] = "coaps://";
+            static const char COAP_TCP[] = "coap+tcp://";
+            static const char COAP_GATT[] = "coap+gatt://";
+            static const char COAP_RFCOMM[] = "coap+rfcomm://";
+        }
+
         #define MAX_PERMISSION_LENGTH (5)
         #define CREATE (1)
         #define READ (2)
@@ -47,16 +59,31 @@ namespace OIC
         // TODO : Currently discovery timeout for owned and unowned devices is fixed as 5
         // The value should be accepted from the application as a parameter during ocplatform
         // config call
+
+#ifdef __APPLE__
+        #define ES_SEC_DISCOVERY_TIMEOUT 15
+#else
         #define ES_SEC_DISCOVERY_TIMEOUT 5
+#endif
 
-        EnrolleeSecurity::EnrolleeSecurity(
-            std::shared_ptr< OC::OCResource > resource,
-            const std::string secDbPath)
+        EnrolleeSecurity::EnrolleeSecurity(std::shared_ptr< OC::OCResource > resource)
         {
-            (void) secDbPath;
             m_ocResource = resource;
         }
 
+        void EnrolleeSecurity::onEnrolleeSecuritySafetyCB(OC::PMResultList_t *result,
+                                                        int hasError,
+                                                        ESSecurityCb cb,
+                                                        std::weak_ptr<EnrolleeSecurity> this_ptr)
+        {
+            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "onEnrolleeSecuritySafetyCB");
+            std::shared_ptr<EnrolleeSecurity> Ptr = this_ptr.lock();
+            if(Ptr)
+            {
+                cb(result, hasError);
+            }
+        }
+
         void EnrolleeSecurity::convertUUIDToString(const uint8_t uuid[UUID_SIZE],
                                                               std::string& uuidString)
         {
@@ -77,45 +104,695 @@ namespace OIC
             uuidString = uuidArray;
         }
 
-        void EnrolleeSecurity::ownershipTransferCb(OC::PMResultList_t *result, int hasError)
+        std::string EnrolleeSecurity::getResourceDeviceAddress(const std::string& host)
         {
-            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "ownershipTransferCb IN");
+            size_t prefix_len = 0;
+
+            if (host.compare(0, sizeof(COAP) - 1, COAP) == 0)
+            {
+                prefix_len = sizeof(COAP) - 1;
+            }
+            else if (host.compare(0, sizeof(COAPS) - 1, COAPS) == 0)
+            {
+                prefix_len = sizeof(COAPS) - 1;
+            }
+            else if (host.compare(0, sizeof(COAP_TCP) - 1, COAP_TCP) == 0)
+            {
+                prefix_len = sizeof(COAP_TCP) - 1;
+            }
+            else if (host.compare(0, sizeof(COAP_GATT) - 1, COAP_GATT) == 0)
+            {
+                prefix_len = sizeof(COAP_GATT) - 1;
+            }
+            else if (host.compare(0, sizeof(COAP_RFCOMM) - 1, COAP_RFCOMM) == 0)
+            {
+                prefix_len = sizeof(COAP_RFCOMM) - 1;
+            }
+            else
+            {
+                OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG,
+                    "Well-known prefix for connectivity is not found. Please check OCResource::setHost");
+                return {};
+            }
+
+            // remove prefix
+            std::string host_token = host.substr(prefix_len);
+
+            if (host_token[0] == '[') // IPv6
+            {
+                size_t bracket = host_token.find(']');
+
+                // extract the ipv6 address
+                return host_token.substr(0, bracket + 1);
+            }
+            else
+            {
+                size_t dot = host_token.find('.');
+                if (std::string::npos == dot) // MAC
+                {
+                    size_t semi_count = std::count(host_token.begin(), host_token.end(), ':');
+                    if (semi_count > 5)
+                    {
+                        size_t found_semi = host_token.find_last_of(':');
+                        host_token = host_token.substr(0, found_semi);
+                    }
+                    return host_token;
+                }
+                else // IPv4
+                {
+                    size_t colon = host_token.find(':');
+
+                    // extract the ipv4 address
+                    return host_token.substr(0, colon);
+                }
+            }
+        }
+
+        bool EnrolleeSecurity::isOwnerIDMatched(std::shared_ptr< OC::OCSecureResource > foundDevice)
+        {
+            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "isOwnerIDMatched IN");
+
+            if(foundDevice.get() == nullptr)
+            {
+                OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "foundDevice is NULL ptr");
+                return false;
+            }
+
+            bool ret = false;
+            std::string ownerID;
+            char uuidString[UUID_STRING_SIZE] = {};
+            if(RAND_UUID_OK == OCConvertUuidToString(foundDevice->getDevPtr()->doxm->owner.id, uuidString))
+            {
+                ownerID = uuidString;
+            }
+            else
+            {
+                ownerID = {};
+            }
+
+            OIC_LOG_V(INFO_PRIVATE, ENROLEE_SECURITY_TAG, "Mediator ID %s", m_mediatorID.c_str());
+            OIC_LOG_V(INFO_PRIVATE, ENROLEE_SECURITY_TAG, "Enrollee's Owner ID %s", ownerID.c_str());
+
+            if(ownerID == m_mediatorID)
+            {
+                OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG,
+                    "The found device's first owner ID is matched with Mediator's ID");
+                ret = true;
+            }
+            else
+            {
+                OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG,
+                    "The found device's first owner ID is NOT matched with Mediator's ID");
+            }
+
+            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "isOwnerIDMatched OUT");
+
+            return ret;
+        }
+
+#ifdef MULTIPLE_OWNER
+        bool EnrolleeSecurity::isSubOwnerIDMatched(std::shared_ptr< OC::OCSecureResource > foundDevice)
+        {
+            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "isSubOwnerIDMatched IN");
+
+            if(foundDevice.get() == nullptr)
+            {
+                OIC_LOG(ERROR, ENROLEE_SECURITY_TAG,
+                    "The found device's sub owner ID is NOT matched with Mediator's ID");
+
+                return false;
+            }
+
+            bool ret = false;
+            std::string subOwnerID;
+            char uuidString[UUID_STRING_SIZE] = {};
+
+            OicSecSubOwner_t* subOwnerList = foundDevice->getDevPtr()->doxm->subOwners;
+
+            while(subOwnerList)
+            {
+                if(RAND_UUID_OK == OCConvertUuidToString(subOwnerList->uuid.id, uuidString))
+                {
+                    subOwnerID = uuidString;
+                }
+                else
+                {
+                    subOwnerID = {};
+                }
+
+                if(subOwnerID == m_mediatorID)
+                {
+                    OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG,
+                    "The found device's owner ID is matched with Mediator's ID as a second owner");
+                    ret = true;
+                    break;
+                }
+                subOwnerList = subOwnerList->next;
+            }
+
+            if(!ret)
+            {
+                OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG,
+                    "The found device's sub owner ID is NOT matched with Mediator's ID");
+            }
+
+            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "isSubOwnerIDMatched OUT");
+            return ret;
+        }
+
+        void EnrolleeSecurity::changeMOTMethodCB(PMResultList_t *result, int hasError)
+        {
+            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "changeMOTMethodCB IN");
+            if (hasError)
+            {
+                OIC_LOG_V(ERROR, ENROLEE_SECURITY_TAG,
+                                "requestEnableMOTMode API is failed with error %d", hasError);
+                enableMOTModeResult = false;
+            }
+            else
+            {
+                OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "requestEnableMOTMode API is succeeded");
+                enableMOTModeResult = true;
+            }
+
+            delete result;
+            m_cond.notify_all();
+        }
+
+
+        void EnrolleeSecurity::selectMOTMethodCB(PMResultList_t *result, int hasError)
+        {
+            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "selectMOTMethodCB IN");
+            if (hasError)
+            {
+                OIC_LOG_V(ERROR, ENROLEE_SECURITY_TAG,
+                                "selectMOTMethod API is failed with error %d", hasError);
+                motMethodProvResult = false;
+            }
+            else
+            {
+                OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "selectMOTMethod API is succeeded");
+                motMethodProvResult = true;
+            }
+
+            delete result;
+            m_cond.notify_all();
+        }
+
+        void EnrolleeSecurity::preconfigPinProvCB(PMResultList_t *result, int hasError)
+        {
+            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "preconfigPinProvCB IN");
+            if (hasError)
+            {
+                OIC_LOG_V(ERROR, ENROLEE_SECURITY_TAG,
+                                "provisionPreconfPin API is failed with error %d", hasError);
+                preConfigPinProvResult = false;
+            }
+            else
+            {
+                OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "provisionPreconfPin API is succeeded");
+                preConfigPinProvResult = true;
+            }
+
+            delete result;
+            m_cond.notify_all();
+        }
+
+        void EnrolleeSecurity::multipleOwnershipTransferCb(OC::PMResultList_t *result, int hasError)
+        {
+            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "multipleOwnershipTransferCb IN");
+
+            otmResult = false;
+
             if (hasError)
             {
-                OIC_LOG_V(ERROR, ENROLEE_SECURITY_TAG, "OwnershipTransfer is failed with code(%d)", hasError);
-                OTMResult = false;
+                OIC_LOG_V(ERROR, ENROLEE_SECURITY_TAG, "multipleOwnershipTransferCb is failed with code(%d)", hasError);
+                otmResult = false;
+                m_cond.notify_all();
             }
             else
             {
-                OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "OwnershipTransfer is succeeded");
                 for (unsigned int i = 0; i < result->size(); i++)
                 {
-                    OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Result is = %d for device", result->at(i).res);
+                    std::string uuid;
+                    convertUUIDToString(result->at(i).deviceId.id, uuid);
+
+                    if(m_ocResource != NULL && m_ocResource->sid() == uuid)
+                    {
+                        if( OC_STACK_OK == result->at(i).res )
+                        {
+                            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "multipleOwnershipTransferCb is succeeded");
+                            OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Result is = %d", result->at(i).res);
+                            OIC_LOG_V(INFO_PRIVATE, ENROLEE_SECURITY_TAG, "device uuid : %s", uuid.c_str());
+
+                            otmResult = true;
+                        }
+                        else
+                        {
+                            OIC_LOG_V(ERROR, ENROLEE_SECURITY_TAG, "multipleOwnershipTransfer is failed with code(%d)", hasError);
+                            otmResult = false;
+                        }
+                    }
                 }
                 delete result;
-                OTMResult = true;
+                m_cond.notify_all();
             }
-            m_cond.notify_all();
         }
 
-        ESResult EnrolleeSecurity::provisionOwnership()
+        ESResult EnrolleeSecurity::requestSetPreconfPinData(const ESOwnershipTransferData& MOTData)
         {
-            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "provisionOwnership IN");
+            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "requestSetPreconfPinData IN");
+
+            ESResult res = ESResult::ES_ERROR;
+
+            OC::ResultCallBack preconfigPinProvCB = std::bind(
+                    &EnrolleeSecurity::onEnrolleeSecuritySafetyCB,
+                    std::placeholders::_1, std::placeholders::_2,
+                    static_cast<ESSecurityCb>(std::bind(&EnrolleeSecurity::preconfigPinProvCB,
+                    this, std::placeholders::_1, std::placeholders::_2)),
+                    shared_from_this());
+
+            std::string pin = MOTData.getPreConfiguredPin();
+
+            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "provisionPreconfPin is called.");
+            if(OC_STACK_OK != m_securedResource->provisionPreconfPin(
+                                    pin.c_str(), pin.length(), preconfigPinProvCB))
+            {
+                OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "provisionPreconfPin API error");
+                res = ESResult:: ES_PRE_CONFIG_PIN_PROVISIONING_FAILURE;
+                return res;
+            }
+
+            std::unique_lock<std::mutex> lck(m_mtx);
+            m_cond.wait(lck);
+
+            if(!preConfigPinProvResult)
+            {
+                OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "provisionPreconfPin is failed.");
+                res = ESResult:: ES_PRE_CONFIG_PIN_PROVISIONING_FAILURE;
+                return res;
+            }
+
+            return ESResult::ES_OK;
+        }
+
+        ESResult EnrolleeSecurity::requestSetMOTMethod(const ESOwnershipTransferData& MOTData)
+        {
+            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "requestSetMOTMethod IN");
 
             ESResult res = ESResult::ES_ERROR;
 
+            OC::ResultCallBack selectMOTMethodCB = std::bind(
+                    &EnrolleeSecurity::onEnrolleeSecuritySafetyCB,
+                    std::placeholders::_1, std::placeholders::_2,
+                    static_cast<ESSecurityCb>(std::bind(&EnrolleeSecurity::selectMOTMethodCB,
+                    this, std::placeholders::_1, std::placeholders::_2)),
+                    shared_from_this());
+
+            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "selectMOTMethod is called.");
+            if(OC_STACK_OK != m_securedResource->selectMOTMethod(
+                                    MOTData.getMOTMethod(),
+                                    selectMOTMethodCB))
+            {
+                OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "selectMOTMethod API error");
+                res = ESResult:: ES_MOT_METHOD_SELECTION_FAILURE;
+                return res;
+            }
+
+            std::unique_lock<std::mutex> lck(m_mtx);
+            m_cond.wait(lck);
+
+            if(!motMethodProvResult)
+            {
+                OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "selectMOTMethod is failed.");
+                res = ESResult:: ES_MOT_METHOD_SELECTION_FAILURE;
+                return res;
+            }
+
+            return ESResult::ES_OK;
+        }
+
+        ESResult EnrolleeSecurity::requestEnableMOTMode()
+        {
+            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "requestEnableMOTMode IN");
+            ESResult res = ESResult:: ES_ERROR;
+
+            OC::ResultCallBack changeMOTMethodCB = std::bind(
+                    &EnrolleeSecurity::onEnrolleeSecuritySafetyCB,
+                    std::placeholders::_1, std::placeholders::_2,
+                    static_cast<ESSecurityCb>(std::bind(&EnrolleeSecurity::changeMOTMethodCB,
+                    this, std::placeholders::_1, std::placeholders::_2)),
+                    shared_from_this());
+
+            if(OC_STACK_OK !=
+                m_securedResource->changeMOTMode(OIC_MULTIPLE_OWNER_ENABLE, changeMOTMethodCB))
+            {
+                OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "changeMOTMode is failed.");
+                return ESResult:: ES_MOT_ENABLING_FAILURE;
+            }
+
+            std::unique_lock<std::mutex> lck(m_mtx);
+            m_cond.wait(lck);
+
+            if(!enableMOTModeResult)
+            {
+                OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "requestEnableMOTMode is failed.");
+                res = ESResult:: ES_MOT_ENABLING_FAILURE;
+                return res;
+            }
+
+            return ESResult::ES_OK;
+        }
+
+        ESResult EnrolleeSecurity::provisionMOTConfig(const ESOwnershipTransferData& MOTData)
+        {
+            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "provisionMOTConfig IN");
+            ESResult res = ESResult:: ES_ERROR;
+
+            if(!m_securedResource->isMOTEnabled())
+            {
+                res = requestEnableMOTMode();
+                if(res != ESResult::ES_OK)
+                {
+                    OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "requestEnableMOTMode is failed.");
+                    return res;
+                }
+            }
+
+            if( OIC_PRECONFIG_PIN == MOTData.getMOTMethod() &&
+                !MOTData.getPreConfiguredPin().empty())
+            {
+                res = requestSetPreconfPinData(MOTData);
+
+                if(res != ESResult::ES_OK)
+                {
+                    OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "RequestSetPreconfPinData is failed.");
+                    return res;
+                }
+            }
+            if(OIC_PRECONFIG_PIN == MOTData.getMOTMethod() ||
+               OIC_RANDOM_DEVICE_PIN == MOTData.getMOTMethod())
+            {
+                res = requestSetMOTMethod(MOTData);
+
+                if(res != ESResult::ES_OK)
+                {
+                    OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "RequestSetMOTMethod is failed.");
+                    return res;
+                }
+            }
+            return res;
+        }
+#endif
+
+        void EnrolleeSecurity::ownershipTransferCb(OC::PMResultList_t *result, int hasError
+                                                   , ESResult& res)
+        {
+            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "ownershipTransferCb IN");
+
+            otmResult = false;
+
+            if (hasError)
+            {
+                for (unsigned int i = 0; i < result->size(); i++)
+                {
+                    std::string uuid;
+                    convertUUIDToString(result->at(i).deviceId.id, uuid);
+
+                    if(m_ocResource != NULL && m_ocResource->sid() == uuid)
+                    {
+                        if(OC_STACK_USER_DENIED_REQ == result->at(i).res)
+                        {
+                            res = ESResult::ES_USER_DENIED_CONFIRMATION_REQ;
+                        }
+                        else if(OC_STACK_AUTHENTICATION_FAILURE  == result->at(i).res)
+                        {
+                            OicSecOxm_t oxm = OIC_OXM_COUNT;
+                            if(OC_STACK_OK != m_securedResource->getOTMethod(&oxm))
+                            {
+                                otmResult = false;
+                                return;
+                            }
+
+                            if(OIC_MANUFACTURER_CERTIFICATE == oxm)
+                            {
+                                res = ESResult::ES_AUTHENTICATION_FAILURE_WITH_WRONG_CERT;
+                            }
+                            else if(OIC_CON_MFG_CERT == oxm)
+                            {
+                                res = ESResult::ES_AUTHENTICATION_FAILURE_WITH_WRONG_CERT;
+                            }
+                            else if(OIC_RANDOM_DEVICE_PIN == oxm)
+                            {
+                                res = ESResult::ES_AUTHENTICATION_FAILURE_WITH_WRONG_PIN;
+                            }
+                        }
+                        else if(OC_STACK_COMM_ERROR == result->at(i).res)
+                        {
+                            OIC_LOG(ERROR, ENROLEE_SECURITY_TAG,
+                                "OwnershipTransfer is failed with OC_STACK_COMM_ERROR");
+                            res = ESResult::ES_COMMUNICATION_ERROR;
+                        }
+                        else if(OC_STACK_TIMEOUT == result->at(i).res)
+                        {
+                            OIC_LOG(ERROR, ENROLEE_SECURITY_TAG,
+                                "OwnershipTransfer is failed with OC_STACK_TIMEOUT");
+                            res = ESResult::ES_COMMUNICATION_ERROR;
+                        }
+                        else if(OC_STACK_GATEWAY_TIMEOUT== result->at(i).res)
+                        {
+                            OIC_LOG(ERROR, ENROLEE_SECURITY_TAG,
+                                "OwnershipTransfer is failed with OC_STACK_GATEWAY_TIMEOUT");
+                            res = ESResult::ES_COMMUNICATION_ERROR;
+                        }
+                    }
+                }
+                OIC_LOG_V(ERROR, ENROLEE_SECURITY_TAG, "OwnershipTransfer is failed with ESResult(%d)", res);
+
+                otmResult = false;
+            }
+            else
+            {
+                for (unsigned int i = 0; i < result->size(); i++)
+                {
+                    std::string uuid;
+                    convertUUIDToString(result->at(i).deviceId.id, uuid);
+
+                    if(m_ocResource != NULL && m_ocResource->sid() == uuid)
+                    {
+                        if( OC_STACK_OK == result->at(i).res )
+                        {
+                            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "OwnershipTransfer is succeeded");
+                            OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Result is = %d", result->at(i).res);
+                            OIC_LOG_V(INFO_PRIVATE, ENROLEE_SECURITY_TAG, "device uuid : %s", uuid.c_str());
+
+                            otmResult = true;
+                        }
+                        else
+                        {
+                            OIC_LOG_V(ERROR, ENROLEE_SECURITY_TAG, "OwnershipTransfer is failed with code(%d)", hasError);
+                            otmResult = false;
+                        }
+                    }
+                }
+            }
+
+            delete result;
+            m_cond.notify_all();
+        }
+
+        ESResult EnrolleeSecurity::discoverTargetSecureResource()
+        {
+            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "discoverTargetSecureResource IN");
+
             OCStackResult result = OC_STACK_ERROR;
+
             OicUuid_t uuid;
             if(OC_STACK_OK != ConvertStrToUuid(m_ocResource->sid().c_str(), &uuid))
             {
                 OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "Convert to uuid from deviceID failed.");
+                return ES_ERROR;
+            }
+
+            // If a discovered resource uses BLE transport, unicast for secure resource discovery is
+            // used.
+            if( m_ocResource->connectivityType() & CT_ADAPTER_GATT_BTLE )
+            {
+                std::string GattAddress = getResourceDeviceAddress(m_ocResource->host());
+                if(!GattAddress.empty())
+                {
+                    result = OCSecure::discoverSingleDeviceInUnicast(ES_SEC_DISCOVERY_TIMEOUT,
+                                                            &uuid,
+                                                            GattAddress,
+                                                            m_ocResource->connectivityType(),
+                                                            m_securedResource);
+                    if(result != OC_STACK_OK)
+                    {
+                        return ES_SECURE_RESOURCE_DISCOVERY_FAILURE;
+                    }
+                }
+                else
+                {
+                    OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "GATT BTLE address format is wrong.");
+                    return ES_ERROR;
+                }
+            }
+            else
+            {
+                result = OCSecure::discoverSingleDevice(ES_SEC_DISCOVERY_TIMEOUT,
+                                                        &uuid,
+                                                        m_securedResource);
+                if(result != OC_STACK_OK)
+                {
+                    return ES_SECURE_RESOURCE_DISCOVERY_FAILURE;
+                }
+            }
+
+            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "Secured resource is found.");
+            OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "HOST: %s", m_securedResource->getDevAddr().c_str());
+            OIC_LOG_V(INFO_PRIVATE, ENROLEE_SECURITY_TAG, "SID: %s", m_securedResource->getDeviceID().c_str());
+            OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Owned status: %d", m_securedResource->getOwnedStatus());
+
+            OicSecOxm_t selectedOTMethod = OIC_OXM_COUNT;
+            if( OC_STACK_OK != m_securedResource->getOTMethod(&selectedOTMethod) )
+            {
+                selectedOTMethod = OIC_OXM_COUNT; // Out-of-range
+            }
+            OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Selected OT Method: %d", (int)(selectedOTMethod));
+#ifdef MULTIPLE_OWNER
+            OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "MOT Supported: %d", (int)(m_securedResource->isMOTSupported()));
+            OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "MOT Enabled: %d", (int)(m_securedResource->isMOTEnabled()));
+#endif
+            if(m_securedResource->getOwnedStatus())
+            {
+                char uuidString[UUID_STRING_SIZE] = {};
+                if(RAND_UUID_OK == OCConvertUuidToString(m_securedResource->getDevPtr()->doxm->owner.id, uuidString))
+                {
+                    OIC_LOG_V(INFO_PRIVATE, ENROLEE_SECURITY_TAG, "Owner ID: %s", uuidString);
+                }
+                else
+                {
+                    OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "OCConvertUuidToString is failed");
+                }
+            }
+
+            return ES_OK;
+        }
+
+        ESOwnershipTransferData EnrolleeSecurity::getOwnershipTransferDataFromUser
+                                            (SecurityProvStatusCbWithOption callback)
+        {
+            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "getOwnershipTransferDataFromUser IN");
+            ESOwnershipTransferData ownershipTransferData;
+
+            std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
+                             std::make_shared< SecProvisioningStatus >
+                                           (m_securedResource,
+                                           ESResult::ES_SECURE_RESOURCE_IS_DISCOVERED);
+            ownershipTransferData = callback(securityProvisioningStatus);
+#ifdef MULTIPLE_OWNER
+            if(OIC_RANDOM_DEVICE_PIN == ownershipTransferData.getMOTMethod())
+            {
+                OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "Selected MOT Method: OIC_RANDOM_DEVICE_PIN");
+            }
+            else if(OIC_PRECONFIG_PIN == ownershipTransferData.getMOTMethod())
+            {
+                OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "Selected MOT Method: OIC_PRECONFIG_PIN");
+                OIC_LOG_V(INFO_PRIVATE, ENROLEE_SECURITY_TAG, "Pre-configured PIN: %s",
+                                    ownershipTransferData.getPreConfiguredPin().c_str());
+            }
+#endif
+            return ownershipTransferData;
+        }
+
+        ESResult EnrolleeSecurity::syncUpWithMediatorDB()
+        {
+            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "syncUpWithMediatorDB IN");
+
+            OCStackResult result = OC_STACK_ERROR;
+            ESResult res = ESResult::ES_ERROR;
+
+            OC::ResultCallBack removeDeviceWithUuidCB = std::bind(
+                    &EnrolleeSecurity::onEnrolleeSecuritySafetyCB,
+                    std::placeholders::_1, std::placeholders::_2,
+                    static_cast<ESSecurityCb>(std::bind(&EnrolleeSecurity::removeDeviceWithUuidCB,
+                    this, std::placeholders::_1, std::placeholders::_2)),
+                    shared_from_this());
+
+            result = OCSecure::removeDeviceWithUuid(ES_SEC_DISCOVERY_TIMEOUT,
+                                                    m_ocResource->sid(),
+                                                    removeDeviceWithUuidCB);
+            if(result != OC_STACK_OK)
+            {
+                OIC_LOG_V(ERROR, ENROLEE_SECURITY_TAG, "removeDeviceWithUuid failed. (%d)", result);
+                res = ESResult::ES_OWNERSHIP_IS_NOT_SYNCHRONIZED;
                 return res;
             }
 
-            result = OCSecure::discoverSingleDevice(ES_SEC_DISCOVERY_TIMEOUT,
-                                                    &uuid,
-                                                    m_securedResource);
-            if (result != OC_STACK_OK)
+            std::unique_lock<std::mutex> lck(m_mtx);
+            m_cond.wait_for(lck, std::chrono::seconds(ES_SEC_DISCOVERY_TIMEOUT));
+
+            if(!removeDeviceResult)
+            {
+                OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "Removing device is failed.");
+                res = ESResult::ES_OWNERSHIP_IS_NOT_SYNCHRONIZED;
+                return res;
+            }
+            return ESResult::ES_OK;
+        }
+
+        std::string EnrolleeSecurity::getMediatorDevID()
+        {
+            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "getMediatorDevID IN");
+            OCUUIdentity* mediatorDevId = (OCUUIdentity* )OICMalloc(sizeof(OCUUIdentity));
+            if(!mediatorDevId)
+            {
+                OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "provisionOwnership: OICMalloc error return");
+                return {};
+            }
+
+            if(OC::OCPlatform::getDeviceId(mediatorDevId) != OC_STACK_OK)
+            {
+                OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "getDeviceId is failed.");
+                OICFree(mediatorDevId);
+                return {};
+            }
+
+            char uuidString[UUID_STRING_SIZE] = {};
+            if(RAND_UUID_OK == OCConvertUuidToString(mediatorDevId->id, uuidString))
+            {
+                OIC_LOG_V(INFO_PRIVATE, ENROLEE_SECURITY_TAG, "Mediator UUID : %s", uuidString);
+                OICFree(mediatorDevId);
+                return std::string(uuidString);
+            }
+
+            OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "OCConvertUuidToString is failed.");
+            OICFree(mediatorDevId);
+            return {};
+        }
+
+        ESResult EnrolleeSecurity::provisionOwnership(SecurityProvStatusCbWithOption callback)
+        {
+            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "provisionOwnership IN");
+
+            ESResult res = ESResult:: ES_ERROR;
+
+            ESOwnershipTransferData ownershipTransferData;
+
+            std::string mediatorDevIdStr = getMediatorDevID();
+            if(mediatorDevIdStr.empty())
+            {
+                OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "getMediatorDevID is failed.");
+                return res;
+            }
+            else
+            {
+                m_mediatorID = mediatorDevIdStr;
+            }
+
+            res = discoverTargetSecureResource();
+
+            if (res != ES_OK)
             {
                 OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "Secure Resource Discovery failed.");
                 res = ESResult:: ES_SECURE_RESOURCE_DISCOVERY_FAILURE;
@@ -123,76 +800,148 @@ namespace OIC
             }
             else if (m_securedResource)
             {
-                OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "Secured resource is found.");
-                OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "HOST: %s", m_securedResource->getDevAddr().c_str());
-                OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "SID: %s", m_securedResource->getDeviceID().c_str());
-                OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Owned status: %d", m_securedResource->getOwnedStatus());
+                if(callback != NULL)
+                {
+                    ownershipTransferData = getOwnershipTransferDataFromUser(callback);
+                }
 
-                if (m_securedResource->getOwnedStatus()) // owned check logic
+                if(m_securedResource->getOwnedStatus())
                 {
-                    if(isOwnedDeviceRegisteredInSVRDB())
+                    if(isOwnedDeviceRegisteredInDB())
                     {
-                        OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG,
+#ifdef MULTIPLE_OWNER
+                        if(isSubOwnerIDMatched(m_securedResource))
+                        {
+                            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG,
                                 "The found device is already owned by Mediator.(SUCCESS)");
-                        res = ESResult::ES_OK;
+                            res = ESResult::ES_OK;
+                            return res;
+                        }
+
+                        if(isOwnerIDMatched(m_securedResource))
+                        {
+                            if((OIC_PRECONFIG_PIN == ownershipTransferData.getMOTMethod() ||
+                                OIC_RANDOM_DEVICE_PIN == ownershipTransferData.getMOTMethod()))
+                            {
+                                if(m_securedResource->isMOTSupported())
+                                {
+                                    res = provisionMOTConfig(ownershipTransferData);
+                                    if(res != ES_OK)
+                                    {
+                                        OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG,
+                                            "provisionMOTConfig is failed.");
+                                        return res;
+                                    }
+                                    OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG,
+                                        "The found device is already owned by Mediator and enabled MOT mode.");
+                                    return res;
+                                }
+                                else
+                                {
+                                    OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG,
+                                        "The found device is not supported MOT");
+                                    return ESResult:: ES_MOT_NOT_SUPPORTED;
+                                }
+                            }
+                            else
+                            {
+                                OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG,
+                                    "The found device is already owned by Mediator.(SUCCESS)");
+                                res = ESResult::ES_OK;
+                                return res;
+                            }
+                        }
+
+                        OIC_LOG(ERROR, ENROLEE_SECURITY_TAG,
+                            "An ownership transfer knowledge is not synchronized"
+                            "between mediator and found enrollee.(FAILED)");
+                        res = ESResult::ES_OWNERSHIP_IS_NOT_SYNCHRONIZED;
+                        return res;
+#else
+                        if(isOwnerIDMatched(m_securedResource))
+                        {
+                            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG,
+                                "The found device is already owned by Mediator.(SUCCESS)");
+                            res = ESResult::ES_OK;
+                            return res;
+                        }
+                        else
+                        {
+                            OIC_LOG(ERROR, ENROLEE_SECURITY_TAG,
+                                "An ownership transfer knowledge is not synchronized"
+                                "between mediator and found enrollee.(FAILED)");
+                            res = ESResult::ES_OWNERSHIP_IS_NOT_SYNCHRONIZED;
+                            return res;
+                        }
+#endif
+                    }
+#ifdef MULTIPLE_OWNER
+                    else if( !isOwnedDeviceRegisteredInDB() &&
+                             !isOwnerIDMatched(m_securedResource) &&
+                             !isSubOwnerIDMatched(m_securedResource) &&
+                             m_securedResource->isMOTEnabled() &&
+                             (OIC_PRECONFIG_PIN == ownershipTransferData.getMOTMethod() ||
+                              OIC_RANDOM_DEVICE_PIN == ownershipTransferData.getMOTMethod()))
+                    {
+                        // MOT case;
+                        res = performMultipleOwnershipTransfer(ownershipTransferData);
+
+                        if(res != ESResult::ES_OK)
+                        {
+                            OIC_LOG_V(ERROR, ENROLEE_SECURITY_TAG,
+                                            "Multiple Ownership-Transfer failed. (%d)", res);
+                            return res;
+                        }
+                    }
+                    else if( !isOwnedDeviceRegisteredInDB() &&
+                             (isOwnerIDMatched(m_securedResource) ||
+                             isSubOwnerIDMatched(m_securedResource)))
+#else
+                    else if( !isOwnedDeviceRegisteredInDB() && isOwnerIDMatched(m_securedResource))
+#endif
+                    {
+                        OIC_LOG(ERROR, ENROLEE_SECURITY_TAG,
+                        "An ownership transfer knowledge is not synchronized between mediator and found enrollee.(FAILED)");
+                        res = ESResult::ES_OWNERSHIP_IS_NOT_SYNCHRONIZED;
+                        return res;
                     }
                     else
                     {
-                        OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "The found device is not one in SVR DB");
-                        res = ESResult::ES_ERROR;
+                        OIC_LOG(ERROR, ENROLEE_SECURITY_TAG,
+                            "The found device is already owned by Other Mediator.(FAILED)");
+                        res = ESResult::ES_OWNERSHIP_TRANSFER_FAILURE;
+                        return res;
                     }
-                    return res;
                 }
-                else // unowned check logic
+                else
                 {
-                    if(isOwnedDeviceRegisteredInSVRDB())
+                    if(isOwnedDeviceRegisteredInDB())
                     {
-                        OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG,
-                            "Found Unowned device's DevID at DB of ownedDevices list");
-
-                        OC::ResultCallBack removeDeviceWithUuidCB = std::bind(
-                                &EnrolleeSecurity::removeDeviceWithUuidCB,
-                                this, std::placeholders::_1, std::placeholders::_2);
+                        res = syncUpWithMediatorDB();
 
-                        result = OCSecure::removeDeviceWithUuid(ES_SEC_DISCOVERY_TIMEOUT,
-                                                                m_ocResource->sid(),
-                                                                removeDeviceWithUuidCB);
-                        if(result != OC_STACK_OK)
+                        if(res != ESResult::ES_OK)
                         {
-                            OIC_LOG_V(ERROR, ENROLEE_SECURITY_TAG, "removeDeviceWithUuid failed. (%d)", result);
-                            res = ESResult::ES_OWNERSHIP_TRANSFER_FAILURE;
-                            return res;
-                        }
-
-                        std::unique_lock<std::mutex> lck(m_mtx);
-                        m_cond.wait_for(lck, std::chrono::seconds(ES_SEC_DISCOVERY_TIMEOUT));
-
-                        if(!removeDeviceResult)
-                        {
-                            OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "Removing device is failed.");
-                            res = ESResult::ES_OWNERSHIP_TRANSFER_FAILURE;
+                            OIC_LOG_V(ERROR, ENROLEE_SECURITY_TAG,
+                                            "syncUpWithMediatorDB failed. (%d)", res);
                             return res;
                         }
                         OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "Removing device is succeeded.");
                     }
-
                     res = performOwnershipTransfer();
 
                     if(res != ESResult::ES_OK)
                     {
                         OIC_LOG_V(ERROR, ENROLEE_SECURITY_TAG, "Ownership-Transfer failed. (%d)", res);
-                        res = ESResult::ES_OWNERSHIP_TRANSFER_FAILURE;
                         return res;
                     }
-
-                    std::unique_lock<std::mutex> lck(m_mtx);
-                    m_cond.wait(lck);
-
-                    if(!OTMResult)
+#ifdef MULTIPLE_OWNER
+                    if( m_securedResource->isMOTSupported() &&
+                        ownershipTransferData.getMOTMethod() != OIC_OXM_COUNT)
                     {
-                        OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "Ownership-Transfer failed.");
-                        res = ESResult::ES_OWNERSHIP_TRANSFER_FAILURE;
+                        res = provisionMOTConfig(ownershipTransferData);
                     }
+                    return res;
+#endif
                 }
             }
             else
@@ -208,30 +957,93 @@ namespace OIC
             OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "performOwnershipTransfer IN.");
 
             OCStackResult result = OC_STACK_ERROR;
+            ESResult res = ESResult::ES_ERROR;
 
-            OTMCallbackData_t justWorksCBData;
-            justWorksCBData.loadSecretCB = LoadSecretJustWorksCallback;
-            justWorksCBData.createSecureSessionCB = CreateSecureSessionJustWorksCallback;
-            justWorksCBData.createSelectOxmPayloadCB = CreateJustWorksSelectOxmPayload;
-            justWorksCBData.createOwnerTransferPayloadCB =
-                    CreateJustWorksOwnerTransferPayload;
-            OCSecure::setOwnerTransferCallbackData(OIC_JUST_WORKS, &justWorksCBData, NULL);
-
-            OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Transfering ownership for : %s ",
+            OIC_LOG_V(INFO_PRIVATE, ENROLEE_SECURITY_TAG, "Transfering ownership for : %s ",
                     m_securedResource->getDeviceID().c_str());
 
-            OC::ResultCallBack ownershipTransferCb = std::bind(
-                    &EnrolleeSecurity::ownershipTransferCb, this, std::placeholders::_1,
-                    std::placeholders::_2);
+            OC::ResultCallBack ownershipTransferCb =
+                std::bind(&EnrolleeSecurity::onEnrolleeSecuritySafetyCB,
+                          std::placeholders::_1, std::placeholders::_2,
+                          static_cast<ESSecurityCb>(std::bind(&EnrolleeSecurity::ownershipTransferCb,
+                          this, std::placeholders::_1, std::placeholders::_2, std::ref(res))),
+                          shared_from_this());
+
 
+            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "doOwnershipTransfer is excuted");
             result = m_securedResource->doOwnershipTransfer(ownershipTransferCb);
+
             if (result != OC_STACK_OK)
             {
                 OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "doOwnershipTransfer is failed");
                 return ESResult::ES_ERROR;
             }
+
+            std::unique_lock<std::mutex> lck(m_mtx);
+            m_cond.wait(lck);
+
+            if(!otmResult)
+            {
+                OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "Ownership-Transfer failed.");
+                return res;
+            }
+
+            return ESResult::ES_OK;
+        }
+
+#ifdef MULTIPLE_OWNER
+        ESResult EnrolleeSecurity::performMultipleOwnershipTransfer(const ESOwnershipTransferData& MOTdata)
+        {
+            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "performMultipleOwnershipTransfer IN.");
+
+            OCStackResult result = OC_STACK_ERROR;
+
+            OIC_LOG_V(INFO_PRIVATE, ENROLEE_SECURITY_TAG, "Transfering sub-ownership for : %s ",
+                    m_securedResource->getDeviceID().c_str());
+
+            if(OIC_PRECONFIG_PIN == MOTdata.getMOTMethod() &&
+               !MOTdata.getPreConfiguredPin().empty())
+            {
+                std::string pin = MOTdata.getPreConfiguredPin();
+
+                result = m_securedResource->addPreconfigPIN(pin.c_str(), pin.length());
+                if(OC_STACK_OK != result)
+                {
+                    OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "addPreconfigPIN is failed");
+                    return ESResult::ES_ERROR;
+                }
+
+                OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Preconfig PIN : %s", pin.c_str());
+            }
+
+            OC::ResultCallBack multipleOwnershipTransferCb =
+                std::bind(&EnrolleeSecurity::onEnrolleeSecuritySafetyCB,
+                          std::placeholders::_1, std::placeholders::_2,
+                          static_cast<ESSecurityCb>(std::bind(&EnrolleeSecurity::multipleOwnershipTransferCb,
+                          this, std::placeholders::_1, std::placeholders::_2)),
+                          shared_from_this());
+
+            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "doMultipleOwnershipTransfer is excuted");
+
+            result = m_securedResource->doMultipleOwnershipTransfer(multipleOwnershipTransferCb);
+            if(OC_STACK_OK != result)
+            {
+                OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "doMultipleOwnershipTransfer is failed");
+                return ESResult::ES_ERROR;
+            }
+
+            std::unique_lock<std::mutex> lck(m_mtx);
+            m_cond.wait(lck);
+
+            if(!otmResult)
+            {
+                OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "Multiple Ownership-Transfer failed.");
+                return ESResult::ES_OWNERSHIP_TRANSFER_FAILURE;
+            }
+
             return ESResult::ES_OK;
         }
+#endif
 
         void EnrolleeSecurity::removeDeviceWithUuidCB(OC::PMResultList_t *result, int hasError)
         {
@@ -252,16 +1064,18 @@ namespace OIC
                     std::string uuid;
                     convertUUIDToString(result->at(i).deviceId.id, uuid);
 
-                    OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG,
-                        "Result is = %d for device %s",  result->at(i).res, uuid.c_str());
+                    OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Result is = %d", result->at(i).res);
+                    OIC_LOG_V(INFO_PRIVATE, ENROLEE_SECURITY_TAG, "device uuid : %s", uuid.c_str());
                }
                removeDeviceResult = true;
             }
             m_cond.notify_all();
         }
 
-        bool EnrolleeSecurity::isOwnedDeviceRegisteredInSVRDB()
+        bool EnrolleeSecurity::isOwnedDeviceRegisteredInDB()
         {
+            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "isOwnedDeviceRegisteredInDB IN");
+
             OCStackResult res = OC_STACK_ERROR;
 
             OCUuidList_t *uuidList = NULL;
@@ -271,6 +1085,7 @@ namespace OIC
             if (OC_STACK_OK != res)
             {
                 OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "Error while getting info from DB");
+                OICFree(uuidList);
                 return false;
             }
 
@@ -279,7 +1094,7 @@ namespace OIC
             {
                 std::string uuid;
                 convertUUIDToString(pUuidList->dev.id, uuid);
-                OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG,
+                OIC_LOG_V(INFO_PRIVATE, ENROLEE_SECURITY_TAG,
                     "m_ocResource->sid(): %s, cur DB UUID %s",
                     m_ocResource->sid().c_str(), uuid.c_str());
                 if(m_ocResource->sid() == uuid.c_str())
@@ -310,7 +1125,7 @@ namespace OIC
             // Need to discover Owned device in a given network, again
             std::shared_ptr< OC::OCSecureResource > ownedDevice = NULL;
 
-            OCStackResult result;
+            OCStackResult result = OC_STACK_ERROR;
             OicUuid_t uuid;
             if(OC_STACK_OK != ConvertStrToUuid(m_ocResource->sid().c_str(), &uuid))
             {
@@ -318,10 +1133,33 @@ namespace OIC
                 return res;
             }
 
+            // If a discovered resource uses BLE transport, unicast for secure resource discovery is
+            // used.
+            if( m_ocResource->connectivityType() & CT_ADAPTER_GATT_BTLE )
+            {
+                std::string GattAddress = getResourceDeviceAddress(m_ocResource->host());
+                if(!GattAddress.empty())
+                {
+                    result = OCSecure::discoverSingleDeviceInUnicast(ES_SEC_DISCOVERY_TIMEOUT,
+                                                            &uuid,
+                                                            GattAddress,
+                                                            m_ocResource->connectivityType(),
+                                                            ownedDevice);
+                }
+                else
+                {
+                    OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "GATT BTLE address format is wrong.");
+                    res = ESResult:: ES_ERROR;
+                    return res;
+                }
+            }
+            else
+            {
+                result = OCSecure::discoverSingleDevice(ES_SEC_DISCOVERY_TIMEOUT,
+                                                        &uuid,
+                                                        ownedDevice);
+            }
 
-            result = OCSecure::discoverSingleDevice(ES_SEC_DISCOVERY_TIMEOUT,
-                                                    &uuid,
-                                                    ownedDevice);
             if (result != OC_STACK_OK)
             {
                 OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "secureResource Discovery failed.");
@@ -332,12 +1170,12 @@ namespace OIC
             {
                 OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "Secured resource is found.");
                 OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "HOST: %s", ownedDevice->getDevAddr().c_str());
-                OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "SID: %s", ownedDevice->getDeviceID().c_str());
+                OIC_LOG_V(INFO_PRIVATE, ENROLEE_SECURITY_TAG, "SID: %s", ownedDevice->getDeviceID().c_str());
                 OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Owned status: %d", ownedDevice->getOwnedStatus());
 
                 if (ownedDevice->getOwnedStatus())
                 {
-                    if(!isOwnedDeviceRegisteredInSVRDB())
+                    if(!isOwnedDeviceRegisteredInDB())
                     {
                         OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "The found device is not one in SVR DB");
                         res = ESResult::ES_SECURE_RESOURCE_DISCOVERY_FAILURE;
@@ -408,9 +1246,13 @@ namespace OIC
 
             OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Given CredId: %d", credId);
 
-            OC::ResultCallBack CertProvisioningCb = std::bind(
-                            &EnrolleeSecurity::CertProvisioningCb, this, std::placeholders::_1,
-                            std::placeholders::_2);
+            OC::ResultCallBack CertProvisioningCb =
+                std::bind(&EnrolleeSecurity::onEnrolleeSecuritySafetyCB,
+                          std::placeholders::_1, std::placeholders::_2,
+                          static_cast<ESSecurityCb>(std::bind(&EnrolleeSecurity::certProvisioningCb,
+                          this, std::placeholders::_1, std::placeholders::_2)),
+                          shared_from_this());
+
             OCStackResult rst = ownedDevice->provisionTrustCertChain(SIGNED_ASYMMETRIC_KEY,
                                                                     static_cast<uint16_t>(credId),
                                                                     CertProvisioningCb);
@@ -444,7 +1286,7 @@ namespace OIC
                 return res;
             }
 
-            OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Given cloudUuid: %s", cloudUuid.c_str());
+            OIC_LOG_V(INFO_PRIVATE, ENROLEE_SECURITY_TAG, "Given cloudUuid: %s", cloudUuid.c_str());
 
             OicUuid_t uuid;
             if(OC_STACK_OK != ConvertStrToUuid(cloudUuid.c_str(), &uuid))
@@ -462,9 +1304,13 @@ namespace OIC
                 return res;
             }
 
-            OC::ResultCallBack aclProvisioningCb = std::bind(
-                            &EnrolleeSecurity::ACLProvisioningCb, this, std::placeholders::_1,
-                            std::placeholders::_2);
+            OC::ResultCallBack aclProvisioningCb =
+                std::bind(&EnrolleeSecurity::onEnrolleeSecuritySafetyCB,
+                          std::placeholders::_1, std::placeholders::_2,
+                          static_cast<ESSecurityCb>(std::bind(&EnrolleeSecurity::aclProvisioningCb,
+                          this, std::placeholders::_1, std::placeholders::_2)),
+                          shared_from_this());
+
             // ACL provisioning to Enrollee
             OCStackResult rst = ownedDevice->provisionACL(acl, aclProvisioningCb);
             if(OC_STACK_OK != rst)
@@ -480,7 +1326,7 @@ namespace OIC
             {
                 res = ESResult::ES_OK;
             }
-
+            OCDeleteACLList(acl);
             return res;
         }
 
@@ -492,13 +1338,13 @@ namespace OIC
             OicSecAcl_t* acl = (OicSecAcl_t*) OICCalloc(1, sizeof(OicSecAcl_t));
             if(!acl)
             {
-                OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "createAcl: OICCalloc error return");
+                OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "createAcl: OICCalloc error return");
                 return NULL;  // not need to 'goto' |ERROR| before allocating |acl|
             }
             OicSecAce_t* ace = (OicSecAce_t*) OICCalloc(1, sizeof(OicSecAce_t));
             if(!ace)
             {
-                OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG,  "createAcl: OICCalloc error return");
+                OIC_LOG(ERROR, ENROLEE_SECURITY_TAG,  "createAcl: OICCalloc error return");
                 return NULL;  // not need to 'goto' |ERROR| before allocating |acl|
             }
             LL_APPEND(acl->aces, ace);
@@ -508,7 +1354,7 @@ namespace OIC
             OicSecRsrc_t* rsrc = (OicSecRsrc_t*)OICCalloc(1, sizeof(OicSecRsrc_t));
             if(!rsrc)
             {
-                OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "createAcl: OICCalloc error return");
+                OIC_LOG(ERROR, ENROLEE_SECURITY_TAG, "createAcl: OICCalloc error return");
                 OCDeleteACLList(acl);
                 return NULL;
             }
@@ -518,7 +1364,8 @@ namespace OIC
             rsrc->href = (char*) OICCalloc(len, sizeof(char));
             if(!rsrc->href)
             {
-                OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG,  "createAcl: OICCalloc error return");
+                OIC_LOG(ERROR, ENROLEE_SECURITY_TAG,  "createAcl: OICCalloc error return");
+                FreeRsrc(rsrc);
                 OCDeleteACLList(acl);
                 return NULL;
             }
@@ -527,10 +1374,39 @@ namespace OIC
             size_t arrLen = 1;
             rsrc->typeLen = arrLen;
             rsrc->types = (char**)OICCalloc(arrLen, sizeof(char*));
+            if(!rsrc->types)
+            {
+                OIC_LOG(ERROR, ENROLEE_SECURITY_TAG,  "createAcl: OICCalloc error return");
+                FreeRsrc(rsrc);
+                OCDeleteACLList(acl);
+                return NULL;
+            }
+            rsrc->types[0] = OICStrdup("rt");   // ignore
+            if(!rsrc->types[0])
+            {
+                OIC_LOG(ERROR, ENROLEE_SECURITY_TAG,  "createAcl: OICStrdup error return");
+                FreeRsrc(rsrc);
+                OCDeleteACLList(acl);
+                return NULL;
+            }
+
             rsrc->interfaceLen = 1;
             rsrc->interfaces = (char**)OICCalloc(arrLen, sizeof(char*));
-            rsrc->types[0] = OICStrdup("rt");   // ignore
+            if(!rsrc->interfaces)
+            {
+                OIC_LOG(ERROR, ENROLEE_SECURITY_TAG,  "createAcl: OICCalloc error return");
+                FreeRsrc(rsrc);
+                OCDeleteACLList(acl);
+                return NULL;
+            }
             rsrc->interfaces[0] = OICStrdup("if");  // ignore
+            if(!rsrc->interfaces[0])
+            {
+                OIC_LOG(ERROR, ENROLEE_SECURITY_TAG,  "createAcl: OICStrdup error return");
+                FreeRsrc(rsrc);
+                OCDeleteACLList(acl);
+                return NULL;
+            }
 
             LL_APPEND(ace->resources, rsrc);
 
@@ -541,9 +1417,9 @@ namespace OIC
             return acl;
         }
 
-        void EnrolleeSecurity::ACLProvisioningCb(PMResultList_t *result, int hasError)
+        void EnrolleeSecurity::aclProvisioningCb(PMResultList_t *result, int hasError)
         {
-            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "ACLProvisioningCb IN");
+            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "aclProvisioningCb IN");
 
             if (hasError)
             {
@@ -558,8 +1434,9 @@ namespace OIC
                for (unsigned int i = 0; i < result->size(); i++)
                {
                    convertUUIDToString(result->at(i).deviceId.id, devUuid);
-                   OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Result is = %d  for device %s",
-                                                           result->at(i).res, devUuid.c_str());
+
+                   OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Result is = %d", result->at(i).res);
+                   OIC_LOG_V(INFO_PRIVATE, ENROLEE_SECURITY_TAG, "device uuid : %s", devUuid.c_str());
                }
                delete result;
                aclResult = true;
@@ -567,9 +1444,9 @@ namespace OIC
             m_cond.notify_all();
         }
 
-        void EnrolleeSecurity::CertProvisioningCb(PMResultList_t *result, int hasError)
+        void EnrolleeSecurity::certProvisioningCb(PMResultList_t *result, int hasError)
         {
-            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "CertProvisioningCb IN");
+            OIC_LOG(DEBUG, ENROLEE_SECURITY_TAG, "certProvisioningCb IN");
 
             if (hasError)
             {
@@ -584,8 +1461,9 @@ namespace OIC
                for (unsigned int i = 0; i < result->size(); i++)
                {
                    convertUUIDToString(result->at(i).deviceId.id, devUuid);
-                   OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Result is = %d  for device %s",
-                                                           result->at(i).res, devUuid.c_str());
+
+                   OIC_LOG_V(DEBUG, ENROLEE_SECURITY_TAG, "Result is = %d", result->at(i).res);
+                   OIC_LOG_V(INFO_PRIVATE, ENROLEE_SECURITY_TAG, "device uuid : %s", devUuid.c_str());
                }
                delete result;
                certResult= true;
index 2e9b3fa..fbf676e 100755 (executable)
@@ -25,6 +25,7 @@
 #include <atomic>
 #include <condition_variable>
 
+
 #include "ESRichCommon.h"
 #include "OCProvisioningManager.hpp"
 
@@ -41,18 +42,18 @@ namespace OIC
         class OCSecureResource;
 
         typedef std::vector<OCProvisionResult_t> PMResultList_t;
+        typedef std::function<void(OC::PMResultList_t *result, int hasError)> ESSecurityCb;
 
         /**
          * This class contains the methods needed for security  layer interaction.
          *
          * @see EnrolleeSecurity
          */
-        class EnrolleeSecurity
+        class EnrolleeSecurity : public std::enable_shared_from_this<EnrolleeSecurity>
         {
         public:
-            EnrolleeSecurity(std::shared_ptr< OC::OCResource > resource,
-            const std::string secDbPath);
-            ESResult provisionOwnership();
+            EnrolleeSecurity(std::shared_ptr< OC::OCResource > resource);
+            ESResult provisionOwnership(SecurityProvStatusCbWithOption callback);
             std::string getUUID() const;
 
         private:
@@ -63,19 +64,48 @@ namespace OIC
 
             std::mutex m_mtx;
             std::condition_variable m_cond;
-            std::atomic<bool> OTMResult;
+            std::atomic<bool> otmResult;
+            std::atomic<bool> enableMOTModeResult;
+            std::atomic<bool> motMethodProvResult;
+            std::atomic<bool> preConfigPinProvResult;
             std::atomic<bool> removeDeviceResult;
             std::atomic<bool> aclResult;
             std::atomic<bool> certResult;
+            std::string m_mediatorID;
 
             std::shared_ptr< OC::OCSecureResource > m_securedResource;
 
+            static void onEnrolleeSecuritySafetyCB(OC::PMResultList_t *result,
+                                    int hasError,
+                                    ESSecurityCb cb,
+                                    std::weak_ptr<EnrolleeSecurity> this_ptr);
+
             ESResult performOwnershipTransfer();
-            bool isOwnedDeviceRegisteredInSVRDB();
+            bool isOwnedDeviceRegisteredInDB();
             void removeDeviceWithUuidCB(OC::PMResultList_t *result, int hasError);
-            void ownershipTransferCb(OC::PMResultList_t *result, int hasError);
+            ESResult discoverTargetSecureResource();
+            ESOwnershipTransferData getOwnershipTransferDataFromUser
+                                        (SecurityProvStatusCbWithOption callback);
+            ESResult syncUpWithMediatorDB();
+#ifdef MULTIPLE_OWNER
+            ESResult performMultipleOwnershipTransfer(const ESOwnershipTransferData& MOTdata);
+            void changeMOTMethodCB(PMResultList_t *result, int hasError);
+
+            void selectMOTMethodCB(PMResultList_t *result, int hasError);
+            void preconfigPinProvCB(PMResultList_t *result, int hasError);
+            void multipleOwnershipTransferCb(OC::PMResultList_t *result, int hasError);
+            bool isSubOwnerIDMatched(std::shared_ptr< OC::OCSecureResource > foundDevice);
+            ESResult requestSetPreconfPinData(const ESOwnershipTransferData& MOTData);
+            ESResult requestSetMOTMethod(const ESOwnershipTransferData& MOTData);
+            ESResult requestEnableMOTMode();
+            ESResult provisionMOTConfig(const ESOwnershipTransferData& MOTData);
+#endif
+            void ownershipTransferCb(OC::PMResultList_t *result, int hasError, ESResult& res);
             void convertUUIDToString(const uint8_t uuid[UUID_SIZE],
                                                 std::string& uuidString);
+            std::string getResourceDeviceAddress(const std::string& host);
+            bool isOwnerIDMatched(std::shared_ptr< OC::OCSecureResource > foundDevice);
+            std::string getMediatorDevID();
 
 #if defined(__WITH_DTLS__) && defined(__WITH_TLS__)
         public:
@@ -89,8 +119,8 @@ namespace OIC
                 std::shared_ptr< OC::OCSecureResource > ownedDevice,
                 std::string& cloudUuid);
             OicSecAcl_t* createAcl(const OicUuid_t cloudUuid);
-            void ACLProvisioningCb(PMResultList_t *result, int hasError);
-            void CertProvisioningCb(PMResultList_t *result, int hasError);
+            void aclProvisioningCb(PMResultList_t *result, int hasError);
+            void certProvisioningCb(PMResultList_t *result, int hasError);
 #endif //defined(__WITH_DTLS__) && defined(__WITH_TLS__)
         };
     }
index 15dbf43..941239d 100755 (executable)
 #include "ESException.h"
 #include "logger.h"
 #include "OCResource.h"
+#include "oic_string.h"
 #ifdef __WITH_DTLS__
 #include "EnrolleeSecurity.h"
 #include "base64.h"
 #include "oic_malloc.h"
+#include "cacommon.h"
 #endif //__WITH_DTLS
 
 namespace OIC
@@ -49,20 +51,33 @@ namespace OIC
             m_secProvisioningDbPathCb = nullptr;
             m_devicePropProvStatusCb = nullptr;
             m_cloudPropProvStatusCb = nullptr;
+            m_connectRequestStatusCb = nullptr;
 
             m_deviceId = resource->sid();
         }
 
+        void RemoteEnrollee::onSecurityStatusHandlerCallback(
+                const std::shared_ptr< SecProvisioningStatus > status,
+                std::weak_ptr<RemoteEnrollee> this_ptr)
+        {
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG,"onSecurityStatusHandlerCallback");
+            std::shared_ptr<RemoteEnrollee> Ptr = this_ptr.lock();
+            if(Ptr)
+            {
+                Ptr->securityStatusHandler(status);
+            }
+        }
+
         void RemoteEnrollee::securityStatusHandler(
                 const std::shared_ptr< SecProvisioningStatus > status) const
         {
-            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "securityStatusHandlr IN");
-            OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_TAG, "UUID = %s, ESResult = %d",
-                    status->getDeviceUUID().c_str(), status->getESResult());
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "securityStatusHandlr IN");
+            OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG, "UUID = %s", status->getDeviceUUID().c_str());
+            OIC_LOG_V(INFO, ES_REMOTE_ENROLLEE_TAG, "ESResult = %d", status->getESResult());
 
             if(status->getESResult() == ES_OK)
             {
-                OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "Ownership transfer is successfully done.");
+                OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "Ownership transfer is successfully done.");
                 m_securityProvStatusCb(status);
             }
             else
@@ -70,60 +85,171 @@ namespace OIC
                 OIC_LOG(ERROR, ES_REMOTE_ENROLLEE_TAG, "Ownership transfer is failed.");
                 m_securityProvStatusCb(status);
             }
-            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "securityStatusHandlr OUT");
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "securityStatusHandlr OUT");
+        }
+
+        ESOwnershipTransferData RemoteEnrollee::onSecurityStatusWithOptionHandlerCallback(
+                const std::shared_ptr< SecProvisioningStatus > status,
+                std::weak_ptr<RemoteEnrollee> this_ptr)
+        {
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG,"onSecurityStatusWithOptionHandlerCallback");
+            std::shared_ptr<RemoteEnrollee> Ptr = this_ptr.lock();
+            if(Ptr)
+            {
+                return Ptr->securityStatusWithOptionHandler(status);
+            }
+            return ESOwnershipTransferData();
+        }
+
+        ESOwnershipTransferData RemoteEnrollee::securityStatusWithOptionHandler(
+                const std::shared_ptr< SecProvisioningStatus > status) const
+        {
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "securityStatusWithOptionHandler IN");
+            OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG, "UUID = %s", status->getDeviceUUID().c_str());
+            OIC_LOG_V(INFO, ES_REMOTE_ENROLLEE_TAG, "ESResult = %d", status->getESResult());
+
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "securityStatusWithOptionHandler OUT");
+            return m_securityProvStatusCbWithOption(status);
+        }
+
+        void RemoteEnrollee::onGetStatusHandlerCallback(
+                const std::shared_ptr< GetEnrolleeStatus > status,
+                std::weak_ptr<RemoteEnrollee> this_ptr)
+        {
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG,"onGetStatusHandlerCallback");
+            std::shared_ptr<RemoteEnrollee> Ptr = this_ptr.lock();
+            if(Ptr)
+            {
+                Ptr->getStatusHandler(status);
+            }
         }
 
         void RemoteEnrollee::getStatusHandler(
                 const std::shared_ptr< GetEnrolleeStatus > status) const
         {
-            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "getStatusHandler IN");
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "getStatusHandler IN");
 
-            OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_TAG, "getStatusHandler = %d",
+            OIC_LOG_V(INFO, ES_REMOTE_ENROLLEE_TAG, "getStatusHandler = %d",
                                                     status->getESResult());
             m_getStatusCb(status);
 
-            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "getStatusHandler OUT");
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "getStatusHandler OUT");
+        }
+
+        void RemoteEnrollee::onGetConfigurationStatusHandlerCallback(
+                const std::shared_ptr< GetConfigurationStatus > status,
+                std::weak_ptr<RemoteEnrollee> this_ptr)
+        {
+            OIC_LOG(INFO,ES_REMOTE_ENROLLEE_TAG,"onGetConfigurationStatusHandlerCallback");
+            std::shared_ptr<RemoteEnrollee> Ptr = this_ptr.lock();
+            if(Ptr)
+            {
+                Ptr->getConfigurationStatusHandler(status);
+            }
         }
 
         void RemoteEnrollee::getConfigurationStatusHandler (
                 const std::shared_ptr< GetConfigurationStatus > status) const
         {
-            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "getConfigurationStatusHandler IN");
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "getConfigurationStatusHandler IN");
 
-            OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_TAG,"GetConfigurationStatus = %d",
+            OIC_LOG_V(INFO, ES_REMOTE_ENROLLEE_TAG,"GetConfigurationStatus = %d",
                                                     status->getESResult());
             m_getConfigurationStatusCb(status);
 
-            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "getConfigurationStatusHandler OUT");
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "getConfigurationStatusHandler OUT");
+        }
+
+        void RemoteEnrollee::onDevicePropProvisioningStatusHandlerCallback(
+                const std::shared_ptr< DevicePropProvisioningStatus > status,
+                std::weak_ptr<RemoteEnrollee> this_ptr)
+        {
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG,"onDevicePropProvisioningStatusHandlerCallback");
+            std::shared_ptr<RemoteEnrollee> Ptr = this_ptr.lock();
+            if(Ptr)
+            {
+                Ptr->devicePropProvisioningStatusHandler(status);
+            }
         }
 
         void RemoteEnrollee::devicePropProvisioningStatusHandler(
                 const std::shared_ptr< DevicePropProvisioningStatus > status) const
         {
-            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "devicePropProvisioningStatusHandler IN");
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "devicePropProvisioningStatusHandler IN");
 
-            OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_TAG, "ProvStatus = %d", status->getESResult());
+            OIC_LOG_V(INFO, ES_REMOTE_ENROLLEE_TAG, "DeviceProvStatus = %d", status->getESResult());
             m_devicePropProvStatusCb(status);
+#ifdef __WITH_DTLS__
+            if( m_ocResource.get() != nullptr &&
+                    !(m_ocResource->connectivityType() & CT_ADAPTER_GATT_BTLE) &&
+                    ES_OK == status->getESResult() )
+            {
+                // NOTE: Temporary patch
+                CAEndpoint_t endpoint = {.adapter = CA_ADAPTER_IP};
+
+                OCDevAddr address = m_ocResource->getDevAddr();
+                OICStrcpy(endpoint.addr, MAX_ADDR_STR_SIZE, address.addr);
+                endpoint.port = address.port;
 
-            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "devicePropProvisioningStatusHandler OUT");
+                OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_TAG, "HOST = %s", endpoint.addr);
+                OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_TAG, "PORT = %u", endpoint.port);
+                CAcloseSslSession(&endpoint);
+            }
+#endif
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "devicePropProvisioningStatusHandler OUT");
+        }
+
+        void RemoteEnrollee::onCloudPropProvisioningStatusHandlerCallback(
+                const std::shared_ptr< CloudPropProvisioningStatus > status,
+                std::weak_ptr<RemoteEnrollee> this_ptr)
+        {
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG,"onCloudPropProvisioningStatusHandlerCallback");
+            std::shared_ptr<RemoteEnrollee> Ptr = this_ptr.lock();
+            if(Ptr)
+            {
+                Ptr->cloudPropProvisioningStatusHandler(status);
+            }
         }
 
         void RemoteEnrollee::cloudPropProvisioningStatusHandler (
                 const std::shared_ptr< CloudPropProvisioningStatus > status) const
         {
-            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "cloudPropProvisioningStatusHandler IN");
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "cloudPropProvisioningStatusHandler IN");
 
-            OIC_LOG_V(DEBUG,ES_REMOTE_ENROLLEE_TAG,"CloudProvStatus = %d",
+            OIC_LOG_V(INFO,ES_REMOTE_ENROLLEE_TAG,"CloudProvStatus = %d",
                                                     status->getESResult());
             m_cloudPropProvStatusCb(status);
 
-            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "cloudPropProvisioningStatusHandler OUT");
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "cloudPropProvisioningStatusHandler OUT");
+        }
+
+        void RemoteEnrollee::onConnectRequestStatusHandlerCallback(
+                const std::shared_ptr< ConnectRequestStatus > status,
+                std::weak_ptr<RemoteEnrollee> this_ptr)
+        {
+            OIC_LOG_V(DEBUG,ES_REMOTE_ENROLLEE_TAG,"onConnectRequestStatusHandlerCallback");
+            std::shared_ptr<RemoteEnrollee> Ptr = this_ptr.lock();
+            if(Ptr)
+            {
+                Ptr->connectRequestStatusHandler(status);
+            }
+        }
+
+        void RemoteEnrollee::connectRequestStatusHandler(
+                const std::shared_ptr< ConnectRequestStatus > status) const
+        {
+            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "connectRequestStatusHandler IN");
+
+            OIC_LOG_V(DEBUG, ES_REMOTE_ENROLLEE_TAG, "RequestConnectStatus = %d", status->getESResult());
+            m_connectRequestStatusCb(status);
+
+            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "connectRequestStatusHandler OUT");
         }
 
         void RemoteEnrollee::onDiscoveredCallback(const std::shared_ptr<OC::OCResource> resource,
             std::weak_ptr<RemoteEnrollee> this_ptr)
         {
-            OIC_LOG_V(DEBUG,ES_REMOTE_ENROLLEE_TAG,"onDiscoveredCallback()");
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG,"onDiscoveredCallback()");
             std::shared_ptr<RemoteEnrollee> Ptr = this_ptr.lock();
             if(Ptr)
             {
@@ -133,7 +259,7 @@ namespace OIC
 
         void RemoteEnrollee::onDeviceDiscovered(std::shared_ptr<OC::OCResource> resource)
         {
-            OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_TAG, "onDeviceDiscovered IN");
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "onDeviceDiscovered IN");
 
             try
             {
@@ -147,21 +273,21 @@ namespace OIC
 
                         // Get the resource URI
                         resourceURI = resource->uri();
-                        OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG,
+                        OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG,
                                 "URI of the resource: %s", resourceURI.c_str());
 
                         // Get the resource host address
                         hostAddress = resource->host();
-                        OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG,
+                        OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG,
                                 "Host address of the resource: %s", hostAddress.c_str());
 
                         hostDeviceID = resource->sid();
-                        OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG,
+                        OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG,
                                 "Host DeviceID of the resource: %s", hostDeviceID.c_str());
 
                         if(!m_deviceId.empty() && m_deviceId == hostDeviceID)
                         {
-                            OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_TAG, "Find matched resource for cloud provisioning");
+                            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "Find matched resource for cloud provisioning");
                             m_ocResource = resource;
                             m_discoveryResponse = true;
                             m_cond.notify_all();
@@ -171,23 +297,23 @@ namespace OIC
             }
             catch(std::exception& e)
             {
-                OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG,
+                OIC_LOG_V(INFO, ES_REMOTE_ENROLLEE_TAG,
                         "Exception in foundResource: %s", e.what());
             }
 
-            OIC_LOG (DEBUG, ES_REMOTE_ENROLLEE_TAG, "onDeviceDiscovered OUT");
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "onDeviceDiscovered OUT");
         }
 
         ESResult RemoteEnrollee::discoverResource()
         {
-            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "discoverResource IN");
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "discoverResource IN");
 
             std::string query("");
             query.append(ES_BASE_RES_URI);
             query.append("?rt=");
-            query.append(OC_RSRVD_ES_RES_TYPE_PROV);
+            query.append(OC_RSRVD_ES_RES_TYPE_EASYSETUP);
 
-            OIC_LOG_V (DEBUG, ES_REMOTE_ENROLLEE_TAG, "query = %s", query.c_str());
+            OIC_LOG_V(INFO, ES_REMOTE_ENROLLEE_TAG, "query = %s", query.c_str());
 
             m_discoveryResponse = false;
 
@@ -199,7 +325,7 @@ namespace OIC
 
             if (result != OCStackResult::OC_STACK_OK)
             {
-                OIC_LOG(ERROR,ES_REMOTE_ENROLLEE_TAG,
+                OIC_LOG(ERROR, ES_REMOTE_ENROLLEE_TAG,
                         "Failed discoverResource");
                 return ES_ERROR;
             }
@@ -209,7 +335,7 @@ namespace OIC
 
             if (!m_discoveryResponse)
             {
-                OIC_LOG(ERROR,ES_REMOTE_ENROLLEE_TAG,
+                OIC_LOG(ERROR, ES_REMOTE_ENROLLEE_TAG,
                         "Failed discoverResource because timeout");
                 return ES_ERROR;
             }
@@ -219,7 +345,7 @@ namespace OIC
 
         void RemoteEnrollee::provisionSecurity(const SecurityProvStatusCb callback)
         {
-            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "provisionSecurity IN");
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionSecurity IN");
 #ifdef __WITH_DTLS__
             ESResult res = ESResult::ES_ERROR;
             if(!callback)
@@ -229,23 +355,63 @@ namespace OIC
             m_securityProvStatusCb = callback;
 
             SecurityProvStatusCb securityProvStatusCb = std::bind(
-                    &RemoteEnrollee::securityStatusHandler,
-                    this,
-                    std::placeholders::_1);
+                    &RemoteEnrollee::onSecurityStatusHandlerCallback,
+                    std::placeholders::_1,
+                    shared_from_this());
             //TODO : DBPath is passed empty as of now. Need to take dbpath from application.
-            if(!m_enrolleeSecurity.get())
+            if(!m_localEnrolleeSecurity.get())
             {
-                m_enrolleeSecurity = std::make_shared <EnrolleeSecurity> (m_ocResource, "");
+                m_localEnrolleeSecurity = std::make_shared <EnrolleeSecurity> (m_ocResource);
             }
 
-            res = m_enrolleeSecurity->provisionOwnership();
+            res = m_localEnrolleeSecurity->provisionOwnership(NULL);
 
             std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
-                            std::make_shared< SecProvisioningStatus >(m_enrolleeSecurity->getUUID(), res);
+                            std::make_shared< SecProvisioningStatus >(m_localEnrolleeSecurity->getUUID(), res);
             securityProvStatusCb(securityProvisioningStatus);
-            m_enrolleeSecurity.reset();
 #else
-            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG,"Mediator is unsecured built.");
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG,"Mediator is unsecured built.");
+
+            if(!callback)
+            {
+                throw ESInvalidParameterException("Callback is empty");
+            }
+            std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
+                     std::make_shared< SecProvisioningStatus >
+                                   ("", ESResult::ES_SEC_OPERATION_IS_NOT_SUPPORTED);
+            callback(securityProvisioningStatus);
+#endif
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionSecurity OUT");
+        }
+
+        void RemoteEnrollee::provisionSecurity(const SecurityProvStatusCbWithOption callback)
+        {
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionSecurity IN");
+#ifdef __WITH_DTLS__
+            ESResult res = ESResult::ES_ERROR;
+            if(!callback)
+            {
+                throw ESInvalidParameterException("Callback is empty");
+            }
+            m_securityProvStatusCbWithOption = callback;
+
+            SecurityProvStatusCbWithOption securityProvStatusCbWithOption = std::bind(
+                                    &RemoteEnrollee::onSecurityStatusWithOptionHandlerCallback,
+                                    std::placeholders::_1,
+                                    shared_from_this());
+
+            if(!m_localEnrolleeSecurity.get())
+            {
+                m_localEnrolleeSecurity = std::make_shared <EnrolleeSecurity> (m_ocResource);
+            }
+
+            res = m_localEnrolleeSecurity->provisionOwnership(securityProvStatusCbWithOption);
+
+            std::shared_ptr< SecProvisioningStatus > securityProvisioningStatus =
+                            std::make_shared< SecProvisioningStatus >(m_localEnrolleeSecurity->getUUID(), res);
+            securityProvStatusCbWithOption(securityProvisioningStatus);
+#else
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG,"Mediator is unsecured built.");
 
             if(!callback)
             {
@@ -256,12 +422,12 @@ namespace OIC
                                    ("", ESResult::ES_SEC_OPERATION_IS_NOT_SUPPORTED);
             callback(securityProvisioningStatus);
 #endif
-            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "provisionSecurity OUT");
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionSecurity OUT");
         }
 
         void RemoteEnrollee::getStatus(const GetStatusCb callback)
         {
-            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "getStatus IN");
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "getStatus IN");
 
             if(!callback)
             {
@@ -276,16 +442,19 @@ namespace OIC
             m_getStatusCb = callback;
 
             GetStatusCb getStatusCb = std::bind(
-                &RemoteEnrollee::getStatusHandler, this, std::placeholders::_1);
+                &RemoteEnrollee::onGetStatusHandlerCallback,
+                std::placeholders::_1,
+                shared_from_this());
+
             m_enrolleeResource->registerGetStatusCallback(getStatusCb);
             m_enrolleeResource->getStatus();
 
-            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "getStatus OUT");
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "getStatus OUT");
         }
 
         void RemoteEnrollee::getConfiguration(const GetConfigurationStatusCb callback)
         {
-            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "getConfiguration IN");
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "getConfiguration IN");
 
             if(!callback)
             {
@@ -300,17 +469,20 @@ namespace OIC
             m_getConfigurationStatusCb = callback;
 
             GetConfigurationStatusCb getConfigurationStatusCb = std::bind(
-                    &RemoteEnrollee::getConfigurationStatusHandler, this, std::placeholders::_1);
+                    &RemoteEnrollee::onGetConfigurationStatusHandlerCallback,
+                    std::placeholders::_1,
+                    shared_from_this());
+
             m_enrolleeResource->registerGetConfigurationStatusCallback(getConfigurationStatusCb);
             m_enrolleeResource->getConfiguration();
 
-            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "getConfiguration OUT");
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "getConfiguration OUT");
         }
 
         void RemoteEnrollee::provisionDeviceProperties(const DeviceProp& deviceProp,
                                                             const DevicePropProvStatusCb callback)
         {
-            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "provisionDeviceProperties IN");
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionDeviceProperties IN");
 
             if(!callback)
             {
@@ -324,24 +496,20 @@ namespace OIC
                 throw ESBadRequestException ("Device not created");
             }
 
-            if(deviceProp.getSsid().empty())
-            {
-                throw ESBadRequestException ("Invalid Provisiong Data.");
-            }
-
             DevicePropProvStatusCb devicePropProvStatusCb = std::bind(
-                    &RemoteEnrollee::devicePropProvisioningStatusHandler,
-                    this, std::placeholders::_1);
+                    &RemoteEnrollee::onDevicePropProvisioningStatusHandlerCallback,
+                    std::placeholders::_1,
+                    shared_from_this());
 
             m_enrolleeResource->registerDevicePropProvStatusCallback(devicePropProvStatusCb);
             m_enrolleeResource->provisionProperties(deviceProp);
 
-            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "provisionDeviceProperties OUT");
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionDeviceProperties OUT");
         }
 
         void RemoteEnrollee::initCloudResource()
         {
-            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "initCloudResource IN");
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "initCloudResource IN");
 
             ESResult result = ES_ERROR;
 
@@ -349,7 +517,7 @@ namespace OIC
 
             if (result == ES_ERROR)
             {
-                OIC_LOG(ERROR,ES_REMOTE_ENROLLEE_TAG,
+                OIC_LOG(ERROR, ES_REMOTE_ENROLLEE_TAG,
                                     "Failed to create resource object using discoverResource");
                 throw ESBadRequestException ("Resource object not created");
             }
@@ -366,13 +534,24 @@ namespace OIC
                 }
             }
 
-            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "initCloudResource OUT");
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "initCloudResource OUT");
         }
 
         void RemoteEnrollee::provisionCloudProperties(const CloudProp& cloudProp,
                                                             const CloudPropProvStatusCb callback)
         {
-            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "provisionCloudProperties IN");
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionCloudProperties w/o OCResource IN");
+
+            provisionCloudProperties(NULL, cloudProp, callback);
+
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionCloudProperties w/o OCResource OUT");
+        }
+
+        void RemoteEnrollee::provisionCloudProperties(const std::shared_ptr< OC::OCResource > resource,
+                                                        const CloudProp& cloudProp,
+                                                        const CloudPropProvStatusCb callback)
+        {
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionCloudProperties IN");
 
             if(!callback)
             {
@@ -381,18 +560,56 @@ namespace OIC
 
             m_cloudPropProvStatusCb = callback;
 
-            if(cloudProp.getAuthCode().empty() ||
+            if((cloudProp.getAuthCode().empty() && cloudProp.getAccessToken().empty()) ||
                 cloudProp.getAuthProvider().empty() ||
                 cloudProp.getCiServer().empty())
             {
                 throw ESBadRequestException ("Invalid Cloud Provisiong Info.");
             }
 
-            try
+            if(resource)
             {
-                initCloudResource();
+                if(resource->getResourceTypes().at(0) != OC_RSRVD_ES_RES_TYPE_EASYSETUP ||
+                                resource->connectivityType() & CT_ADAPTER_TCP)
+                {
+                    OIC_LOG(ERROR, ES_REMOTE_ENROLLEE_TAG, "Given resource is not valid due to wrong rt or conntype");
+                    throw ESInvalidParameterException("A given OCResource is wrong");
+                }
+
+                auto interfaces = resource->getResourceInterfaces();
+                bool isFound = false;
+                for(auto interface : interfaces)
+                {
+                    if(interface.compare(BATCH_INTERFACE) == 0)
+                    {
+                        OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "RemoteEnrollee object is succeessfully created");
+                        OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG, "HOST: %s", resource->host().c_str());
+                        OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG, "URI: %s", resource->uri().c_str());
+                        OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG, "SID: %s", resource->sid().c_str());
+                        OIC_LOG_V(INFO_PRIVATE, ES_REMOTE_ENROLLEE_TAG, "CONNECTIVITY: %d", resource->connectivityType());
+                        isFound = true;
+                    }
+                }
+
+                if(!isFound)
+                {
+                    throw ESInvalidParameterException("A given OCResource has no batch interface");
+                }
             }
 
+            try
+            {
+                if(resource == NULL)
+                {
+                    initCloudResource();
+                }
+                else
+                {
+                    OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "Skip to find a provisioning resource");
+                    m_ocResource = resource;
+                    m_cloudResource = std::make_shared<CloudResource>(m_ocResource);
+                }
+            }
             catch (const std::exception& e)
             {
                 OIC_LOG_V(ERROR, ES_REMOTE_ENROLLEE_TAG,
@@ -407,15 +624,15 @@ namespace OIC
             if(!(cloudProp.getCloudID().empty() && cloudProp.getCredID() <= 0))
             {
                 ESResult res = ESResult::ES_ERROR;
-                if(!m_enrolleeSecurity.get())
+                if(!m_cloudEnrolleeSecurity.get())
                 {
-                    m_enrolleeSecurity = std::make_shared <EnrolleeSecurity> (m_ocResource, "");
+                    m_cloudEnrolleeSecurity = std::make_shared <EnrolleeSecurity> (m_ocResource);
                 }
 
 
-                res = m_enrolleeSecurity->provisionSecurityForCloudServer(cloudProp.getCloudID(),
+                res = m_cloudEnrolleeSecurity->provisionSecurityForCloudServer(cloudProp.getCloudID(),
                                                                           cloudProp.getCredID());
-                m_enrolleeSecurity.reset();
+
                 if(res != ESResult::ES_OK)
                 {
                     m_cloudResource = nullptr;
@@ -427,7 +644,7 @@ namespace OIC
             }
             else
             {
-                OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "ACL and Cert. provisioning are skipped.");
+                OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "ACL and Cert. provisioning are skipped.");
             }
 #endif //defined(__WITH_DTLS__) && defined(__WITH_TLS__)
 
@@ -437,13 +654,38 @@ namespace OIC
             }
 
             CloudPropProvStatusCb cloudPropProvStatusCb = std::bind(
-                    &RemoteEnrollee::cloudPropProvisioningStatusHandler,
-                                    this, std::placeholders::_1);
+                    &RemoteEnrollee::onCloudPropProvisioningStatusHandlerCallback,
+                    std::placeholders::_1,
+                    shared_from_this());
 
             m_cloudResource->registerCloudPropProvisioningStatusCallback(cloudPropProvStatusCb);
             m_cloudResource->provisionProperties(cloudProp);
 
-            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "provisionCloudProperties OUT");
+            OIC_LOG(INFO, ES_REMOTE_ENROLLEE_TAG, "provisionCloudProperties OUT");
+        }
+
+        void RemoteEnrollee::requestToConnect(const std::vector<ES_CONNECT_TYPE> &connectTypes, const ConnectRequestStatusCb callback)
+        {
+            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "connect IN");
+
+            if(!callback)
+            {
+                throw ESInvalidParameterException("Callback is empty");
+            }
+
+            m_connectRequestStatusCb = callback;
+
+            ConnectRequestStatusCb connectRequestStatusCb = std::bind(
+                        &RemoteEnrollee::onConnectRequestStatusHandlerCallback,
+                        std::placeholders::_1,
+                        shared_from_this());
+
+            m_enrolleeResource->registerConnectRequestStatusCallback(connectRequestStatusCb);
+            m_enrolleeResource->requestToConnect(connectTypes);
+
+            OIC_LOG(DEBUG, ES_REMOTE_ENROLLEE_TAG, "connect OUT");
         }
     }
 }
+
+
index 026dec7..ac097fa 100755 (executable)
@@ -47,14 +47,14 @@ public:
 
     ESResult initEnrollee()
     {
-        ESResourceMask resourcemMask = (ESResourceMask)(ES_WIFI_RESOURCE |
-                                                    ES_CLOUD_RESOURCE |
+        ESResourceMask resourcemMask = (ESResourceMask)(ES_WIFICONF_RESOURCE |
+                                                    ES_COAPCLOUDCONF_RESOURCE |
                                                     ES_DEVCONF_RESOURCE);
         ESProvisioningCallbacks callbacks;
 
-        callbacks.WiFiProvCb = &onWiFiProvisioning;
+        callbacks.WiFiConfProvCb = &onWiFiProvisioning;
         callbacks.DevConfProvCb = &onDevConfProvisioning;
-        callbacks.CloudDataProvCb = &onCloudProvisioning;
+        callbacks.CoapCloudConfProvCb = &onCloudProvisioning;
 
         return ESInitEnrollee(false, resourcemMask, callbacks);
     }
@@ -62,7 +62,7 @@ public:
     ESResult setDeviceProperty()
     {
         ESDeviceProperty deviceProperty = {
-            {{WIFI_11G, WiFi_EOF}, WIFI_5G}, {"Test Device", "Test Model Number"}
+            {{WIFI_11G, WiFi_EOF}, WIFI_5G}, {"Test Device"}
         };
 
         return ESSetDeviceProperty(&deviceProperty);
@@ -79,15 +79,15 @@ public:
     }
 
 private:
-    static void onWiFiProvisioning(ESWiFiProvData* /*data*/)
+    static void onWiFiProvisioning(ESWiFiConfData* /*data*/)
     {
     }
 
-    static void onDevConfProvisioning(ESDevConfProvData* /*data*/)
+    static void onDevConfProvisioning(ESDevConfData* /*data*/)
     {
     }
 
-    static void onCloudProvisioning(ESCloudProvData* /*data*/)
+    static void onCloudProvisioning(ESCoapCloudConfData* /*data*/)
     {
     }
 };
index f0931f0..853f132 100755 (executable)
@@ -88,14 +88,14 @@ public:
     EasysetupMediatorTest() = default;
     ~EasysetupMediatorTest() = default;
 
-    std::shared_ptr<OC::OCResource> CreateNotProvResource()
+    std::shared_ptr<OC::OCResource> CreateNotEasySetupResource()
     {
         OCConnectivityType connectivityType = CT_DEFAULT;
-        std::vector<std::string> types = {"oic.wk.notprov"};
+        std::vector<std::string> types = {"oic.r.noteasysetup"};
         std::vector<std::string> ifaces = {DEFAULT_INTERFACE};
 
         return OCPlatform::constructResourceObject("coap://192.168.1.2:5000",
-                                                   "/NotProvisioningResURI",
+                                                   "/NotEasySetupResURI",
                                                    connectivityType,
                                                    false,
                                                    types,
@@ -104,7 +104,7 @@ public:
 
     void discoverRemoteEnrollee()
     {
-        std::string uri = std::string("/oic/res?rt=") + OC_RSRVD_ES_RES_TYPE_PROV;
+        std::string uri = std::string("/oic/res?rt=") + OC_RSRVD_ES_RES_TYPE_EASYSETUP;
         OC::OCPlatform::findResource("", uri,
                 OCConnectivityType::CT_DEFAULT,
                 std::bind(&EasysetupMediatorTest::discoverRemoteEnrolleeCb,
@@ -175,21 +175,21 @@ private:
             return ;
         }
 
-        if(!resource->getResourceTypes().at(0).compare(OC_RSRVD_ES_RES_TYPE_PROV))
+        if(!resource->getResourceTypes().at(0).compare(OC_RSRVD_ES_RES_TYPE_EASYSETUP))
         {
             m_enrolleeResource = resource;
         }
     }
 };
 
-TEST_F(EasysetupMediatorTest, createremoteenrolleeFailedWithNotProvResource)
+TEST_F(EasysetupMediatorTest, createremoteenrolleeFailedWithNotEasySetupResource)
 {
-    auto remoteEnrollee = EasySetup::getInstance()->createRemoteEnrollee(CreateNotProvResource());
+    auto remoteEnrollee = EasySetup::getInstance()->createRemoteEnrollee(CreateNotEasySetupResource());
 
     EXPECT_EQ(nullptr, remoteEnrollee);
 }
 
-TEST_F(EasysetupMediatorTest, createremoteenrolleeSucceedWithProvResource)
+TEST_F(EasysetupMediatorTest, createremoteenrolleeSucceedWithEasySetupResource)
 {
     discoverRemoteEnrollee();
     g_remoteEnrollee = EasySetup::getInstance()->createRemoteEnrollee(m_enrolleeResource);
@@ -240,13 +240,11 @@ TEST_F(GetConfigurationTest, GetConfigurationSucceed)
                 {
                     if(conf.getWiFiModes().at(0) == WIFI_11G &&
                         conf.getWiFiFreq() == WIFI_5G &&
-                        !strcmp(conf.getDeviceName().c_str(), "Test Device") &&
-                        !strcmp(conf.getModelNumber().c_str(), "Test Model Number"))
+                        !strcmp(conf.getDeviceName().c_str(), "Test Device"))
                     {
                         isWellConstructed = true;
                     }
                     cout << "getDeviceName : " << conf.getDeviceName().c_str() << endl;
-                    cout << "getModelNumber : " << conf.getModelNumber().c_str() << endl;
                 }
             }
         });
@@ -345,7 +343,6 @@ TEST_F(ProvisionDevicePropertiesTest,
 {
     DeviceProp devProp;
     devProp.setWiFiProp("Iotivity_SSID", "Iotivity_PWD", WPA2_PSK, TKIP_AES);
-    devProp.setDevConfProp("korean", "Korea", "Location");
 
     EXPECT_ANY_THROW(g_remoteEnrollee->provisionDeviceProperties(devProp, nullptr));
 }
@@ -355,7 +352,6 @@ TEST_F(ProvisionDevicePropertiesTest,
 {
     DeviceProp devProp;
     devProp.setWiFiProp("", "Iotivity_PWD", WPA2_PSK, TKIP_AES);
-    devProp.setDevConfProp("korean", "Korea", "Location");
     EXPECT_ANY_THROW(g_remoteEnrollee->provisionDeviceProperties(devProp,
                                                                  deviceProvisioningStatusCb));
 }
@@ -365,7 +361,6 @@ TEST_F(ProvisionDevicePropertiesTest,
 {
     DeviceProp devProp;
     devProp.setWiFiProp("Iotivity_SSID", "Iotivity_PWD", WPA2_PSK, TKIP_AES);
-    devProp.setDevConfProp("korean", "Korea", "Location");
 
     int cntForReceivedCallbackWithSuccess = 0;
 
diff --git a/service/easy-setup/sampleapp/enrollee/linux-samsung/SConscript b/service/easy-setup/sampleapp/enrollee/linux-samsung/SConscript
new file mode 100755 (executable)
index 0000000..a1074ae
--- /dev/null
@@ -0,0 +1,70 @@
+#######################################################################
+# Copyright 2016 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.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+######################################################################
+# Build script for Linux Enrollee Sample App
+######################################################################
+
+Import('env')
+
+print Dir('#').abspath
+print Dir('.').abspath
+
+enrollee_env = env.Clone()
+transport = enrollee_env.get('TARGET_TRANSPORT')
+
+######################################################################
+# Build flags
+######################################################################
+enrollee_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+enrollee_env.AppendUnique(CXXFLAGS = ['-Wall', '-std=c++0x'])
+
+if env.get('RELEASE'):
+    enrollee_env.AppendUnique(CCFLAGS = ['-Os'])
+    enrollee_env.AppendUnique(CPPDEFINES = ['NDEBUG'])
+else:
+    enrollee_env.AppendUnique(CCFLAGS = ['-g'])
+
+if env.get('LOGGING'):
+    env.AppendUnique(CPPDEFINES = ['TB_LOG'])
+
+enrollee_env.PrependUnique(CPPPATH = [
+               env.get('SRC_DIR') + '/resource/include',
+        env.get('SRC_DIR') + '/resource/oc_logger/include',
+        env.get('SRC_DIR') + '/resource/csdk/logger/include',
+        env.get('SRC_DIR') + '/resource/csdk/stack/include',
+        env.get('SRC_DIR') + '/extlibs/cjson',
+        env.get('SRC_DIR') + '/service/easy-setup/inc',
+        env.get('SRC_DIR') + '/service/easy-setup/enrollee/inc',
+        env.get('SRC_DIR') + '/service/easy-setup/enrollee/src'])
+
+enrollee_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'ocsrm', 'pthread', 'connectivity_abstraction','coap', 'ESEnrolleeSDK'])
+if enrollee_env.get('SECURED') == '1':
+       enrollee_env.PrependUnique(LIBS = ['ocpmapi', 'ocprovision'])
+       enrollee_env.AppendUnique(LIBS = ['mbedtls', 'mbedx509', 'mbedcrypto'])
+
+enrollee = enrollee_env.Program('sc_enrollee', 'sc_enrollee.c')
+
+i_enrollee = enrollee_env.Install(env.get('BUILD_DIR'), enrollee)
+
+justworksdat = enrollee_env.Install(env.get('BUILD_DIR') + '/service/easy-setup/sampleapp/enrollee/linux-samsung/',
+                                    env.get('SRC_DIR') + '/service/easy-setup/sampleapp/enrollee/linux-samsung/oic_svr_db_server.dat')
+
+Alias('enrollee-samsung', [i_enrollee, justworksdat])
+env.AppendTarget('enrollee-samsung')
diff --git a/service/easy-setup/sampleapp/enrollee/linux-samsung/oic_svr_db_server.dat b/service/easy-setup/sampleapp/enrollee/linux-samsung/oic_svr_db_server.dat
new file mode 100644 (file)
index 0000000..82b4e40
Binary files /dev/null and b/service/easy-setup/sampleapp/enrollee/linux-samsung/oic_svr_db_server.dat differ
diff --git a/service/easy-setup/sampleapp/enrollee/linux-samsung/sc_enrollee.c b/service/easy-setup/sampleapp/enrollee/linux-samsung/sc_enrollee.c
new file mode 100755 (executable)
index 0000000..0584ccc
--- /dev/null
@@ -0,0 +1,318 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+
+#include "samsung/sc_easysetup.h"
+
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <oic_string.h>
+#include "oic_malloc.h"
+
+#define TAG "ENROLLEE_SAMPLE"
+
+void *listeningFunc(void *);
+
+/**
+ * Secure Virtual Resource database for Iotivity Server
+ * It contains Server's Identity and the PSK credentials
+ * of other devices which the server trusts
+ */
+static char CRED_FILE[] = "oic_svr_db_server.dat";
+
+OCPersistentStorage ps;
+
+/**
+ * @var gIsSecured
+ * @brief Variable to check if secure mode is enabled or not.
+ */
+static bool gIsSecured = false;
+
+static SCProperties g_SCProperties = {0, 0, "", "", 0, {""}, ""};
+
+void PrintMenu()
+{
+    printf("============\n");
+    printf("S: Enabled Security\n");
+    printf("I: Init & Start EasySetup\n");
+    printf("D: Set DeviceInfo\n");
+    printf("T: Terminate\n");
+    printf("Q: Quit\n");
+    printf("============\n");
+}
+
+void WiFiProvCbInApp(ESWiFiConfData *eventData)
+{
+    printf("WiFiProvCbInApp IN\n");
+
+    if(eventData == NULL)
+    {
+        printf("ESWiFiProvData is NULL\n");
+        return ;
+    }
+
+    printf("SSID : %s\n", eventData->ssid);
+    printf("Password : %s\n", eventData->pwd);
+    printf("AuthType : %d\n", eventData->authtype);
+    printf("EncType : %d\n", eventData->enctype);
+
+    if(eventData->userdata != NULL)
+    {
+        SCWiFiConfProperties *data = eventData->userdata;
+        printf("[SC] DiscoveryChannel : %d\n", data->discoveryChannel);
+    }
+
+    printf("WiFiProvCbInApp OUT\n");
+}
+
+void DevConfProvCbInApp(ESDevConfData *eventData)
+{
+    printf("DevConfProvCbInApp IN\n");
+
+    if(eventData == NULL)
+    {
+        printf("ESDevConfProvData is NULL\n");
+        return ;
+    }
+
+    if(eventData->userdata != NULL)
+    {
+        SCDevConfProperties *data = eventData->userdata;
+        for(int i = 0 ; i < data->numLocation ; ++i)
+        {
+            printf("[SC] Location : %s\n", data->location[i]);
+        }
+        printf("[SC] Register Mobile Device : %s\n", data->regMobileDev);
+        printf("[SC] Country : %s\n", data->country);
+        printf("[SC] Language : %s\n", data->language);
+        printf("[SC] GPS Location : %s\n", data->gpsLocation);
+        printf("[SC] UTC Date time : %s\n", data->utcDateTime);
+        printf("[SC] Regional time : %s\n", data->regionalDateTime);
+    }
+
+    printf("DevConfProvCbInApp OUT\n");
+}
+
+void CloudDataProvCbInApp(ESCoapCloudConfData *eventData)
+{
+    printf("CloudDataProvCbInApp IN\n");
+
+    if(eventData == NULL)
+    {
+        printf("ESCloudProvData is NULL\n");
+        return ;
+    }
+
+    printf("AuthCode : %s\n", eventData->authCode);
+    printf("AuthProvider : %s\n", eventData->authProvider);
+    printf("CI Server : %s\n", eventData->ciServer);
+
+    if(eventData->userdata != NULL)
+    {
+        SCCoapCloudServerConfProperties *data = eventData->userdata;
+        printf("[SC] ClientID : %s\n", data->clientID);
+    }
+
+    printf("CloudDataProvCbInApp OUT\n");
+}
+
+ESProvisioningCallbacks gCallbacks = {
+    .WiFiConfProvCb = &WiFiProvCbInApp,
+    .DevConfProvCb = &DevConfProvCbInApp,
+    .CoapCloudConfProvCb = &CloudDataProvCbInApp
+};
+
+FILE* server_fopen(const char *path, const char *mode)
+{
+    (void) path;
+    return fopen(CRED_FILE, mode);
+}
+
+void EnableSecurity()
+{
+    printf("Inside EnableSecurity API..\n");
+
+    gIsSecured = true;
+
+    // Initialize Persistent Storage for SVR database
+    ps = (OCPersistentStorage){ server_fopen, fread, fwrite, fclose, unlink };
+    OCRegisterPersistentStorageHandler(&ps);
+}
+
+void StartEasySetup()
+{
+    printf("StartEasySetup IN\n");
+
+    if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
+    {
+        printf("OCStack init error!!\n");
+        return;
+    }
+
+    ESResourceMask resourcemMask = ES_WIFICONF_RESOURCE | ES_COAPCLOUDCONF_RESOURCE | ES_DEVCONF_RESOURCE;
+    if(ESInitEnrollee(gIsSecured, resourcemMask, gCallbacks) != ES_OK)
+    {
+        printf("OCStack init error!!\n");
+        return;
+    }
+    printf("ESInitEnrollee Success\n");
+
+    // Set callbacks for Samsung
+    ESSetCallbackForUserdata(&ReadUserdataCb, &WriteUserdataCb);
+
+    pthread_t thread_handle;
+    if (pthread_create(&thread_handle, NULL, listeningFunc, NULL))
+    {
+        printf("Thread creation failed\n");
+    }
+
+    printf("StartEasySetup OUT\n");
+}
+
+void SetDeviceInfo()
+{
+    printf("SetDeviceInfo IN\n");
+
+    ESDeviceProperty deviceProperty = {
+        {{WIFI_11G, WIFI_11N, WIFI_11AC, WiFi_EOF}, WIFI_5G},
+            {"Test Device"}
+    };
+
+    if(ESSetDeviceProperty(&deviceProperty) == ES_ERROR)
+        printf("ESSetDeviceProperty Error\n");
+
+    // Set user properties if needed
+    strncpy(g_SCProperties.deviceType, "deviceType", MAXLEN_STRING);
+    strncpy(g_SCProperties.deviceSubType, "deviceSubType", MAXLEN_STRING);
+    g_SCProperties.netConnectionState = NET_STATE_INIT;
+    g_SCProperties.discoveryChannel = WIFI_DISCOVERY_CHANNEL_INIT;
+    strncpy(g_SCProperties.regSetDev, "{\"wm\":\"00:11:22:33:44:55\",\"pm\":\"00:11:22:33:44:55\",\"bm\":\"00:11:22:33:44:55\",\"rk\":[\"VOICE\",\"EXTRA\",\"BTHIDPOWERON\"],\"sl\":[\"TV2MOBILE\",\"MOBILE2TV\",\"BTWAKEUP\",\"WOWLAN\",\"BTREMOTECON\",\"DLNADMR\"]}", MAXLEN_STRING);
+    strncpy(g_SCProperties.nwProvInfo, "{\"IMEI\":\"123456789012345 / 01\",\"IMSI\":\"123401234567890\",\"MCC_MNC\":\"100_10\",\"SN\":\"XY0123456XYZ\"}", MAXLEN_STRING);
+    strncpy(g_SCProperties.pnpPin, "pinNumber", MAXLEN_STRING);
+    strncpy(g_SCProperties.modelNumber, "Model Number", MAXLEN_STRING);
+    strncpy(g_SCProperties.esProtocolVersion, "2.0", MAXLEN_STRING);
+
+    if(SetSCProperties(&g_SCProperties) == ES_ERROR)
+        printf("SetSCProperties Error\n");
+
+    printf("SetDeviceInfo OUT\n");
+}
+
+void StopEasySetup()
+{
+    printf("StopEasySetup IN\n");
+
+    if (ESTerminateEnrollee() == ES_ERROR)
+    {
+        printf("ESTerminateEnrollee Failed!!\n");
+        return;
+    }
+
+    //stop OC Stack
+    if (OCStop() != OC_STACK_OK)
+    {
+        printf("OCStack stop failed!!\n");
+        return;
+    }
+
+    printf("StopEasySetup OUT\n");
+}
+
+int main()
+{
+    printf("#########################\n");
+    printf("EasySetup Enrollee SAMPLE\n");
+    printf("#########################\n");
+    PrintMenu();
+    char option;
+
+    while(true)
+    {
+        if(scanf("%c", &option) != 1)
+        {
+            printf("Failed to read input data\n");
+            continue;
+        }
+
+        if(option!= '\n')
+        {
+            switch (option)
+            {
+                case 'H': // help
+                case 'h':
+                    PrintMenu();
+                    break;
+
+                case 'Q': // quit
+                case 'q':
+                    printf("quit");
+                    break;
+
+                case 'S': // Enable Security
+                case 's':
+                    EnableSecurity();
+                    PrintMenu();
+                    break;
+
+                case 'I': // Init EasySetup
+                case 'i':
+                    StartEasySetup();
+                    PrintMenu();
+                    break;
+
+                case 'D': // Set Device Info
+                case 'd':
+                    SetDeviceInfo();
+                    PrintMenu();
+                    break;
+                case 'T': // stop easy setup
+                case 't':
+                    StopEasySetup();
+                    PrintMenu();
+                    break;
+                default:
+                    printf("wrong option\n");
+                    PrintMenu();
+                    break;
+            }
+            if (option == 'Q' || option == 'q') break;
+        }
+    }
+    return 0;
+}
+
+void *listeningFunc(void * data)
+{
+    (void)data;
+    OCStackResult result;
+
+    while (true)
+    {
+        result = OCProcess();
+        if (result != OC_STACK_OK)
+        {
+           printf("OCStack stop error");
+        }
+    }
+    return NULL;
+}
+
index 8918906..b680634 100644 (file)
@@ -58,8 +58,7 @@ enrollee_env.PrependUnique(CPPPATH = [
 enrollee_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'ocsrm', 'pthread', 'connectivity_abstraction','coap', 'ESEnrolleeSDK'])
 if enrollee_env.get('SECURED') == '1':
        enrollee_env.PrependUnique(LIBS = ['ocpmapi', 'ocprovision'])
-       if enrollee_env.get('WITH_TCP') == True:
-               enrollee_env.AppendUnique(LIBS = ['mbedtls', 'mbedx509', 'mbedcrypto'])
+       enrollee_env.AppendUnique(LIBS = ['mbedtls', 'mbedx509', 'mbedcrypto'])
 
 enrollee = enrollee_env.Program('enrollee', ['enrolleewifi.c', 'easysetup_x.c'])
 
@@ -68,5 +67,9 @@ i_enrollee = enrollee_env.Install(env.get('BUILD_DIR'), enrollee)
 justworksdat = enrollee_env.Install(env.get('BUILD_DIR') + '/service/easy-setup/sampleapp/enrollee/linux/',
                                     env.get('SRC_DIR') + '/service/easy-setup/sampleapp/enrollee/linux/oic_svr_db_server.dat')
 
-Alias('enrollee', [i_enrollee, justworksdat])
+MOTdat = enrollee_env.Install(env.get('BUILD_DIR') + '/service/easy-setup/sampleapp/enrollee/linux/',
+                                    env.get('SRC_DIR') + '/service/easy-setup/sampleapp/enrollee/linux/oic_svr_db_server_MOT.dat')
+
+
+Alias('enrollee', [i_enrollee, justworksdat, MOTdat])
 env.AppendTarget('enrollee')
index aaa351b..d7a2773 100755 (executable)
@@ -48,18 +48,25 @@ void ReadUserdataCb(OCRepPayload* payload, char* resourceType, void** userdata)
 
     if(payload != NULL)
     {
-        if(strstr(resourceType, OC_RSRVD_ES_RES_TYPE_WIFI))
+        if(strstr(resourceType, OC_RSRVD_ES_RES_TYPE_WIFICONF))
         {
             int64_t value = -1;
             if (OCRepPayloadGetPropInt(payload, USERPROPERTY_KEY_INT, &value))
             {
-                if(*userdata != NULL)
+                if(*userdata == NULL)
                 {
                     *userdata = (void*)OICMalloc(sizeof(UserProperties));
+                    if( *userdata == NULL )
+                    {
+                        OIC_LOG(ERROR, ESX_ENROLLEE_TAG, "OICMalloc for UserProperties is failed");
+                        return ;
+                    }
+                    memset(*userdata, 0, sizeof(UserProperties));
                 }
+
+                ((UserProperties*)(*userdata))->userValue_int = value;
                 OIC_LOG_V(INFO, ESX_ENROLLEE_TAG, "[User specific property] %s : %ld",
                                                                             USERPROPERTY_KEY_INT, value);
-                ((UserProperties*)(*userdata))->userValue_int = value;
                 g_userProperties.userValue_int = value;
             }
         }
@@ -74,7 +81,7 @@ void WriteUserdataCb(OCRepPayload* payload, char* resourceType)
 
     if(payload != NULL)
     {
-        if(strstr(resourceType, OC_RSRVD_ES_RES_TYPE_WIFI))
+        if(strstr(resourceType, OC_RSRVD_ES_RES_TYPE_WIFICONF))
         {
             OCRepPayloadSetPropInt(payload, USERPROPERTY_KEY_INT, g_userProperties.userValue_int);
         }
index a3126c0..ccc096a 100755 (executable)
@@ -39,7 +39,11 @@ pthread_t thread_handle = NULL;
  * It contains Server's Identity and the PSK credentials
  * of other devices which the server trusts
  */
+#ifdef MULTIPLE_OWNER
+static char CRED_FILE[] = "oic_svr_db_server_MOT.dat";
+#else
 static char CRED_FILE[] = "oic_svr_db_server.dat";
+#endif
 
 OCPersistentStorage ps;
 
@@ -63,13 +67,31 @@ void PrintMenu()
     printf("============\n");
 }
 
-void WiFiProvCbInApp(ESWiFiProvData *eventData)
+void ConnectRequestCbInApp(ESConnectRequest *connectRequest)
 {
-    printf("WiFiProvCbInApp IN\n");
+    printf("ConnectRequestCbInApp IN\n");
+
+    if(connectRequest == NULL)
+    {
+        printf("connectRequest is NULL\n");
+        return ;
+    }
+
+    for(int i = 0 ; i < connectRequest->numRequest ; ++i)
+    {
+        printf("connect : %d\n", connectRequest->connect[i]);
+    }
+
+    printf("ConnectRequestCbInApp OUT\n");
+}
+
+void WiFiConfProvCbInApp(ESWiFiConfData *eventData)
+{
+    printf("WiFiConfProvCbInApp IN\n");
 
     if(eventData == NULL)
     {
-        printf("ESWiFiProvData is NULL\n");
+        printf("ESWiFiConfData is NULL\n");
         return ;
     }
 
@@ -83,46 +105,46 @@ void WiFiProvCbInApp(ESWiFiProvData *eventData)
         printf("userValue : %d\n", ((UserProperties *)(eventData->userdata))->userValue_int);
     }
 
-    printf("WiFiProvCbInApp OUT\n");
+    printf("WiFiConfProvCbInApp OUT\n");
 }
 
-void DevConfProvCbInApp(ESDevConfProvData *eventData)
+void DevConfProvCbInApp(ESDevConfData *eventData)
 {
     printf("DevConfProvCbInApp IN\n");
 
     if(eventData == NULL)
     {
-        printf("ESDevConfProvData is NULL\n");
+        printf("ESDevConfData is NULL\n");
         return ;
     }
 
-    printf("Language : %s\n", eventData->language);
-    printf("Country : %s\n", eventData->country);
-
     printf("DevConfProvCbInApp OUT\n");
 }
 
-void CloudDataProvCbInApp(ESCloudProvData *eventData)
+void CoapCloudConfProvCbInApp(ESCoapCloudConfData *eventData)
 {
-    printf("CloudDataProvCbInApp IN\n");
+    printf("CoapCloudConfProvCbInApp IN\n");
 
     if(eventData == NULL)
     {
-        printf("ESCloudProvData is NULL\n");
+        printf("ESCoapCloudConfData is NULL\n");
         return ;
     }
 
     printf("AuthCode : %s\n", eventData->authCode);
+    printf("AcessToken : %s\n", eventData->accessToken);
+    printf("AcessTokenType : %d\n", eventData->accessTokenType);
     printf("AuthProvider : %s\n", eventData->authProvider);
     printf("CI Server : %s\n", eventData->ciServer);
 
-    printf("CloudDataProvCbInApp OUT\n");
+    printf("CoapCloudConfProvCbInApp OUT\n");
 }
 
 ESProvisioningCallbacks gCallbacks = {
-    .WiFiProvCb = &WiFiProvCbInApp,
+    .ConnectRequestCb = &ConnectRequestCbInApp,
+    .WiFiConfProvCb = &WiFiConfProvCbInApp,
     .DevConfProvCb = &DevConfProvCbInApp,
-    .CloudDataProvCb = &CloudDataProvCbInApp
+    .CoapCloudConfProvCb = &CoapCloudConfProvCbInApp
 };
 
 FILE* server_fopen(const char *path, const char *mode)
@@ -152,7 +174,7 @@ void StartEasySetup()
         return;
     }
 
-    ESResourceMask resourcemMask = ES_WIFI_RESOURCE | ES_CLOUD_RESOURCE | ES_DEVCONF_RESOURCE;
+    ESResourceMask resourcemMask = ES_WIFICONF_RESOURCE | ES_COAPCLOUDCONF_RESOURCE | ES_DEVCONF_RESOURCE;
     if(ESInitEnrollee(gIsSecured, resourcemMask, gCallbacks) != ES_OK)
     {
         printf("OCStack init error!!\n");
@@ -173,13 +195,14 @@ void SetDeviceInfo()
     printf("SetDeviceInfo IN\n");
 
     ESDeviceProperty deviceProperty = {
-        {{WIFI_11G, WIFI_11N, WIFI_11AC, WiFi_EOF}, WIFI_5G}, {"Test Device", "Test Model Number"}
+        {{WIFI_11G, WIFI_11N, WIFI_11AC, WiFi_EOF}, WIFI_5G}, {"Test Device"}
     };
 
     // Set user properties if needed
     char userValue_str[] = "user_str";
     g_userProperties.userValue_int = 0;
-    strcpy(g_userProperties.userValue_str, userValue_str);
+
+    strncpy(g_userProperties.userValue_str, userValue_str, strlen(userValue_str) + 1);
     SetUserProperties(&g_userProperties);
 
     if(ESSetDeviceProperty(&deviceProperty) == ES_ERROR)
@@ -227,7 +250,7 @@ int main()
     printf("EasySetup Enrollee SAMPLE\n");
     printf("#########################\n");
     PrintMenu();
-    char option;
+    char option = '\0';
 
     while(true)
     {
@@ -284,7 +307,10 @@ int main()
                     PrintMenu();
                     break;
             }
-            if (option == 'Q' || option == 'q') { break; }
+            if (option == 'Q' || option == 'q')
+            {
+                break;
+            }
         }
     }
     return 0;
index 82b4e40..135d7b3 100644 (file)
Binary files a/service/easy-setup/sampleapp/enrollee/linux/oic_svr_db_server.dat and b/service/easy-setup/sampleapp/enrollee/linux/oic_svr_db_server.dat differ
diff --git a/service/easy-setup/sampleapp/enrollee/linux/oic_svr_db_server_MOT.dat b/service/easy-setup/sampleapp/enrollee/linux/oic_svr_db_server_MOT.dat
new file mode 100644 (file)
index 0000000..49b1490
Binary files /dev/null and b/service/easy-setup/sampleapp/enrollee/linux/oic_svr_db_server_MOT.dat differ
index 1c9271b..75e55b8 100644 (file)
@@ -77,6 +77,13 @@ help_vars.Add(EnumVariable('TARGET_ARCH', 'Target architecture', default_arch, o
 help_vars.Add(EnumVariable('SECURED', 'Build with DTLS', '0', allowed_values=('0', '1')))
 help_vars.Add(EnumVariable('ROUTING', 'Enable routing', 'EP', allowed_values=('GW', 'EP')))
 
+AddOption('--prefix',
+                  dest='prefix',
+                  type='string',
+                  nargs=1,
+                  action='store',
+                  metavar='DIR',
+                  help='installation prefix')
 ######################################################################
 # Platform(build target) specific options: SDK/NDK & toolchain
 ######################################################################
old mode 100644 (file)
new mode 100755 (executable)
index bdf7a8a..b00216e
@@ -34,7 +34,6 @@ cp -LR ./extlibs/tinycbor $sourcedir/tmp/extlibs
 cp -R ./extlibs/cjson $sourcedir/tmp/extlibs
 cp -R ./extlibs/mbedtls $sourcedir/tmp/extlibs
 cp -R ./extlibs/gtest $sourcedir/tmp/extlibs
-cp -R ./extlibs/tinydtls $sourcedir/tmp/extlibs
 cp -LR ./extlibs/sqlite3 $sourcedir/tmp/extlibs
 cp -R ./extlibs/timer $sourcedir/tmp/extlibs
 cp -R ./extlibs/rapidxml $sourcedir/tmp/extlibs
@@ -74,7 +73,7 @@ if [ ! -d .git ]; then
    git commit -m "Initial commit"
 fi
 
-buildoption="--define 'TARGET_TRANSPORT '$1 --define 'SECURED '$2 --define 'ROUTING '$3 --define 'RELEASE '$4 --define 'LOGGING '$5 --define 'ES_TARGET_ENROLLEE '$6 --define 'WITH_TCP '$7 --define 'WITH_CLOUD '$8" 
+buildoption="--define 'TARGET_TRANSPORT '$1 --define 'SECURED '$2 --define 'ROUTING '$3 --define 'RELEASE '$4 --define 'LOGGING '$5 --define 'ES_TARGET_ENROLLEE '$6 --define 'WITH_TCP '$7 --define 'WITH_CLOUD '$8"
 echo "Calling core gbs build command"
 gbscommand="gbs build -A armv7l -B ~/GBS-ROOT-OIC $buildoption --include-all --repository ./"
 echo $gbscommand
index 83c2fc7..8c7c58c 100755 (executable)
@@ -70,16 +70,35 @@ void PrintMenu()
     cout << "========================" << endl;
 }
 
-void WiFiProvCbInApp(ESWiFiProvData *eventData)
+void ConnectRequestCbInApp(ESConnectRequest *connectRequest)
 {
-    cout << "WiFiProvCbInApp IN" << endl;
+    cout << "ConnectRequestCbInApp IN" << endl;
+
+    if(connectRequest == NULL)
+    {
+        cout << "connectRequest is NULL" << endl;
+        return ;
+    }
+
+    for(int i = 0 ; i < connectRequest->numRequest ; ++i)
+    {
+        cout << "connect : " << connectRequest->connect[i] << endl;
+    }
+
+    cout << "ConnectRequestCbInApp OUT" << endl;
+    PrintMenu();
+}
+
+void WiFiConfProvCbInApp(ESWiFiConfData *eventData)
+{
+    cout << "WiFiConfProvCbInApp IN" << endl;
     gWiFiCBflag = true;
 
     ESSetState(ES_STATE_CONNECTING_TO_ENROLLER);
 
     if(eventData == NULL)
     {
-        cout << "ESWiFiProvData is NULL" << endl;
+        cout << "ESWiFiConfData is NULL" << endl;
         return ;
     }
 
@@ -100,47 +119,46 @@ void WiFiProvCbInApp(ESWiFiProvData *eventData)
         strncpy(gPasswd, eventData->pwd, strlen(eventData->pwd));
     }
 
-    cout << "WiFiProvCbInApp OUT" << endl;
+    cout << "WiFiConfProvCbInApp OUT" << endl;
     PrintMenu();
 }
 
-void DevConfProvCbInApp(ESDevConfProvData *eventData)
+void DevConfProvCbInApp(ESDevConfData *eventData)
 {
     cout << "DevConfProvCbInApp IN" << endl;
 
     if(eventData == NULL)
     {
-        cout << "ESDevConfProvData is NULL" << endl;
+        cout << "ESDevConfData is NULL" << endl;
         return ;
     }
 
-    cout << "Language : " << eventData->language << endl;
-    cout << "Country : " << eventData->country << endl;
     cout << "DevConfProvCbInApp OUT" << endl;
     PrintMenu();
 }
 
-void CloudDataProvCbInApp(ESCloudProvData *eventData)
+void CoapCloudConfProvCbInApp(ESCoapCloudConfData *eventData)
 {
-    cout << "CloudDataProvCbInApp IN" << endl;
+    cout << "CoapCloudConfProvCbInApp IN" << endl;
 
     if(eventData == NULL)
     {
-        cout << "ESCloudProvData is NULL" << endl;
+        cout << "ESCoapCloudConfData is NULL" << endl;
         return ;
     }
 
     cout << "AuthCode : " << eventData->authCode << endl;
     cout << "AuthProvider : " << eventData->authProvider << endl;
     cout << "CI Server : " << eventData->ciServer << endl;
-    cout << "CloudDataProvCbInApp OUT" << endl;
+    cout << "CoapCloudConfProvCbInApp OUT" << endl;
     PrintMenu();
 }
 
 ESProvisioningCallbacks gCallbacks = {
-    .WiFiProvCb = &WiFiProvCbInApp,
+    .ConnectRequestCb = &ConnectRequestCbInApp,
+    .WiFiConfProvCb = &WiFiConfProvCbInApp,
     .DevConfProvCb = &DevConfProvCbInApp,
-    .CloudDataProvCb = &CloudDataProvCbInApp
+    .CoapCloudConfProvCb = &CoapCloudConfProvCbInApp
 };
 
 FILE* server_fopen(const char *path, const char *mode)
@@ -170,7 +188,7 @@ void StartEasySetup()
         return;
     }
 
-    ESResourceMask resourcemMask = (ESResourceMask) (ES_WIFI_RESOURCE | ES_CLOUD_RESOURCE | ES_DEVCONF_RESOURCE);
+    ESResourceMask resourcemMask = (ESResourceMask) (ES_WIFICONF_RESOURCE | ES_COAPCLOUDCONF_RESOURCE | ES_DEVCONF_RESOURCE);
     cout << "resourcemMask : " << resourcemMask << endl;
     if(ESInitEnrollee(gIsSecured, resourcemMask, gCallbacks) != ES_OK)
     {
index 981d6b0..56ae07b 100644 (file)
@@ -29,8 +29,8 @@ root_dir = env.get('ROOT_DIR')
 build_dir = env.get('BUILD_DIR')
 sample_dir = build_dir
 
-env.ParseConfig("pkg-config --cflags --libs capi-network-wifi dlog gobject-2.0 gio-2.0 gthread-2.0 glib-2.0")
-env.AppendUnique(CPPFLAGS = ['-std=c++0x', '-fPIC', '-D__TIZEN__','-DWITH_POSIX', '-Wall', '-DSLP_SDK_LOG', '-g','-D_GNU_SOURCE','-DTIZEN_DEBUG_ENABLE', '-DTB_LOG','`pkg-config', '--cflags', '--libs','dlog','capi-network-wifi',
+env.ParseConfig("pkg-config --cflags --libs capi-network-wifi dlog gobject-2.0 gio-2.0 gthread-2.0 glib-2.0 iotivity")
+env.AppendUnique(CPPFLAGS = ['-fPIC', '-D__TIZEN__','-DWITH_POSIX', '-Wall', '-DSLP_SDK_LOG', '-g','-D_GNU_SOURCE','-DTIZEN_DEBUG_ENABLE', '-DTB_LOG','`pkg-config', '--cflags', '--libs', 'iotivity', 'dlog','capi-network-wifi',
                 'gobject-2.0', 'gio-2.0', 'gthread-2.0', 'glib-2.0`'])
 
 env.AppendUnique(CPPDEFINES = ['TB_LOG'])
diff --git a/service/easy-setup/sampleapp/mediator/android-samsung/.gitignore b/service/easy-setup/sampleapp/mediator/android-samsung/.gitignore
new file mode 100644 (file)
index 0000000..6451fc5
--- /dev/null
@@ -0,0 +1,50 @@
+#built application files\r
+*.apk\r
+*.ap_\r
+\r
+# files for the dex VM\r
+*.dex\r
+\r
+# Java class files\r
+*.class\r
+\r
+# generated files\r
+bin/\r
+gen/\r
+\r
+# Local configuration file (sdk path, etc)\r
+local.properties\r
+\r
+# Proguard folder generated by Eclipse \r
+proguard/ \r
+\r
+# Windows thumbnail db\r
+Thumbs.db\r
+\r
+# OSX files\r
+.DS_Store\r
+\r
+# Eclipse project files\r
+.classpath\r
+.project\r
+\r
+#Android Studio & Gradle\r
+.gradle\r
+/local.properties\r
+/.idea/workspace.xml\r
+/.idea/libraries\r
+.DS_Store\r
+/build/*\r
+/base/build/*\r
+/base/obj/*\r
+/base/libs/*\r
+/sample/*\r
+\r
+#Some older projects\r
+/*/out\r
+/*/*/build\r
+/*/*/production\r
+*.iws\r
+*.ipr\r
+*~\r
+*.swp
\ No newline at end of file
diff --git a/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/EasySetup.iml b/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/EasySetup.iml
new file mode 100755 (executable)
index 0000000..b8f4dc9
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<module external.linked.project.id="EasySetup" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">\r
+  <component name="FacetManager">\r
+    <facet type="java-gradle" name="Java-Gradle">\r
+      <configuration>\r
+        <option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />\r
+        <option name="BUILDABLE" value="false" />\r
+      </configuration>\r
+    </facet>\r
+  </component>\r
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="true">\r
+    <exclude-output />\r
+    <content url="file://$MODULE_DIR$">\r
+      <excludeFolder url="file://$MODULE_DIR$/.gradle" />\r
+    </content>\r
+    <orderEntry type="inheritedJdk" />\r
+    <orderEntry type="sourceFolder" forTests="false" />\r
+  </component>\r
+</module>\r
diff --git a/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/EasySetupGradle.iml b/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/EasySetupGradle.iml
new file mode 100644 (file)
index 0000000..4ac7e4f
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.id="EasySetupGradle" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="java-gradle" name="Java-Gradle">
+      <configuration>
+        <option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
+        <option name="BUILDABLE" value="false" />
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <excludeFolder url="file://$MODULE_DIR$/.gradle" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/app.iml b/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/app.iml
new file mode 100644 (file)
index 0000000..cb62b4a
--- /dev/null
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="EasySetup" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="android-gradle" name="Android-Gradle">
+      <configuration>
+        <option name="GRADLE_PROJECT_PATH" value=":app" />
+      </configuration>
+    </facet>
+    <facet type="android" name="Android">
+      <configuration>
+        <option name="SELECTED_BUILD_VARIANT" value="debug" />
+        <option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
+        <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
+        <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
+        <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugAndroidTest" />
+        <option name="COMPILE_JAVA_TEST_TASK_NAME" value="compileDebugAndroidTestSources" />
+        <afterSyncTasks>
+          <task>generateDebugAndroidTestSources</task>
+          <task>generateDebugSources</task>
+        </afterSyncTasks>
+        <option name="ALLOW_USER_CONFIGURATION" value="false" />
+        <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
+        <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
+        <option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
+        <option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="false">
+    <output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
+    <output-test url="file://$MODULE_DIR$/build/intermediates/classes/androidTest/debug" />
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/androidTest/debug" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
+      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/EasySetup/EasySetupCore-debug/unspecified/jars" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/EasySetup/iotivity-armeabi-base-debug/unspecified/jars" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
+      <excludeFolder url="file://$MODULE_DIR$/build/outputs" />
+      <excludeFolder url="file://$MODULE_DIR$/build/tmp" />
+    </content>
+    <orderEntry type="jdk" jdkName="Android API 21 Platform" jdkType="Android SDK" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module" module-name="EasySetupCore-debug" exported="" />
+    <orderEntry type="module" module-name="iotivity-armeabi-base-debug" exported="" />
+    <orderEntry type="library" exported="" name="EasySetupCore-debug-unspecified" level="project" />
+    <orderEntry type="library" exported="" name="iotivity-armeabi-base-debug-unspecified" level="project" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/build.gradle b/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/build.gradle
new file mode 100644 (file)
index 0000000..11c057b
--- /dev/null
@@ -0,0 +1,58 @@
+//******************************************************************
+//
+// Copyright 2016 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+apply plugin: 'com.android.application'
+
+android {
+    compileSdkVersion 21
+    buildToolsVersion "20.0.0"
+
+    defaultConfig {
+        applicationId "org.iotivity.service.easysetup"
+        minSdkVersion 21
+        targetSdkVersion 21
+        versionCode 1
+        versionName "1.0"
+    }
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+    }
+    lintOptions {
+        abortOnError false
+    }
+}
+repositories {
+    flatDir {
+        dirs "../../../../../../../android/android_api/base/build/outputs/aar/", "../../../../../mediator/richsdk/android/EasySetupCore/build/outputs/aar/"
+    }
+}
+
+try {
+    dependencies {
+        compile ":iotivity-base-${TARGET_ARCH}-${RELEASE}@aar"
+        compile ":EasySetupCore-${RELEASE}@aar"
+    }
+} catch (all) {
+    print "${ERROR_MSG}"
+    assert all
+}
diff --git a/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/proguard-rules.pro b/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/proguard-rules.pro
new file mode 100644 (file)
index 0000000..d26150c
--- /dev/null
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/rahul/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/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/AndroidManifest.xml b/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/AndroidManifest.xml
new file mode 100644 (file)
index 0000000..6bae09a
--- /dev/null
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="org.iotivity.service.easysetup"
+    android:versionCode="1"
+    android:versionName="1.0">
+
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+
+    <uses-feature
+        android:name="android.hardware.touchscreen"
+        android:required="false" />
+
+    <application
+        android:allowBackup="true"
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name"
+        android:theme="@style/AppTheme">
+        <activity
+            android:name=".LoginActivity"
+            android:label="@string/app_name">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+            </intent-filter>
+        </activity>
+        <activity android:name=".EasysetupActivity" android:label="@string/app_name">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
diff --git a/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/assets/oic_svr_db_client.dat b/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/assets/oic_svr_db_client.dat
new file mode 100644 (file)
index 0000000..229c8ad
Binary files /dev/null and b/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/assets/oic_svr_db_client.dat differ
diff --git a/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/assets/oic_svr_db_client.json b/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/assets/oic_svr_db_client.json
new file mode 100644 (file)
index 0000000..2d47964
--- /dev/null
@@ -0,0 +1,88 @@
+{\r
+    "acl": {\r
+        "aclist": {\r
+            "aces": [\r
+                {\r
+                    "subjectuuid": "*",\r
+                    "resources": [\r
+                        {\r
+                            "href": "/oic/res",\r
+                            "rel": "",\r
+                            "rt": ["oic.wk.res"],\r
+                            "if": ["oic.if.ll"]\r
+                        },\r
+                        {\r
+                            "href": "/oic/d",\r
+                            "rel": "",\r
+                            "rt": ["oic.wk.d"],\r
+                            "if": ["oic.if.baseline", "oic.if.r"]\r
+                        },\r
+                        {\r
+                            "href": "/oic/p",\r
+                            "rel": "",\r
+                            "rt": ["oic.wk.p"],\r
+                            "if": ["oic.if.baseline", "oic.if.r"]\r
+                        },\r
+                        {\r
+                            "href": "/oic/ad",\r
+                            "rel": "",\r
+                            "rt": ["oic.wk.ad"],\r
+                            "if": ["oic.if.baseline"]\r
+                        },\r
+                        {\r
+                            "href": "/oic/sec/acl",\r
+                            "rel": "",\r
+                            "rt": ["oic.r.acl"],\r
+                            "if": ["oic.if.baseline"]\r
+                        },\r
+                        {\r
+                            "href": "/oic/res/types/d",\r
+                            "rel": "",\r
+                            "rt": ["oic.wk.res"],\r
+                            "if": ["oic.if.baseline"]\r
+                        }\r
+                    ],\r
+                    "permission": 2\r
+                },\r
+                {\r
+                    "subjectuuid": "*",\r
+                    "resources": [\r
+                        {\r
+                            "href": "/oic/sec/doxm",\r
+                            "rel": "",\r
+                            "rt": ["oic.r.doxm"],\r
+                            "if": ["oic.if.baseline"]\r
+                        },\r
+                        {\r
+                            "href": "/oic/sec/pstat",\r
+                            "rel": "",\r
+                            "rt": ["oic.r.pstat"],\r
+                            "if": ["oic.if.baseline"]\r
+                        }\r
+                    ],\r
+                    "permission": 2\r
+                }\r
+            ]\r
+        },\r
+        "rowneruuid" : "61646d69-6e44-6576-6963-655575696430"\r
+    },\r
+    "pstat": {\r
+        "isop": true,\r
+        "deviceuuid": "61646d69-6e44-6576-6963-655575696430",\r
+        "rowneruuid": "61646d69-6e44-6576-6963-655575696430",\r
+        "cm": 0,\r
+        "tm": 0,\r
+        "om": 3,\r
+        "sm": 3\r
+        },\r
+    "doxm": {\r
+        "oxms": [0],\r
+        "oxmsel": 0,\r
+        "sct": 1,\r
+        "owned": true,\r
+        "deviceuuid": "61646d69-6e44-6576-6963-655575696430",\r
+        "devowneruuid": "61646d69-6e44-6576-6963-655575696430",\r
+        "rowneruuid": "61646d69-6e44-6576-6963-655575696430",\r
+        "x.com.samsung.dpc": false\r
+    }\r
+}\r
diff --git a/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/java/org/iotivity/service/easysetup/EasysetupActivity.java b/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/java/org/iotivity/service/easysetup/EasysetupActivity.java
new file mode 100755 (executable)
index 0000000..9b079eb
--- /dev/null
@@ -0,0 +1,1136 @@
+/**
+ * ***************************************************************
+ * <p/>
+ * Copyright 2016 Samsung Electronics All Rights Reserved.
+ * <p/>
+ * <p/>
+ * <p/>
+ * 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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.
+ * <p/>
+ * ****************************************************************
+ */
+
+package org.iotivity.service.easysetup;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.util.Log;
+import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.RadioButton;
+import android.widget.RadioGroup;
+import android.widget.Spinner;
+import android.widget.TextView;
+import android.widget.Toast;
+import android.widget.ToggleButton;
+
+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.ObserveType;
+import org.iotivity.base.OcPlatform;
+import org.iotivity.base.OcPresenceStatus;
+import org.iotivity.base.OcProvisioning;
+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 org.iotivity.base.OcAccountManager;
+import org.iotivity.service.easysetup.mediator.ESConstants;
+import org.iotivity.service.easysetup.mediator.CloudProp;
+import org.iotivity.service.easysetup.mediator.CloudPropProvisioningCallback;
+import org.iotivity.service.easysetup.mediator.CloudPropProvisioningStatus;
+import org.iotivity.service.easysetup.mediator.DevicePropProvisioningCallback;
+import org.iotivity.service.easysetup.mediator.DevicePropProvisioningStatus;
+import org.iotivity.service.easysetup.mediator.ESException;
+import org.iotivity.service.easysetup.mediator.EasySetup;
+import org.iotivity.service.easysetup.mediator.GetConfigurationCallback;
+import org.iotivity.service.easysetup.mediator.GetConfigurationStatus;
+import org.iotivity.service.easysetup.mediator.RemoteEnrollee;
+import org.iotivity.service.easysetup.mediator.SecurityProvisioningCallback;
+import org.iotivity.service.easysetup.mediator.SecurityProvisioningStatus;
+import org.iotivity.service.easysetup.mediator.enums.ESCloudProvState;
+import org.iotivity.service.easysetup.mediator.enums.ESResult;
+import org.iotivity.service.easysetup.mediator.enums.WIFI_AUTHTYPE;
+import org.iotivity.service.easysetup.mediator.enums.WIFI_ENCTYPE;
+import org.iotivity.service.easysetup.mediator.enums.WIFI_FREQ;
+import org.iotivity.service.easysetup.mediator.enums.WIFI_MODE;
+import org.iotivity.service.easysetup.mediator.samsung.SCDeviceProp;
+import org.iotivity.service.easysetup.mediator.samsung.SCEnrolleeConf;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.List;
+
+
+public class EasysetupActivity extends Activity
+                                implements OcPlatform.OnPresenceListener,
+                                           OcResource.OnObserveListener{
+    private static final String TAG = "Easysetup Mediator: ";
+    PlatformConfig cfg;
+    OcAccountManager m_accountManager = null;
+    final String deviceID = "9E09F4FE-978A-4BC3-B356-1F93BCA37829";
+    final String samsungCIServer = "coap+tcp://52.69.149.85:5683";
+
+    private static final int BUFFER_SIZE = 1024;
+
+    private String filePath = "";
+    public static final String OIC_CLIENT_JSON_DB_FILE =  "oic_svr_db_client.dat";
+    public static final String OIC_SQL_DB_FILE =  "PDM.db";
+
+    private boolean isFirstTime = true;
+    String mEnrolleeDeviceID;
+    String mAuthCode;
+    String mAuthProvider;
+    String mRefreshtoken;
+    String mUserID;
+    String mAccessToken;
+    String mEnrolleeAuthCode;
+
+    ToggleButton mSecurityMode;
+
+    RadioGroup mEasysetupProcess;
+    RadioButton mConfigureSecProcess;
+    RadioButton mGetConfigurationProcess;
+    RadioButton mProvisionDevPropProcess;
+    RadioButton mProvisionCloudPropProcess;
+
+    Button mDiscoverResource;
+    Button mStartGetConfiguration;
+    Button mStartConfigureSec;
+    Button mStartProvisionDevProp;
+    Button mStartProvisionCloudProp;
+
+    TextView mGetconfigurationStateText;
+    TextView mDevNameText;
+    TextView mModelNumberText;
+    TextView mDevTypeText;
+    TextView mDevSubTypeText;
+    TextView mWifiModeText;
+    TextView mWifiFreqText;
+    TextView mCloudAccessableText;
+    TextView mSecStateText;
+    TextView mSecDevIDText;
+    TextView mProvisionDevPropState;
+    TextView mProvisionCloudPropState;
+
+    EditText mEnrollerSsidText;
+    EditText mEnrollerPWText;
+    EditText mInputLanguageText;
+    EditText mInputCountryText;
+    EditText mInputLocationText;
+    EditText mDiscoveryChannelText;
+    EditText mAddrText;
+    EditText mZipCodeText;
+    EditText mBuildingText;
+    EditText mAuthCodeText;
+    EditText mAuthProviderText;
+    EditText mCIServerText;
+
+    LinearLayout mGetConfigurationInfo;
+    LinearLayout mConfigureSecInfo;
+    LinearLayout mProvisionDevPropInfo;
+    LinearLayout mProvisionCloudPropInfo;
+
+    Spinner mAuthType;
+    Spinner mEncType;
+
+    EasySetup mEasySetup;
+    RemoteEnrollee mRemoteEnrollee;
+
+    Activity mActivity;
+    Context mContext;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.easysetup_main);
+
+        mActivity = EasysetupActivity.this;
+        mContext = mActivity.getBaseContext();
+
+        mSecurityMode = (ToggleButton) findViewById(R.id.btn_Security);
+
+        mEasysetupProcess = (RadioGroup) findViewById(R.id.rg_EasysetupProcess);
+
+        mConfigureSecProcess = (RadioButton) findViewById(R.id.btn_configurSec);
+        mGetConfigurationProcess = (RadioButton) findViewById(R.id.btn_getConfiguration);
+        mProvisionDevPropProcess = (RadioButton) findViewById(R.id.btn_provisionDevConf);
+        mProvisionCloudPropProcess =
+                (RadioButton) findViewById(R.id.btn_provisionCloudConf);
+
+        mDiscoverResource = (Button) findViewById(R.id.btn_discoverResource);
+        mStartGetConfiguration =
+                (Button) findViewById(R.id.btn_startGetConfiguration);
+        mStartConfigureSec = (Button) findViewById(R.id.btn_startConfigureSec);
+        mStartProvisionDevProp = (Button) findViewById(R.id.btn_startProvisionDevConf);
+        mStartProvisionCloudProp = (Button) findViewById(R.id.btn_startProvisionCloudConf);
+
+        mGetconfigurationStateText =
+                (TextView) findViewById(R.id.txt_getConfigurationState);
+        mDevNameText = (TextView) findViewById(R.id.txt_devName);
+        mModelNumberText = (TextView) findViewById(R.id.txt_modelNumber);
+        mDevTypeText = (TextView) findViewById(R.id.txt_devType);
+        mDevSubTypeText = (TextView) findViewById(R.id.txt_devSubType);
+        mWifiModeText = (TextView) findViewById(R.id.txt_wifiMode);
+        mWifiFreqText = (TextView) findViewById(R.id.txt_wifiFreq);
+        mCloudAccessableText = (TextView) findViewById(R.id.txt_cloudAccessable);
+        mSecStateText = (TextView) findViewById(R.id.txt_secState);
+        mSecDevIDText = (TextView) findViewById(R.id.txt_secDevID);
+        mProvisionDevPropState = (TextView) findViewById(R.id.txt_provisionDevConfState);
+        mProvisionCloudPropState =
+                (TextView) findViewById(R.id.txt_provisionCloudConfState);
+
+        mEnrollerSsidText = (EditText) findViewById(R.id.editText_EnrollerSSID);
+        mEnrollerPWText = (EditText) findViewById(R.id.editText_EnrollerPW);
+        mInputLanguageText = (EditText) findViewById(R.id.editText_Language);
+        mInputCountryText = (EditText) findViewById(R.id.editText_Country);
+        mInputLocationText = (EditText) findViewById(R.id.editText_Location);
+        mDiscoveryChannelText = (EditText) findViewById(R.id.editText_DiscoveryChannel);
+        mAddrText = (EditText) findViewById(R.id.editText_LocationAddr);
+        mZipCodeText = (EditText) findViewById(R.id.editText_LocationZip);
+        mBuildingText = (EditText) findViewById(R.id.editText_LocationBuilding);
+        mAuthCodeText = (EditText) findViewById(R.id.editText_authcode);
+        mAuthProviderText = (EditText) findViewById(R.id.editText_authprovider);
+        mCIServerText = (EditText) findViewById(R.id.editText_ciserver);
+
+        mGetConfigurationInfo =
+                (LinearLayout) findViewById(R.id.layout_GetConfiguration);
+        mConfigureSecInfo = (LinearLayout) findViewById(R.id.layout_ConfigurSec);
+        mProvisionDevPropInfo = (LinearLayout) findViewById(R.id.layout_ProvisionDevConf);
+        mProvisionCloudPropInfo = (LinearLayout) findViewById(R.id.layout_ProvisionCloudConf);
+
+        mAuthType = (Spinner) findViewById(R.id.spinner_authType);
+        mEncType = (Spinner) findViewById(R.id.spinner_encType);
+
+        mEasysetupProcess.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
+            @Override
+            public void onCheckedChanged(RadioGroup group, int checkedId) {
+                mGetConfigurationInfo.setVisibility(View.GONE);
+                mConfigureSecInfo.setVisibility(View.GONE);
+                mProvisionDevPropInfo.setVisibility(View.GONE);
+                mProvisionCloudPropInfo.setVisibility(View.GONE);
+
+                switch (checkedId) {
+                    case R.id.btn_configurSec:
+                        mConfigureSecInfo.setVisibility(View.VISIBLE);
+                        break;
+
+                    case R.id.btn_getConfiguration:
+                        mGetConfigurationInfo.setVisibility(View.VISIBLE);
+                        break;
+
+                    case R.id.btn_provisionDevConf:
+                        mProvisionDevPropInfo.setVisibility(View.VISIBLE);
+                        break;
+
+                    case R.id.btn_provisionCloudConf:
+                        Log.d(TAG, "Starting login activity");
+                        Intent intent = new Intent(EasysetupActivity.this, LoginActivity.class);
+                        startActivityForResult(intent, 2);
+                        mProvisionCloudPropInfo.setVisibility(View.VISIBLE);
+                        break;
+                }
+            }
+        });
+
+        ArrayAdapter<CharSequence> adAuthType, adEnctype;
+
+        adAuthType = ArrayAdapter.createFromResource(this, R.array.auth_type,
+                android.R.layout.simple_spinner_item);
+        adAuthType.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+
+        adEnctype = ArrayAdapter.createFromResource(this, R.array.enc_type,
+                android.R.layout.simple_spinner_item);
+        adEnctype.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+
+        mAuthType.setAdapter(adAuthType);
+        mAuthType.setSelection(0);
+
+        mEncType.setAdapter(adEnctype);
+        mEncType.setSelection(0);
+
+        addListenerForDiscoverEnrollee();
+        addListenerForStartConfigureSec();
+        addListenerForStartGetConfiguration();
+        addListenerForStartProvisionDevProp();
+        addListenerForStartProvisionCloudProp();
+
+        mSecurityMode.setClickable(false);
+        mConfigureSecProcess.setEnabled(false);
+        mGetConfigurationProcess.setEnabled(false);
+        mProvisionDevPropProcess.setEnabled(false);
+        mProvisionCloudPropProcess.setEnabled(false);
+
+        mEasySetup = EasySetup.getInstance(getApplicationContext());
+
+        initOICStack();
+
+        try {
+            m_accountManager = OcPlatform.constructAccountManagerObject(
+                    samsungCIServer,
+                    EnumSet.of(OcConnectivityType.CT_ADAPTER_TCP));
+
+            Log.e(TAG, "constructAccountManagerObject is successful");
+        } catch (OcException e) {
+            Log.e(TAG, e.toString());
+            Log.e(TAG,"Failed to constructAccountManagerObject");
+        }
+        SharedPreferences settings =
+                                getApplicationContext().getSharedPreferences("IoTivityCloud", 0);
+        mAccessToken = settings.getString("accesstoken", null);
+        mRefreshtoken = settings.getString("refreshtoken", null);
+        mUserID = settings.getString("uid", null);
+
+        if(mRefreshtoken == null)
+        {
+            Log.d(TAG, "Can not find refresh token");
+        }
+
+        if(mAccessToken == null && mRefreshtoken == null)
+        {
+            /* Samsung account */
+            Log.d(TAG, "Starting login activity");
+
+            Intent intent = new Intent(EasysetupActivity.this, LoginActivity.class);
+            startActivityForResult(intent, 1);
+        }
+        else if(mAccessToken != null)
+        {
+            SignInDevice();
+        }
+    }
+
+    private void initOICStack() {
+        filePath = getFilesDir().getPath() + "/";
+
+        SharedPreferences wmbPreference = PreferenceManager.getDefaultSharedPreferences
+                (getApplicationContext());
+        boolean isFirstRun = wmbPreference.getBoolean("FIRSTRUN", true);
+        if (isFirstRun) {
+            if(!copyJsonFromAsset())
+            {
+                Log.e(TAG, "initOICStack error: " + "copyJsonFromAsset()");
+                Toast.makeText(this,"Can't Copy DB file from asset, please retry start SampleApp.",
+                    Toast.LENGTH_LONG).show();
+                return;
+            }
+            SharedPreferences.Editor editor = wmbPreference.edit();
+            editor.putBoolean("FIRSTRUN", false);
+            editor.commit();
+        }
+
+        cfg = new PlatformConfig(
+                this,
+                ServiceType.IN_PROC,
+                ModeType.CLIENT_SERVER,
+                "0.0.0.0", // bind to all available interfaces
+                0,
+                QualityOfService.LOW, filePath + OIC_CLIENT_JSON_DB_FILE);
+        try {
+            /*
+             * Initialize DataBase
+             */
+
+            OcPlatform.Configure(cfg);
+
+            String sqlDbPath = getFilesDir().getAbsolutePath().replace("files", "databases") +
+                    File.separator;
+            File file = new File(sqlDbPath);
+            //check files directory exists
+            if (!(file.isDirectory())) {
+                file.mkdirs();
+                Log.d(TAG, "Sql db directory created at " + sqlDbPath);
+            }
+            Log.d(TAG, "Sql db directory exists at " + sqlDbPath);
+
+            //SQLiteDatabase.openOrCreateDatabase(sqlDbPath+ OIC_SQL_DB_FILE, null);
+            OcProvisioning.provisionInit(sqlDbPath + OIC_SQL_DB_FILE);
+            mSecurityMode.setChecked(true);
+        } catch (OcException e) {
+            logMessage(TAG + "provisionInit error: " + e.getMessage());
+            Log.e(TAG, e.getMessage());
+            Toast.makeText(this,"provisionInit error: " + e.getMessage(),
+                    Toast.LENGTH_LONG).show();
+            mSecurityMode.setChecked(false);
+            return;
+        } catch (UnsatisfiedLinkError e) {
+
+            // Note : Easy setup is built with SECURED = 0, but user still selects Security feature
+            // while running the Mediator App it couldn't find "libocprovision.so".
+            // As per the programmer guide, security feature should be invoked only if build is done with SECURED = 1.
+            mSecurityMode.setChecked(false);
+            Log.e(TAG, " Easy setup is built with secured  = 0, but executed with security feature");
+            Toast.makeText(this,"Security is not enabled [Easy setup is built with SECURED = 0]",
+                    Toast.LENGTH_LONG).show();
+            return;
+        }
+    }
+
+    OcPlatform.OnResourceFoundListener listener =
+            new OcPlatform.OnResourceFoundListener() {
+                @Override
+                public void onFindResourceFailed(Throwable throwable, String s) {
+                    Log.e(TAG, "Failed found resource, ecode: " + s);
+                }
+                @Override
+                public void onResourceFound(OcResource ocResource) {
+                    synchronized (mActivity) {
+                        if(isFirstTime){
+                            if (null == ocResource) {
+                                Log.e(TAG, "Found resource is invalid");
+                                return;
+                            }
+
+                            if(ocResource.getHost().contains("coap+tcp")) {
+                                Log.d(TAG, "Recv Found resource event  from tcp port," +
+                                    "ignoring URI : " + ocResource.getUri());
+                                runOnUiThread(new Runnable() {
+                                    @Override
+                                    public void run() {
+                                        mDiscoverResource.setEnabled(true);
+                                    }
+                                });
+                                return;
+                            }
+
+                            // Get the resource URI
+                            String resourceUri = ocResource.getUri();
+                            // Get the resource host address
+                            String hostAddress = ocResource.getHost();
+                            Log.d(TAG,"URI of the resource: " + resourceUri);
+                            Log.d(TAG,"Host address of the resource: " + hostAddress);
+
+                            runOnUiThread(new Runnable() {
+                                @Override
+                                public void run() {
+                                    mDiscoverResource.setText("Found");
+                                    if(mSecurityMode.isChecked()) {
+                                    mConfigureSecProcess.setEnabled(true);
+                                    }
+                                    mGetConfigurationProcess.setEnabled(true);
+                                    mProvisionDevPropProcess.setEnabled(true);
+                                    mProvisionCloudPropProcess.setEnabled(true);
+                                }
+                            });
+                            isFirstTime = false;
+                            mRemoteEnrollee = mEasySetup.createRemoteEnrollee(ocResource);
+                            mEnrolleeDeviceID = ocResource.getServerId();
+                        }
+                    }
+                }
+            };
+
+    private void addListenerForDiscoverEnrollee() {
+        mDiscoverResource.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Thread thread = new Thread() {
+                    boolean result = true;
+                    @Override
+                    public void run() {
+                        runOnUiThread(new Runnable() {
+                            @Override
+                            public void run() {
+                                mDiscoverResource.setEnabled(false);
+                            }
+                        });
+
+                        try {
+                            String requestUri = OcPlatform.WELL_KNOWN_QUERY + "?rt=" + ESConstants.OC_RSRVD_ES_RES_TYPE_EASYSETUP;
+                            OcPlatform.findResource("",
+                                    requestUri,
+                                    EnumSet.of(OcConnectivityType.CT_DEFAULT),
+                                    listener
+                            );
+                        }
+                        catch (OcException e) {
+                            e.printStackTrace();
+                            result = false;
+                            runOnUiThread(new Runnable() {
+                                @Override
+                                public void run() {
+                                    mDiscoverResource.setEnabled(true);
+                                }
+                            });
+                        }
+                    }
+                };
+
+                thread.start();
+            }
+        });
+    }
+
+    private void addListenerForStartConfigureSec() {
+        mStartConfigureSec.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Thread thread = new Thread() {
+                    @Override
+                    public void run() {
+                        runOnUiThread(new Runnable() {
+                            @Override
+                            public void run() {
+                                mStartConfigureSec.setEnabled(false);
+                            }
+                        });
+
+                        try {
+                            mRemoteEnrollee.provisionSecurity(new SecurityProvisioningCallback() {
+                                @Override
+                                public void onProgress(final SecurityProvisioningStatus securityProvisioningStatus) {
+                                    if(securityProvisioningStatus.getESResult() == ESResult.ES_OK) {
+                                        runOnUiThread(new Runnable() {
+                                            @Override
+                                            public void run() {
+                                                mSecStateText.setText("Success");
+                                                mSecDevIDText.setText(securityProvisioningStatus.getDevUUID());
+                                            }
+                                        });
+                                    }
+                                    else if(securityProvisioningStatus.getESResult()
+                                            == ESResult.ES_SECURE_RESOURCE_DISCOVERY_FAILURE) {
+                                        runOnUiThread(new Runnable() {
+                                            @Override
+                                            public void run() {
+                                                mSecStateText.setText("Not found Secure Resource");
+                                                mStartConfigureSec.setEnabled(true);
+                                            }
+                                        });
+                                    }
+                                    else if(securityProvisioningStatus.getESResult()
+                                            == ESResult.ES_OWNERSHIP_TRANSFER_FAILURE) {
+                                        runOnUiThread(new Runnable() {
+                                            @Override
+                                            public void run() {
+                                                mSecStateText.setText("Ownership transfer failed");
+                                                mStartConfigureSec.setEnabled(true);
+                                            }
+                                        });
+                                    }
+                                    else {
+                                        runOnUiThread(new Runnable() {
+                                            @Override
+                                            public void run() {
+                                                mSecStateText.setText("Failed");
+                                                mStartConfigureSec.setEnabled(true);
+                                            }
+                                        });
+                                    }
+                                }
+                            });
+                        } catch (ESException e) {
+                            e.printStackTrace();
+                            runOnUiThread(new Runnable() {
+                                @Override
+                                public void run() {
+                                    mStartConfigureSec.setEnabled(true);
+                                }
+                            });
+                        }
+                    }
+                };
+
+                thread.start();
+            }
+        });
+    }
+
+    private void addListenerForStartGetConfiguration(){
+        mStartGetConfiguration.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Thread thread = new Thread() {
+                    @Override
+                    public void run() {
+                        runOnUiThread(new Runnable() {
+                            @Override
+                            public void run() {
+                                mGetconfigurationStateText.setText("Process");
+                                mStartGetConfiguration.setEnabled(false);
+                            }
+                        });
+
+                        try {
+                            mRemoteEnrollee.getConfiguration(new GetConfigurationCallback() {
+                                @Override
+                                public void onProgress(GetConfigurationStatus getConfigurationStatus) {
+                                    if(getConfigurationStatus.getESResult() == ESResult.ES_OK) {
+
+                                        final SCEnrolleeConf scEnrolleeConf =
+                                        new SCEnrolleeConf(getConfigurationStatus.getEnrolleeConf());
+
+                                        runOnUiThread(new Runnable() {
+                                            @Override
+                                            public void run() {
+                                                mGetconfigurationStateText.setText("Success");
+                                                mDevNameText.setText(scEnrolleeConf.getDeviceName());
+                                                mModelNumberText.setText(scEnrolleeConf.getModelNumber());
+                                                mDevTypeText.setText(scEnrolleeConf.getDeviceType());
+                                                mDevSubTypeText.setText(scEnrolleeConf.getDeviceSubType());
+                                                setWifiModes(scEnrolleeConf.getWiFiModes());
+                                                setWifiFreq(scEnrolleeConf.getWiFiFreq());
+
+                                                if(scEnrolleeConf.isCloudAccessible()) {
+                                                    mCloudAccessableText.setText("TRUE");
+                                                }
+                                                else {
+                                                    mCloudAccessableText.setText("FALSE");
+                                                }
+                                            }
+                                        });
+                                    }
+                                    else if(getConfigurationStatus.getESResult() == ESResult.ES_COMMUNICATION_ERROR)
+                                    {
+                                        runOnUiThread(new Runnable() {
+                                            @Override
+                                            public void run() {
+                                                mGetconfigurationStateText.setText("Communication Error");
+                                                mStartGetConfiguration.setEnabled(true);
+                                            }
+                                        });
+                                    }
+                                    else {
+                                        runOnUiThread(new Runnable() {
+                                            @Override
+                                            public void run() {
+                                                mGetconfigurationStateText.setText("Failed");
+                                                mStartGetConfiguration.setEnabled(true);
+                                            }
+                                        });
+                                    }
+                                }
+                            });
+                        } catch (ESException e) {
+                            e.printStackTrace();
+                            runOnUiThread(new Runnable() {
+                                @Override
+                                public void run() {
+                                    mGetconfigurationStateText.setText("Failed");
+                                    mStartGetConfiguration.setEnabled(true);
+                                }
+                            });
+                        }
+                    }
+                };
+
+                thread.start();
+            }
+        });
+    }
+
+    private void addListenerForStartProvisionDevProp() {
+        mStartProvisionDevProp.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Thread thread = new Thread() {
+                    @Override
+                    public void run() {
+                        try {
+                            runOnUiThread(new Runnable() {
+                                @Override
+                                public void run() {
+                                    mProvisionDevPropState.setText("Progress");
+                                    mStartProvisionDevProp.setEnabled(false);
+                                }
+                            });
+
+                            String enrollerSSID = mEnrollerSsidText.getText().toString();
+                            String enrollerPW = mEnrollerPWText.getText().toString();
+                            String discoveryChannel = mDiscoveryChannelText.getText().toString();
+                            String addr = mAddrText.getText().toString();
+                            String zipcode = mZipCodeText.getText().toString();
+                            String building = mBuildingText.getText().toString();
+                            WIFI_AUTHTYPE authType =
+                                    WIFI_AUTHTYPE.fromInt(mAuthType.getSelectedItemPosition());
+                            WIFI_ENCTYPE encType =
+                                    WIFI_ENCTYPE.fromInt(mEncType.getSelectedItemPosition());
+                            String inputLanguage = mInputLanguageText.getText().toString();
+                            String inputCountry = mInputCountryText.getText().toString();
+                            String inputLocation = mInputLocationText.getText().toString();
+
+                            ArrayList<String> locations = new ArrayList<String>();
+                            locations.add(addr);
+                            locations.add(zipcode);
+                            locations.add(building);
+
+                            SCDeviceProp scDevProp = new SCDeviceProp();
+                            scDevProp.setWiFiProp(enrollerSSID, enrollerPW, authType, encType);
+                            scDevProp.setDevConfProp(inputLanguage, inputCountry, inputLocation);
+                            scDevProp.setDiscoveryChannel(Integer.parseInt(discoveryChannel));
+                            scDevProp.setSCLocation(locations);
+
+                            mRemoteEnrollee.provisionDeviceProperties(scDevProp, new DevicePropProvisioningCallback() {
+                                @Override
+                                public void onProgress(DevicePropProvisioningStatus devPropProvisioningStatus) {
+                                    final ESResult result = devPropProvisioningStatus.getESResult();
+                                    runOnUiThread(new Runnable() {
+                                        @Override
+                                        public void run() {
+                                            if(result.equals(ESResult.ES_OK)) {
+                                                mProvisionDevPropState.setText("Success");
+                                            }
+                                            else if(result.equals(ESResult.ES_ERROR)) {
+                                                mProvisionDevPropState.setText("Failed");
+                                            }
+                                            else if(result.equals(ESResult.ES_COMMUNICATION_ERROR)) {
+                                                mProvisionDevPropState.setText("Communication Error");
+                                            }
+                                            mStartProvisionDevProp.setEnabled(true);
+                                        }
+                                    });
+                                }
+                            });
+                        } catch (ESException e) {
+                            e.printStackTrace();
+                            runOnUiThread(new Runnable() {
+                                @Override
+                                public void run() {
+                                    mProvisionDevPropState.setText("Failed");
+                                    mStartProvisionDevProp.setEnabled(true);
+                                }
+                            });
+                        }
+                    }
+                };
+
+                thread.start();
+            }
+        });
+    }
+
+    private void addListenerForStartProvisionCloudProp() {
+        mStartProvisionCloudProp.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                Thread thread = new Thread() {
+                    @Override
+                    public void run() {
+                        runOnUiThread(new Runnable() {
+                            @Override
+                            public void run() {
+                                mProvisionCloudPropState.setText("Progress");
+                                mStartProvisionCloudProp.setEnabled(false);
+                            }
+                        });
+
+                        try {
+                            String authCode = mAuthCodeText.getText().toString();
+                            String authProvider = mAuthProviderText.getText().toString();
+                            String ciserver = samsungCIServer;
+
+                            CloudProp cloudProp = new CloudProp();
+                            cloudProp.setCloudProp(authCode, authProvider, ciserver);
+                            cloudProp.setCloudID("f002ae8b-c42c-40d3-8b8d-1927c17bd1b3");
+                            cloudProp.setCredID(1);
+
+                            mRemoteEnrollee.provisionCloudProperties(cloudProp, new CloudPropProvisioningCallback() {
+                                @Override
+                                public void onProgress(CloudPropProvisioningStatus cloudProvisioningStatus) {
+                                    final ESResult result = cloudProvisioningStatus.getESResult();
+                                    runOnUiThread(new Runnable() {
+                                        @Override
+                                        public void run() {
+                                            if(result.equals(ESResult.ES_ENROLLEE_DISCOVERY_FAILURE)) {
+                                                mProvisionCloudPropState.setText("Not Found Resource");
+                                            }
+                                            else if(result.equals(ESResult.ES_OK)) {
+                                                mProvisionCloudPropState.setText("Cloud Provisioning succeeds");
+                                            }
+                                            else if(result.equals(ESResult.ES_ACL_PROVISIONING_FAILURE)){
+                                                mProvisionCloudPropState.setText("ACL-provisioning fails");
+                                            }
+                                            else if(result.equals(ESResult.ES_CERT_PROVISIONING_FAILURE)){
+                                                mProvisionCloudPropState.setText("CERT-provisioning fails");
+                                            }
+                                            else if(result.equals(ESResult.ES_COMMUNICATION_ERROR)){
+                                                mProvisionCloudPropState.setText("Communication Error");
+                                            }
+                                            else {
+                                                mProvisionCloudPropState.setText("Cloud Provisioning fails");
+                                            }
+                                        }
+                                    });
+                                }
+                            });
+                        } catch (ESException e) {
+                            e.printStackTrace();
+                            runOnUiThread(new Runnable() {
+                                @Override
+                                public void run() {
+                                    mProvisionCloudPropState.setText("Failed");
+                                    mStartProvisionCloudProp.setEnabled(true);
+                                }
+                            });
+                        }
+                    }
+                };
+
+                thread.start();
+            }
+        });
+    }
+
+    private boolean copyJsonFromAsset() {
+        InputStream inputStream = null;
+        OutputStream outputStream = null;
+        int length;
+        byte[] buffer = new byte[BUFFER_SIZE];
+        try {
+            inputStream = getAssets().open(OIC_CLIENT_JSON_DB_FILE);
+            File file = new File(filePath);
+            //check files directory exists
+            if (!(file.exists() && file.isDirectory())) {
+                file.mkdirs();
+            }
+            outputStream = new FileOutputStream(filePath + OIC_CLIENT_JSON_DB_FILE);
+            while ((length = inputStream.read(buffer)) != -1) {
+                outputStream.write(buffer, 0, length);
+            }
+        } catch (NullPointerException e) {
+            logMessage(TAG + "Null pointer exception " + e.getMessage());
+            Log.e(TAG, e.getMessage());
+            return false;
+        } catch (FileNotFoundException e) {
+            logMessage(TAG + "Json svr db file not found " + e.getMessage());
+            Log.e(TAG, e.getMessage());
+            return false;
+        } catch (IOException e) {
+            logMessage(TAG + OIC_CLIENT_JSON_DB_FILE + " file copy failed");
+            Log.e(TAG, e.getMessage());
+            return false;
+        } finally {
+            if (inputStream != null) {
+                try {
+                    inputStream.close();
+                } catch (IOException e) {
+                    Log.e(TAG, e.getMessage());
+                    return false;
+                }
+            }
+            if (outputStream != null) {
+                try {
+                    outputStream.close();
+                } catch (IOException e) {
+                    Log.e(TAG, e.getMessage());
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    public void logMessage(String text) {
+
+    }
+
+    public void setWifiModes(ArrayList<WIFI_MODE> types) {
+        String temp = "WIFI - ";
+
+        for(WIFI_MODE type : types) {
+            if(type.equals(WIFI_MODE.WIFI_11A)) {
+                temp = temp + "11A ";
+            }
+            else if(type.equals(WIFI_MODE.WIFI_11B)) {
+                temp = temp + "11B ";
+            }
+            else if(type.equals(WIFI_MODE.WIFI_11G)) {
+                temp = temp + "11G ";
+            }
+            else if(type.equals(WIFI_MODE.WIFI_11N)) {
+                temp = temp + "11N ";
+            }
+            else if(type.equals(WIFI_MODE.WIFI_11AC)) {
+                temp = temp + "11AC ";
+            }
+        }
+        final String modeTypes = temp;
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mWifiModeText.setText(modeTypes);
+            }
+        });
+    }
+
+    public void setWifiFreq(final WIFI_FREQ freq) {
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                if(freq.equals(WIFI_FREQ.WIFI_24G)) {
+                    mWifiFreqText.setText("2.4G");
+                }
+                else if(freq.equals(WIFI_FREQ.WIFI_5G)) {
+                    mWifiFreqText.setText("5G");
+                }
+                else if(freq.equals(WIFI_FREQ.WIFI_BOTH)) {
+                    mWifiFreqText.setText("2.4G & 5G");
+                }
+            }
+        });
+    }
+
+    @Override
+    public void onPresence(OcPresenceStatus status, int sequence, String host) {
+        final String strStaus = status.getValue();
+        Log.d(TAG, "Presence response: " + strStaus + " sequence: " + sequence + " host: " + host);
+        runOnUiThread(new Runnable()
+        {
+            public void run() {
+                Toast.makeText(EasysetupActivity.this, "Easy-Setup completed", Toast.LENGTH_SHORT).show();
+            }
+        });
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+        if(resultCode==RESULT_OK && requestCode==1){
+            mAuthCode = data.getStringExtra("authCode");
+            mAuthProvider = data.getStringExtra("authProvider");
+            String text = "Received authCode= " + mAuthCode;
+            Log.d(TAG, text);
+            SignUpDevice();
+        }
+        else if(resultCode==RESULT_OK && requestCode==2)
+        {
+            mEnrolleeAuthCode = data.getStringExtra("authCode");
+            mAuthCodeText.setText(mEnrolleeAuthCode);
+            mAuthProviderText.setText("samsung");
+            mAuthCodeText.setEnabled(false);
+            mAuthProviderText.setEnabled(false);
+            subscribeDevicePresence();
+        }
+    }
+
+    OcResource.OnPostListener onRefreshTokenPost = new OcResource.OnPostListener() {
+        @Override
+        public void onPostCompleted(List<OcHeaderOption> list, OcRepresentation ocRepresentation) {
+            Log.d(TAG, "onRefreshTokenPost..");
+            try {
+                mAccessToken = ocRepresentation.getValue("accesstoken");
+                mRefreshtoken = ocRepresentation.getValue("refreshtoken");
+
+                saveCloudTokenAtSharedPreferences();
+            }
+            catch (OcException e)
+            {
+                e.printStackTrace();
+            }
+
+            SignInDevice();
+        }
+
+        @Override
+        public void onPostFailed(Throwable throwable) {
+            Log.d(TAG, "onRefreshTokenPost failed..");
+        }
+    };
+
+    public void RefreshToken() {
+        try {
+            OcResource authResource = OcPlatform.constructResourceObject(samsungCIServer, "/.well-known/ocf/account/tokenrefresh",
+                    EnumSet.of(OcConnectivityType.CT_ADAPTER_TCP, OcConnectivityType.CT_IP_USE_V4),
+                    false, Arrays.asList("oic.wk.account"), Arrays.asList(OcPlatform.DEFAULT_INTERFACE));
+            OcRepresentation rep = new OcRepresentation();
+
+            runOnUiThread(new Runnable()
+            {
+                public void run() {
+                    Toast.makeText(EasysetupActivity.this, "RefreshToken in progress..", Toast.LENGTH_SHORT).show();
+                }
+            });
+
+            rep.setValue("di", deviceID);
+            rep.setValue("granttype", "refresh_token");
+            rep.setValue("refreshtoken", mRefreshtoken);
+            rep.setValue("uid", mUserID);
+            authResource.post(rep, new HashMap<String, String>(), onRefreshTokenPost);
+        }
+        catch(OcException e)
+        {
+            e.printStackTrace();
+        }
+
+        Log.d(TAG, "No error while executing login");
+    }
+
+    private void saveCloudTokenAtSharedPreferences() {
+        Log.d(TAG, "accesstoken: " + mAccessToken);
+        SharedPreferences settings = getApplicationContext().getSharedPreferences("IoTivityCloud", 0);
+        SharedPreferences.Editor editor = settings.edit();
+        editor.putString("accesstoken", mAccessToken);
+        editor.putString("refreshtoken", mRefreshtoken);
+        editor.putString("uid", mUserID);
+
+        if(editor.commit() == true)
+            Log.d(TAG, "accesstoken saved");
+        else
+            Log.d(TAG, "accesstoken not saved");
+    }
+
+    OcAccountManager.OnPostListener onSignUpPost = new OcAccountManager.OnPostListener() {
+        @Override
+        public void onPostCompleted(List<OcHeaderOption> list, OcRepresentation ocRepresentation) {
+            Log.d(TAG, "onSignUpPost..");
+            try {
+                runOnUiThread(new Runnable()
+                {
+                    public void run() {
+                        Toast.makeText(EasysetupActivity.this, "Sign-up completed", Toast.LENGTH_SHORT).show();
+                    }
+                });
+
+                mAccessToken = ocRepresentation.getValue("accesstoken");
+                mRefreshtoken = ocRepresentation.getValue("refreshtoken");
+                mUserID = ocRepresentation.getValue("uid");
+
+                if(mAccessToken != null)
+                {
+                    saveCloudTokenAtSharedPreferences();
+                    SignInDevice();
+                }
+            }
+            catch (OcException e)
+            {
+                e.printStackTrace();
+            }
+        }
+
+        @Override
+        public void onPostFailed(Throwable throwable) {
+            Log.d(TAG, "onSignUpPost failed.. : " + throwable.getMessage());
+        }
+    };
+
+    private void SignUpDevice() {
+        try {
+            Log.d(TAG, "SignUpDevice..");
+
+            runOnUiThread(new Runnable()
+            {
+                public void run() {
+                    Toast.makeText(EasysetupActivity.this, "SignUpDevice in progress..", Toast.LENGTH_SHORT).show();
+                }
+            });
+
+            if(m_accountManager != null) {
+                m_accountManager.signUp(mAuthProvider, mAuthCode, onSignUpPost);
+            }
+        }
+        catch(OcException e)
+        {
+            e.printStackTrace();
+        }
+
+        Log.d(TAG, "No error while executing SignUp");
+    }
+
+    OcAccountManager.OnPostListener onSignInPost = new OcAccountManager.OnPostListener() {
+        @Override
+        public void onPostCompleted(List<OcHeaderOption> list, OcRepresentation ocRepresentation) {
+            Log.d(TAG, "onSignInPost..");
+
+            runOnUiThread(new Runnable()
+            {
+                public void run() {
+                    Toast.makeText(EasysetupActivity.this, "Sign-in completed", Toast.LENGTH_SHORT).show();
+                }
+            });
+        }
+
+        @Override
+        public void onPostFailed(Throwable ex) {
+            if (ex instanceof OcException) {
+                OcException ocEx = (OcException) ex;
+                ErrorCode errCode = ocEx.getErrorCode();
+                Log.e(TAG, ocEx.getMessage());
+                if (ErrorCode.UNAUTHORIZED_REQ != errCode) {
+                    RefreshToken();
+                }
+            }
+        }
+    };
+
+    private void SignInDevice() {
+        try {
+            Log.d(TAG, "SignInDevice..");
+
+            runOnUiThread(new Runnable()
+            {
+                public void run() {
+                    Toast.makeText(EasysetupActivity.this, "SignInDevice in progress..", Toast.LENGTH_SHORT).show();
+                }
+            });
+            if(m_accountManager != null) {
+                m_accountManager.signIn(mUserID, mAccessToken, onSignInPost);
+            }
+        }
+        catch(OcException e)
+        {
+            e.printStackTrace();
+        }
+
+        Log.d(TAG, "No error while executing login");
+    }
+
+    @Override
+    public void onObserveCompleted(List<OcHeaderOption> list, OcRepresentation ocRepresentation, int i) {
+        Log.d(TAG,"onObserveCompleted");
+    }
+
+    @Override
+    public void onObserveFailed(Throwable throwable) {
+        Log.d(TAG,"onObserveFailed");
+    }
+
+    public void subscribeDevicePresence()
+    {
+        List<String> deviceIDs = new ArrayList<String>();
+        deviceIDs.add(mEnrolleeDeviceID);
+
+        try {
+
+            OcPlatform.subscribeDevicePresence(samsungCIServer, deviceIDs, EnumSet.of(OcConnectivityType.
+                                               CT_ADAPTER_TCP), this);
+        } catch(OcException e)
+        {
+            e.printStackTrace();
+        }
+
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+    }
+}
diff --git a/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/java/org/iotivity/service/easysetup/LoginActivity.java b/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/java/org/iotivity/service/easysetup/LoginActivity.java
new file mode 100644 (file)
index 0000000..40e30c7
--- /dev/null
@@ -0,0 +1,125 @@
+/**
+ * ***************************************************************
+ * <p/>
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ * <p/>
+ * <p/>
+ * <p/>
+ * 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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.
+ * <p/>
+ * ****************************************************************
+ */
+
+package org.iotivity.service.easysetup;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.UrlQuerySanitizer;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.preference.PreferenceManager;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.ProgressBar;
+import android.widget.RadioButton;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import org.iotivity.base.ModeType;
+import org.iotivity.base.OcException;
+import org.iotivity.base.OcPlatform;
+import org.iotivity.base.OcProvisioning;
+import org.iotivity.base.PlatformConfig;
+import org.iotivity.base.QualityOfService;
+import org.iotivity.base.ServiceType;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+
+public class LoginActivity extends Activity {
+    private static final String TAG = "Easysetup Login: ";
+
+    /* Samsung account */
+    private WebView mWebView = null;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_login);
+
+        /* For Samsung account authentifaction */
+        mWebView = (WebView) findViewById(R.id.webView);
+        mWebView.setVisibility(View.VISIBLE);
+        mWebView.setInitialScale(200);
+        mWebView.getSettings().setJavaScriptEnabled(true);
+        //mWebView.getSettings().setSupportZoom(true);
+        mWebView.getSettings().setBuiltInZoomControls(true);
+        mWebView.setWebViewClient(new WebViewClientClass());
+
+        mWebView.loadUrl("https://account.samsung.com/account/check.do?actionID=StartAP&serviceID=85o501t021&countryCode=KR&languageCode=ko&serviceChannel=PC_APP");
+
+    }
+
+    public void onDestroy() {
+        super.onDestroy();
+    }
+
+    private class WebViewClientClass extends WebViewClient {
+
+        @Override
+        public void onPageFinished(WebView view, String url) {
+            Log.e(TAG, "called!!! url=" + url);
+
+            if(url.contains("https://account.samsung.com/account/hybridCommonClosed.do")){
+
+                mWebView.setVisibility(View.INVISIBLE);
+
+                //parsing url
+                UrlQuerySanitizer sanitizer = new UrlQuerySanitizer();
+                sanitizer.setAllowUnregisteredParamaters(true);
+                sanitizer.parseUrl(url);
+
+                String mAuthCode = null;
+                mAuthCode = sanitizer.getValue("code");
+
+                Intent intent = getIntent();
+                intent.putExtra("authCode", mAuthCode);
+                intent.putExtra("authProvider", "samsung");
+
+                setResult(RESULT_OK, intent);
+
+                finish();
+            }
+        }
+    }
+}
diff --git a/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/drawable-hdpi/background.png b/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/drawable-hdpi/background.png
new file mode 100644 (file)
index 0000000..561cce8
Binary files /dev/null and b/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/drawable-hdpi/background.png differ
diff --git a/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/drawable-hdpi/cancel.png b/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/drawable-hdpi/cancel.png
new file mode 100644 (file)
index 0000000..da342e5
Binary files /dev/null and b/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/drawable-hdpi/cancel.png differ
diff --git a/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/drawable-hdpi/ic_launcher.png b/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..288b665
Binary files /dev/null and b/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/drawable-hdpi/ic_launcher.png differ
diff --git a/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/drawable-hdpi/icon.png b/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/drawable-hdpi/icon.png
new file mode 100644 (file)
index 0000000..24a8af2
Binary files /dev/null and b/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/drawable-hdpi/icon.png differ
diff --git a/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/layout/activity_login.xml b/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/layout/activity_login.xml
new file mode 100644 (file)
index 0000000..96a7df3
--- /dev/null
@@ -0,0 +1,15 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:id="@+id/loginlayout"
+    tools:context="org.iotivity.service.easysetup.mediator.LoginActivity">
+
+    <WebView
+        android:id="@+id/webView"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="visible" />
+
+</LinearLayout>
diff --git a/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/layout/easysetup_main.xml b/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/layout/easysetup_main.xml
new file mode 100755 (executable)
index 0000000..aa68586
--- /dev/null
@@ -0,0 +1,882 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"\r
+    android:orientation="vertical" android:layout_width="match_parent"\r
+    android:layout_height="match_parent"\r
+    android:baselineAligned="true"\r
+    android:weightSum="1"\r
+    android:nestedScrollingEnabled="false">\r
+\r
+    <LinearLayout\r
+        android:orientation="horizontal"\r
+        android:layout_width="match_parent"\r
+        android:layout_height="wrap_content">\r
+\r
+        <Button\r
+            android:layout_width="wrap_content"\r
+            android:layout_height="wrap_content"\r
+            android:text="Discovery"\r
+            android:id="@+id/btn_discoverResource"\r
+            android:layout_marginLeft="20dp"\r
+            android:layout_marginTop="10dp" />\r
+\r
+        <LinearLayout\r
+            android:orientation="horizontal"\r
+            android:layout_width="match_parent"\r
+            android:layout_height="match_parent"\r
+            android:weightSum="1"\r
+            android:baselineAligned="true"\r
+            android:layout_marginLeft="20dp"\r
+            android:id="@+id/layout_Security"\r
+            android:layout_marginRight="20dp">\r
+\r
+            <TextView\r
+                android:layout_width="wrap_content"\r
+                android:layout_height="wrap_content"\r
+                android:text="@string/security_mode"\r
+                android:id="@+id/text_EnableSecurity"\r
+                android:phoneNumber="false"\r
+                android:textSize="16sp"\r
+                android:layout_marginTop="10dp"\r
+                android:layout_marginLeft="20dp" />\r
+\r
+            <ToggleButton\r
+                android:layout_width="wrap_content"\r
+                android:layout_height="wrap_content"\r
+                android:id="@+id/btn_Security"\r
+                android:layout_marginLeft="40dp"\r
+                android:layout_weight="0"\r
+                android:textOff="Disable"\r
+                android:textOn="Enable"\r
+                android:layout_marginTop="10dp" />\r
+\r
+        </LinearLayout>\r
+\r
+    </LinearLayout>\r
+\r
+    <View\r
+        android:layout_height="2dip"\r
+        android:background="#FF909090"\r
+        android:layout_marginTop="10dp"\r
+        android:layout_marginBottom="10dp"\r
+        android:layout_marginLeft="15dp"\r
+        android:layout_marginRight="15dp"\r
+        android:layout_width="match_parent" />\r
+\r
+    <LinearLayout\r
+        android:orientation="vertical"\r
+        android:layout_width="match_parent"\r
+        android:layout_height="wrap_content"\r
+        android:id="@+id/layout_Excution"\r
+        android:layout_marginLeft="10dp"\r
+        android:layout_marginRight="10dp">\r
+\r
+        <TextView\r
+            android:layout_width="wrap_content"\r
+            android:layout_height="wrap_content"\r
+            android:text="@string/easysetup_sequence"\r
+            android:id="@+id/textView22"\r
+            android:layout_marginLeft="10dp"\r
+            android:textSize="16sp" />\r
+\r
+        <RadioGroup\r
+            android:layout_width="match_parent"\r
+            android:layout_height="match_parent"\r
+            android:layout_marginTop="5dp"\r
+            android:id="@+id/rg_EasysetupProcess"\r
+            android:layout_marginLeft="20dp">\r
+\r
+            <RadioButton\r
+                android:layout_width="160dp"\r
+                android:layout_height="32dp"\r
+                android:text="@string/securityprovisioning"\r
+                android:id="@+id/btn_configurSec"\r
+                android:checked="false"\r
+                android:textSize="12sp" />\r
+\r
+            <RadioButton\r
+            android:layout_width="160dp"\r
+            android:layout_height="32dp"\r
+            android:text="GetConfiguration"\r
+            android:id="@+id/btn_getConfiguration"\r
+            android:checked="false"\r
+            android:textSize="12sp" />\r
+\r
+            <RadioButton\r
+                android:layout_width="173dp"\r
+                android:layout_height="32dp"\r
+                android:text="ProvisionDeviceConfig"\r
+                android:id="@+id/btn_provisionDevConf"\r
+                android:textSize="12sp" />\r
+\r
+            <RadioButton\r
+                android:layout_width="160dp"\r
+                android:layout_height="32dp"\r
+                android:text="@string/cloudprovisioning"\r
+                android:id="@+id/btn_provisionCloudConf"\r
+                android:textSize="12sp" />\r
+        </RadioGroup>\r
+\r
+    </LinearLayout>\r
+\r
+    <View\r
+        android:layout_height="2dip"\r
+        android:background="#FF909090"\r
+        android:layout_marginTop="10dp"\r
+        android:layout_marginBottom="10dp"\r
+        android:layout_marginLeft="15dp"\r
+        android:layout_marginRight="15dp"\r
+        android:layout_width="match_parent" />\r
+\r
+    <ScrollView\r
+        android:layout_width="fill_parent"\r
+        android:layout_height="fill_parent"\r
+        android:id="@+id/scrollView" >\r
+\r
+        <LinearLayout\r
+            android:orientation="vertical"\r
+            android:layout_width="match_parent"\r
+            android:layout_height="match_parent"\r
+            android:id="@+id/layout_Infomation"\r
+            android:gravity="center_horizontal"\r
+            android:weightSum="1">\r
+\r
+            <LinearLayout\r
+                android:orientation="vertical"\r
+                android:layout_width="match_parent"\r
+                android:layout_height="match_parent"\r
+                android:layout_marginLeft="20dp"\r
+                android:layout_marginRight="20dp"\r
+                android:id="@+id/layout_ConfigurSec"\r
+                android:layout_marginTop="10dp"\r
+                android:weightSum="1"\r
+                android:visibility="gone">\r
+\r
+                <TextView\r
+                    android:layout_width="wrap_content"\r
+                    android:layout_height="wrap_content"\r
+                    android:textAppearance="?android:attr/textAppearanceSmall"\r
+                    android:text="@string/security_provisioning_state"\r
+                    android:id="@+id/textView10" />\r
+\r
+                <LinearLayout\r
+                    android:orientation="horizontal"\r
+                    android:layout_width="match_parent"\r
+                    android:layout_height="wrap_content"\r
+                    android:id="@+id/layout_secState"\r
+                    android:weightSum="1"\r
+                    android:layout_marginLeft="10dp"\r
+                    android:layout_marginTop="10dp" >\r
+\r
+                    <TextView\r
+                        android:layout_width="80dp"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="State"\r
+                        android:id="@+id/textView12"\r
+                        android:layout_gravity="center_vertical" />\r
+\r
+                    <TextView\r
+                        android:layout_width="wrap_content"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="empty"\r
+                        android:id="@+id/txt_secState" />\r
+\r
+                </LinearLayout>\r
+\r
+                <LinearLayout\r
+                    android:orientation="horizontal"\r
+                    android:layout_width="match_parent"\r
+                    android:layout_height="wrap_content"\r
+                    android:id="@+id/linearLayout2"\r
+                    android:weightSum="1"\r
+                    android:layout_marginLeft="10dp"\r
+                    android:layout_marginTop="10dp" >\r
+\r
+                    <TextView\r
+                        android:layout_width="80dp"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="Device ID"\r
+                        android:id="@+id/textView"\r
+                        android:layout_gravity="center_vertical" />\r
+\r
+                    <TextView\r
+                        android:layout_width="wrap_content"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="empty"\r
+                        android:id="@+id/txt_secDevID" />\r
+                </LinearLayout>\r
+\r
+                <FrameLayout\r
+                    android:layout_width="match_parent"\r
+                    android:layout_height="82dp"\r
+                    android:layout_weight="0.64"></FrameLayout>\r
+\r
+                <Button\r
+                    android:layout_width="90dp"\r
+                    android:layout_height="wrap_content"\r
+                    android:text="START"\r
+                    android:id="@+id/btn_startConfigureSec"\r
+                    android:layout_marginTop="10dp"\r
+                    android:layout_gravity="bottom|right" />\r
+\r
+            </LinearLayout>\r
+\r
+            <LinearLayout\r
+                android:orientation="vertical"\r
+                android:layout_width="match_parent"\r
+                android:layout_height="match_parent"\r
+                android:layout_marginLeft="20dp"\r
+                android:layout_marginRight="20dp"\r
+                android:id="@+id/layout_GetConfiguration"\r
+                android:layout_marginTop="10dp"\r
+                android:visibility="gone">\r
+\r
+                <LinearLayout\r
+                    android:orientation="horizontal"\r
+                    android:layout_width="match_parent"\r
+                    android:layout_height="wrap_content">\r
+\r
+                    <TextView\r
+                        android:layout_width="wrap_content"\r
+                        android:layout_height="wrap_content"\r
+                        android:textAppearance="?android:attr/textAppearanceSmall"\r
+                        android:text="@string/enrollee_property_data"\r
+                        android:id="@+id/textView4" />\r
+\r
+                    <TextView\r
+                        android:layout_width="wrap_content"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="state : "\r
+                        android:id="@+id/textView18"\r
+                        android:layout_marginLeft="80dp" />\r
+\r
+                    <TextView\r
+                        android:layout_width="wrap_content"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="wait"\r
+                        android:id="@+id/txt_getConfigurationState" />\r
+                </LinearLayout>\r
+\r
+                <LinearLayout\r
+                    android:orientation="horizontal"\r
+                    android:layout_width="match_parent"\r
+                    android:layout_height="wrap_content"\r
+                    android:id="@+id/layout_devName"\r
+                    android:weightSum="1"\r
+                    android:layout_marginLeft="10dp"\r
+                    android:layout_marginTop="10dp" >\r
+\r
+                    <TextView\r
+                        android:layout_width="130dp"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="devName"\r
+                        android:id="@+id/textView7"\r
+                        android:layout_gravity="center_vertical" />\r
+\r
+                    <TextView\r
+                        android:layout_width="wrap_content"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="empty"\r
+                        android:id="@+id/txt_devName" />\r
+\r
+                </LinearLayout>\r
+\r
+               <LinearLayout\r
+                    android:orientation="horizontal"\r
+                    android:layout_width="match_parent"\r
+                    android:layout_height="wrap_content"\r
+                    android:id="@+id/layout_modelNumber"\r
+                    android:weightSum="1"\r
+                    android:layout_marginLeft="10dp"\r
+                    android:layout_marginTop="10dp" >\r
+\r
+                    <TextView\r
+                        android:layout_width="130dp"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="modelNumber"\r
+                        android:id="@+id/textView7"\r
+                        android:layout_gravity="center_vertical" />\r
+\r
+                    <TextView\r
+                        android:layout_width="wrap_content"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="empty"\r
+                        android:id="@+id/txt_modelNumber" />\r
+\r
+                </LinearLayout>\r
+\r
+                <LinearLayout\r
+                    android:orientation="horizontal"\r
+                    android:layout_width="match_parent"\r
+                    android:layout_height="wrap_content"\r
+                    android:id="@+id/layout_devType"\r
+                    android:weightSum="1"\r
+                    android:layout_marginLeft="10dp"\r
+                    android:layout_marginTop="10dp" >\r
+\r
+                    <TextView\r
+                        android:layout_width="130dp"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="devType"\r
+                        android:id="@+id/textView8"\r
+                        android:layout_gravity="center_vertical" />\r
+\r
+                    <TextView\r
+                        android:layout_width="wrap_content"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="empty"\r
+                        android:id="@+id/txt_devType" />\r
+\r
+                </LinearLayout>\r
+\r
+                <LinearLayout\r
+                    android:orientation="horizontal"\r
+                    android:layout_width="match_parent"\r
+                    android:layout_height="wrap_content"\r
+                    android:id="@+id/layout_devSubType"\r
+                    android:weightSum="1"\r
+                    android:layout_marginLeft="10dp"\r
+                    android:layout_marginTop="10dp" >\r
+\r
+                    <TextView\r
+                        android:layout_width="130dp"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="devSubType"\r
+                        android:id="@+id/textView9"\r
+                        android:layout_gravity="center_vertical" />\r
+\r
+                    <TextView\r
+                        android:layout_width="wrap_content"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="empty"\r
+                        android:id="@+id/txt_devSubType" />\r
+\r
+                </LinearLayout>\r
+\r
+                <LinearLayout\r
+                    android:orientation="horizontal"\r
+                    android:layout_width="match_parent"\r
+                    android:layout_height="wrap_content"\r
+                    android:id="@+id/layout_wifimode"\r
+                    android:weightSum="1"\r
+                    android:layout_marginLeft="10dp"\r
+                    android:layout_marginTop="10dp" >\r
+\r
+                    <TextView\r
+                        android:layout_width="130dp"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="wifi mode"\r
+                        android:id="@+id/textView20"\r
+                        android:layout_gravity="center_vertical" />\r
+\r
+                    <TextView\r
+                        android:layout_width="wrap_content"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="empty"\r
+                        android:id="@+id/txt_wifiMode" />\r
+\r
+                </LinearLayout>\r
+\r
+                <LinearLayout\r
+                    android:orientation="horizontal"\r
+                    android:layout_width="match_parent"\r
+                    android:layout_height="wrap_content"\r
+                    android:id="@+id/layout_wififreq"\r
+                    android:weightSum="1"\r
+                    android:layout_marginLeft="10dp"\r
+                    android:layout_marginTop="10dp" >\r
+\r
+                    <TextView\r
+                        android:layout_width="130dp"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="wifi freq"\r
+                        android:id="@+id/textView21"\r
+                        android:layout_gravity="center_vertical" />\r
+\r
+                    <TextView\r
+                        android:layout_width="wrap_content"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="empty"\r
+                        android:id="@+id/txt_wifiFreq" />\r
+\r
+                </LinearLayout>\r
+\r
+                <LinearLayout\r
+                    android:orientation="horizontal"\r
+                    android:layout_width="match_parent"\r
+                    android:layout_height="wrap_content"\r
+                    android:id="@+id/layout_coludAccessAble"\r
+                    android:weightSum="1"\r
+                    android:layout_marginLeft="10dp"\r
+                    android:layout_marginTop="10dp" >\r
+\r
+                    <TextView\r
+                        android:layout_width="130dp"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="CloudAccessable"\r
+                        android:id="@+id/textView14"\r
+                        android:layout_gravity="center_vertical" />\r
+\r
+                    <TextView\r
+                        android:layout_width="wrap_content"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="empty"\r
+                        android:id="@+id/txt_cloudAccessable" />\r
+\r
+                </LinearLayout>\r
+\r
+                <Button\r
+                    android:layout_width="90dp"\r
+                    android:layout_height="wrap_content"\r
+                    android:text="@string/start"\r
+                    android:id="@+id/btn_startGetConfiguration"\r
+                    android:layout_gravity="bottom|right" />\r
+\r
+            </LinearLayout>\r
+\r
+            <LinearLayout\r
+                android:orientation="vertical"\r
+                android:layout_width="match_parent"\r
+                android:layout_height="match_parent"\r
+                android:layout_marginLeft="20dp"\r
+                android:layout_marginRight="20dp"\r
+                android:id="@+id/layout_ProvisionDevConf"\r
+                android:layout_marginTop="10dp"\r
+                android:visibility="gone">\r
+\r
+                <LinearLayout\r
+                    android:orientation="horizontal"\r
+                    android:layout_width="match_parent"\r
+                    android:layout_height="wrap_content">\r
+\r
+                    <TextView\r
+                        android:layout_width="wrap_content"\r
+                        android:layout_height="wrap_content"\r
+                        android:textAppearance="?android:attr/textAppearanceSmall"\r
+                        android:text="@string/enroller_infomation"\r
+                        android:id="@+id/textView_DataProvisioning" />\r
+\r
+                    <TextView\r
+                        android:layout_width="wrap_content"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="state : "\r
+                        android:id="@+id/textView19"\r
+                        android:layout_marginLeft="80dp" />\r
+\r
+                    <TextView\r
+                        android:layout_width="wrap_content"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="wait"\r
+                        android:id="@+id/txt_provisionDevConfState" />\r
+                </LinearLayout>\r
+\r
+                <LinearLayout\r
+                    android:orientation="horizontal"\r
+                    android:layout_width="match_parent"\r
+                    android:layout_height="wrap_content"\r
+                    android:id="@+id/linearLayout3"\r
+                    android:weightSum="1"\r
+                    android:layout_marginLeft="10dp"\r
+                    android:layout_marginTop="10dp" >\r
+\r
+                    <TextView\r
+                        android:layout_width="130dp"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="language"\r
+                        android:id="@+id/textView2"\r
+                        android:layout_gravity="center_vertical" />\r
+\r
+                    <EditText\r
+                        android:layout_width="match_parent"\r
+                        android:layout_height="wrap_content"\r
+                        android:id="@+id/editText_Language"\r
+                        android:layout_marginLeft="20dp"\r
+                        android:layout_gravity="center_vertical"\r
+                        android:text="korean" />\r
+                </LinearLayout>\r
+\r
+                <LinearLayout\r
+                    android:orientation="horizontal"\r
+                    android:layout_width="match_parent"\r
+                    android:layout_height="wrap_content"\r
+                    android:id="@+id/linearLayout4"\r
+                    android:weightSum="1"\r
+                    android:layout_marginLeft="10dp"\r
+                    android:layout_marginTop="10dp" >\r
+\r
+                    <TextView\r
+                        android:layout_width="130dp"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="country"\r
+                        android:id="@+id/textView6"\r
+                        android:layout_gravity="center_vertical" />\r
+\r
+                    <EditText\r
+                        android:layout_width="match_parent"\r
+                        android:layout_height="wrap_content"\r
+                        android:id="@+id/editText_Country"\r
+                        android:layout_marginLeft="20dp"\r
+                        android:layout_gravity="center_vertical"\r
+                        android:text="korea" />\r
+                </LinearLayout>\r
+\r
+               <LinearLayout\r
+                    android:orientation="horizontal"\r
+                    android:layout_width="match_parent"\r
+                    android:layout_height="wrap_content"\r
+                    android:id="@+id/layout_InputLocation"\r
+                    android:weightSum="1"\r
+                    android:layout_marginLeft="10dp"\r
+                    android:layout_marginTop="10dp" >\r
+\r
+                    <TextView\r
+                        android:layout_width="130dp"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="location"\r
+                        android:id="@+id/textView23"\r
+                        android:layout_gravity="center_vertical" />\r
+\r
+                    <EditText\r
+                        android:layout_width="match_parent"\r
+                        android:layout_height="wrap_content"\r
+                        android:id="@+id/editText_Location"\r
+                        android:text="Test_Location"\r
+                        android:layout_marginLeft="20dp"\r
+                        android:layout_gravity="center_vertical" />\r
+                </LinearLayout>\r
+\r
+                <LinearLayout\r
+                    android:orientation="horizontal"\r
+                    android:layout_width="match_parent"\r
+                    android:layout_height="wrap_content"\r
+                    android:id="@+id/layout_EnrollerSSID"\r
+                    android:weightSum="1"\r
+                    android:layout_marginLeft="10dp"\r
+                    android:layout_marginTop="10dp">\r
+\r
+                    <TextView\r
+                        android:layout_width="130dp"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="@string/enroller_ssid"\r
+                        android:id="@+id/txt_ssid"\r
+                        android:layout_gravity="center_vertical" />\r
+\r
+                    <EditText\r
+                        android:layout_width="match_parent"\r
+                        android:layout_height="wrap_content"\r
+                        android:id="@+id/editText_EnrollerSSID"\r
+                        android:layout_marginLeft="20dp"\r
+                        android:layout_gravity="center_vertical"\r
+                        android:text="SSID" />\r
+                </LinearLayout>\r
+\r
+                <LinearLayout\r
+                    android:orientation="horizontal"\r
+                    android:layout_width="match_parent"\r
+                    android:layout_height="wrap_content"\r
+                    android:id="@+id/layout_EnrollerPW"\r
+                    android:weightSum="1"\r
+                    android:layout_marginLeft="10dp"\r
+                    android:layout_marginTop="10dp" >\r
+\r
+                    <TextView\r
+                        android:layout_width="130dp"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="Enter Enroller&apos;s PW"\r
+                        android:id="@+id/txt_pass"\r
+                        android:layout_gravity="center_vertical" />\r
+\r
+                    <EditText\r
+                        android:layout_width="match_parent"\r
+                        android:layout_height="wrap_content"\r
+                        android:id="@+id/editText_EnrollerPW"\r
+                        android:layout_marginLeft="20dp"\r
+                        android:layout_gravity="center_vertical"\r
+                        android:text="PW" />\r
+                </LinearLayout>\r
+\r
+                <LinearLayout\r
+                    android:orientation="horizontal"\r
+                    android:layout_width="match_parent"\r
+                    android:layout_height="wrap_content"\r
+                    android:id="@+id/layout_DiscoveryChannel"\r
+                    android:weightSum="1"\r
+                    android:layout_marginLeft="10dp"\r
+                    android:layout_marginTop="10dp" >\r
+\r
+                    <TextView\r
+                        android:layout_width="130dp"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="Enter Discovery Ch."\r
+                        android:id="@+id/textView11"\r
+                        android:layout_gravity="center_vertical" />\r
+\r
+                    <EditText\r
+                        android:layout_width="match_parent"\r
+                        android:layout_height="wrap_content"\r
+                        android:id="@+id/editText_DiscoveryChannel"\r
+                        android:layout_marginLeft="20dp"\r
+                        android:layout_gravity="center_vertical"\r
+                        android:text="1" />\r
+                </LinearLayout>\r
+\r
+                <LinearLayout\r
+                    android:orientation="horizontal"\r
+                    android:layout_width="match_parent"\r
+                    android:layout_height="wrap_content"\r
+                    android:id="@+id/layout_LocationAddr"\r
+                    android:weightSum="1"\r
+                    android:layout_marginLeft="10dp"\r
+                    android:layout_marginTop="10dp" >\r
+\r
+                    <TextView\r
+                        android:layout_width="130dp"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="Enter Addr"\r
+                        android:id="@+id/textView11"\r
+                        android:layout_gravity="center_vertical" />\r
+\r
+                    <EditText\r
+                        android:layout_width="match_parent"\r
+                        android:layout_height="wrap_content"\r
+                        android:id="@+id/editText_LocationAddr"\r
+                        android:layout_marginLeft="20dp"\r
+                        android:layout_gravity="center_vertical"\r
+                        android:text="addr=Seoul, Rep. of Korea" />\r
+                </LinearLayout>\r
+\r
+                <LinearLayout\r
+                    android:orientation="horizontal"\r
+                    android:layout_width="match_parent"\r
+                    android:layout_height="wrap_content"\r
+                    android:id="@+id/layout_LocationZip"\r
+                    android:weightSum="1"\r
+                    android:layout_marginLeft="10dp"\r
+                    android:layout_marginTop="10dp" >\r
+\r
+                    <TextView\r
+                        android:layout_width="130dp"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="Enter Zip code"\r
+                        android:id="@+id/textView11"\r
+                        android:layout_gravity="center_vertical" />\r
+\r
+                    <EditText\r
+                        android:layout_width="match_parent"\r
+                        android:layout_height="wrap_content"\r
+                        android:id="@+id/editText_LocationZip"\r
+                        android:layout_marginLeft="20dp"\r
+                        android:layout_gravity="center_vertical"\r
+                        android:text="zip=02848" />\r
+                </LinearLayout>\r
+\r
+                <LinearLayout\r
+                    android:orientation="horizontal"\r
+                    android:layout_width="match_parent"\r
+                    android:layout_height="wrap_content"\r
+                    android:id="@+id/layout_LocationBuilding"\r
+                    android:weightSum="1"\r
+                    android:layout_marginLeft="10dp"\r
+                    android:layout_marginTop="10dp" >\r
+\r
+                    <TextView\r
+                        android:layout_width="130dp"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="Enter Building name"\r
+                        android:id="@+id/textView11"\r
+                        android:layout_gravity="center_vertical" />\r
+\r
+                    <EditText\r
+                        android:layout_width="match_parent"\r
+                        android:layout_height="wrap_content"\r
+                        android:id="@+id/editText_LocationBuilding"\r
+                        android:layout_marginLeft="20dp"\r
+                        android:layout_gravity="center_vertical"\r
+                        android:text="bd=apartment" />\r
+                </LinearLayout>\r
+\r
+                <LinearLayout\r
+                    android:orientation="horizontal"\r
+                    android:layout_width="match_parent"\r
+                    android:layout_height="wrap_content"\r
+                    android:id="@+id/layout_EnrollerAuthType"\r
+                    android:weightSum="1"\r
+                    android:layout_marginLeft="10dp"\r
+                    android:layout_marginTop="10dp" >\r
+\r
+                    <TextView\r
+                        android:layout_width="130dp"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="@string/select_enroller_authentication_type"\r
+                        android:id="@+id/txt_authtype"\r
+                        android:layout_gravity="center_vertical" />\r
+\r
+                    <Spinner\r
+                        android:layout_width="fill_parent"\r
+                        android:layout_height="wrap_content"\r
+                        android:id="@+id/spinner_authType"\r
+                        android:layout_marginLeft="20dp"\r
+                        android:layout_gravity="center_vertical"\r
+                        android:spinnerMode="dropdown" />\r
+\r
+                </LinearLayout>\r
+\r
+                <LinearLayout\r
+                    android:orientation="horizontal"\r
+                    android:layout_width="match_parent"\r
+                    android:layout_height="wrap_content"\r
+                    android:id="@+id/layout_EnrollerEncType"\r
+                    android:weightSum="1"\r
+                    android:layout_marginLeft="10dp"\r
+                    android:layout_marginTop="10dp" >\r
+\r
+                    <TextView\r
+                        android:layout_width="130dp"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="@string/select_enroller_encription_type"\r
+                        android:id="@+id/textView5"\r
+                        android:layout_gravity="center_vertical" />\r
+\r
+                    <Spinner\r
+                        android:layout_width="fill_parent"\r
+                        android:layout_height="wrap_content"\r
+                        android:id="@+id/spinner_encType"\r
+                        android:layout_marginLeft="20dp"\r
+                        android:layout_gravity="center_vertical"\r
+                        android:spinnerMode="dropdown" />\r
+\r
+                </LinearLayout>\r
+\r
+                <Button\r
+                    android:layout_width="90dp"\r
+                    android:layout_height="wrap_content"\r
+                    android:text="START"\r
+                    android:id="@+id/btn_startProvisionDevConf"\r
+                    android:layout_marginTop="10dp"\r
+                    android:layout_gravity="bottom|right" />\r
+\r
+            </LinearLayout>\r
+\r
+            <LinearLayout\r
+                android:orientation="vertical"\r
+                android:layout_width="match_parent"\r
+                android:layout_height="match_parent"\r
+                android:layout_marginLeft="20dp"\r
+                android:layout_marginRight="20dp"\r
+                android:id="@+id/layout_ProvisionCloudConf"\r
+                android:layout_marginTop="10dp"\r
+                android:visibility="gone">\r
+\r
+                <LinearLayout\r
+                    android:orientation="horizontal"\r
+                    android:layout_width="match_parent"\r
+                    android:layout_height="wrap_content">\r
+\r
+                    <TextView\r
+                        android:layout_width="wrap_content"\r
+                        android:layout_height="wrap_content"\r
+                        android:textAppearance="?android:attr/textAppearanceSmall"\r
+                        android:text="Cloud Information"\r
+                        android:id="@+id/textView15" />\r
+\r
+                    <TextView\r
+                        android:layout_width="wrap_content"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="state : "\r
+                        android:id="@+id/textView24"\r
+                        android:layout_marginLeft="80dp" />\r
+\r
+                    <TextView\r
+                        android:layout_width="wrap_content"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="wait"\r
+                        android:id="@+id/txt_provisionCloudConfState" />\r
+                </LinearLayout>\r
+\r
+                <LinearLayout\r
+                    android:orientation="horizontal"\r
+                    android:layout_width="match_parent"\r
+                    android:layout_height="wrap_content"\r
+                    android:id="@+id/linearLayout11"\r
+                    android:weightSum="1"\r
+                    android:layout_marginLeft="10dp"\r
+                    android:layout_marginTop="10dp" >\r
+\r
+                    <TextView\r
+                        android:layout_width="130dp"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="Enter Target Cloud&apos;s Authcode"\r
+                        android:id="@+id/textView16"\r
+                        android:layout_gravity="center_vertical" />\r
+\r
+                    <EditText\r
+                        android:layout_width="match_parent"\r
+                        android:layout_height="wrap_content"\r
+                        android:id="@+id/editText_authcode"\r
+                        android:layout_marginLeft="20dp"\r
+                        android:layout_gravity="center_vertical"\r
+                        android:text="authcode" />\r
+                </LinearLayout>\r
+\r
+                <LinearLayout\r
+                    android:orientation="horizontal"\r
+                    android:layout_width="match_parent"\r
+                    android:layout_height="wrap_content"\r
+                    android:id="@+id/linearLayout12"\r
+                    android:weightSum="1"\r
+                    android:layout_marginLeft="10dp"\r
+                    android:layout_marginTop="10dp" >\r
+\r
+                    <TextView\r
+                        android:layout_width="130dp"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="Enter Target Cloud&apos;s AuthProvider"\r
+                        android:id="@+id/textView17"\r
+                        android:layout_gravity="center_vertical" />\r
+\r
+                    <EditText\r
+                        android:layout_width="match_parent"\r
+                        android:layout_height="wrap_content"\r
+                        android:id="@+id/editText_authprovider"\r
+                        android:layout_marginLeft="20dp"\r
+                        android:layout_gravity="center_vertical"\r
+                        android:text="authprovider" />\r
+                </LinearLayout>\r
+\r
+                <LinearLayout\r
+                    android:orientation="horizontal"\r
+                    android:layout_width="match_parent"\r
+                    android:layout_height="wrap_content"\r
+                    android:id="@+id/linearLayout"\r
+                    android:weightSum="1"\r
+                    android:layout_marginLeft="10dp"\r
+                    android:layout_marginTop="10dp" >\r
+\r
+                    <TextView\r
+                        android:layout_width="130dp"\r
+                        android:layout_height="wrap_content"\r
+                        android:text="Enter Target Cloud&apos;s Interface server"\r
+                        android:id="@+id/textView3"\r
+                        android:layout_gravity="center_vertical" />\r
+\r
+                    <EditText\r
+                        android:layout_width="match_parent"\r
+                        android:layout_height="wrap_content"\r
+                        android:id="@+id/editText_ciserver"\r
+                        android:layout_marginLeft="20dp"\r
+                        android:layout_gravity="center_vertical"\r
+                        android:text="ciserver" />\r
+                </LinearLayout>\r
+\r
+                <Button\r
+                    android:layout_width="90dp"\r
+                    android:layout_height="wrap_content"\r
+                    android:text="START"\r
+                    android:id="@+id/btn_startProvisionCloudConf"\r
+                    android:layout_marginTop="10dp"\r
+                    android:layout_gravity="bottom|right" />\r
+\r
+            </LinearLayout>\r
+        </LinearLayout>\r
+    </ScrollView>\r
+\r
+</LinearLayout>
\ No newline at end of file
diff --git a/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/menu/main.xml b/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/menu/main.xml
new file mode 100755 (executable)
index 0000000..97c527e
--- /dev/null
@@ -0,0 +1,11 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:context="org.iotivity.service.easysetup.MainActivity" >
+
+    <item
+        android:id="@+id/action_settings"
+        android:orderInCategory="100"
+        android:title="@string/action_settings"/>
+
+</menu>
diff --git a/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/values/arrays.xml b/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/values/arrays.xml
new file mode 100644 (file)
index 0000000..1a28c8c
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<resources>\r
+    <string-array name="auth_type">\r
+        <item>NONE_AUTH</item>\r
+        <item>WEP</item>\r
+        <item>WPA_PSK</item>\r
+        <item>WPA2_PSK</item>\r
+    </string-array>\r
+    <string-array name="enc_type">\r
+        <item>NONE_ENC</item>\r
+        <item>WEP_64</item>\r
+        <item>WEP_128</item>\r
+        <item>TKIP</item>\r
+        <item>AES</item>\r
+        <item>TKIP_AES</item>\r
+    </string-array>\r
+</resources>
\ No newline at end of file
diff --git a/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/values/dimens.xml b/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/values/dimens.xml
new file mode 100644 (file)
index 0000000..ab91646
--- /dev/null
@@ -0,0 +1,7 @@
+<resources>
+
+    <!-- Default screen margins, per the Android Design guidelines. -->
+    <dimen name="activity_horizontal_margin">16dp</dimen>
+    <dimen name="activity_vertical_margin">1dp</dimen>
+
+</resources>
diff --git a/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/values/strings.xml b/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/values/strings.xml
new file mode 100644 (file)
index 0000000..c92a2ea
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">Easy Setup</string>
+    <string name="action_settings">Settings</string>
+
+    <string name="security_mode">Security Mode</string>
+    <string name="enroller_ssid">Enter Enroller\'s SSID</string>
+    <string name="select_enroller_authentication_type">Select Enroller\'s Authentication Type</string>
+    <string name="select_enroller_encription_type">Select Enroller\'s Encription Type</string>
+    <string name="enroller_infomation">Enroller\'s Infomation</string>
+    <string name="requsetpropertydata">RequsetPropertyData</string>
+    <string name="securityprovisioning">SecurityProvisioning</string>
+    <string name="dataprovisioning">DataProvisioning</string>
+    <string name="cloudprovisioning">CloudProvisioning</string>
+    <string name="log">log</string>
+    <string name="start">START</string>
+    <string name="enrollee_property_data">Enrollee\'s Property Data</string>
+    <string name="enter_enroller_apos_s_pw">Enter Enroller\'s PW</string>
+    <string name="easysetup_sequence">Easysetup Sequence</string>
+    <string name="security_provisioning_state">Security Provisioning State</string>
+
+
+</resources>
diff --git a/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/values/styles.xml b/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/app/src/main/res/values/styles.xml
new file mode 100644 (file)
index 0000000..6ce89c7
--- /dev/null
@@ -0,0 +1,20 @@
+<resources>
+
+    <!--
+        Base application theme, dependent on API level. This theme is replaced
+        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Light">
+        <!--
+            Theme customizations available in newer API levels can go in
+            res/values-vXX/styles.xml, while customizations related to
+            backward-compatibility can go here.
+        -->
+    </style>
+
+    <!-- Application theme. -->
+    <style name="AppTheme" parent="AppBaseTheme">
+        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
+    </style>
+
+</resources>
diff --git a/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/build.gradle b/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/build.gradle
new file mode 100755 (executable)
index 0000000..c02583e
--- /dev/null
@@ -0,0 +1,39 @@
+//******************************************************************\r
+//\r
+// Copyright 2016 Samsung Electronics All Rights Reserved.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+//      http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+\r
+// Top-level build file where you can add configuration options common to all sub-projects/modules.\r
+\r
+buildscript {\r
+    repositories {\r
+        jcenter()\r
+    }\r
+    dependencies {\r
+        classpath 'com.android.tools.build:gradle:1.3.0'\r
+\r
+        // NOTE: Do not place your application dependencies here; they belong\r
+        // in the individual module build.gradle files\r
+    }\r
+}\r
+\r
+allprojects {\r
+    repositories {\r
+        jcenter()\r
+    }\r
+}\r
diff --git a/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/gradle.properties b/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/gradle.properties
new file mode 100644 (file)
index 0000000..23f541f
--- /dev/null
@@ -0,0 +1,47 @@
+#
+# //******************************************************************
+# //
+# // Copyright 2016 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.
+# //
+# //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#
+
+# 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
+TARGET_ARCH=armeabi
+RELEASE=release
+SECURED=1
+ERROR_MSG="if building examples from android-studio, you might need to modify the default TARGET_ARCH\
+   and RELEASE in <iotivity>/android/examples/gradle.properties,\
+   if your aar file has different values for TARGET_ARCH and RELEASE"
+
diff --git a/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/settings.gradle b/service/easy-setup/sampleapp/mediator/android-samsung/EasySetup/settings.gradle
new file mode 100755 (executable)
index 0000000..a86cfbe
--- /dev/null
@@ -0,0 +1,21 @@
+//******************************************************************
+//
+// Copyright 2016 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 ':app'
diff --git a/service/easy-setup/sampleapp/mediator/android-samsung/SConscript b/service/easy-setup/sampleapp/mediator/android-samsung/SConscript
new file mode 100644 (file)
index 0000000..8009816
--- /dev/null
@@ -0,0 +1,78 @@
+#//******************************************************************
+#//
+#// Copyright 2016 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.
+#//
+#//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+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=<YOUR_PORT_NUMBER>                                        *
+*    sdkman.monitor.density=108                                               *
+*    http.proxyHost=<YOUR_HTTP_PROXY_ADDRESS>                                 *
+*    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')
+
+#SConscript("../../../../../../android/android_api/SConscript")
+
+def ensure_libs(target, source, env):
+    return target, [source, env.get('BUILD_DIR') + 'liboc.so', env.get('BUILD_DIR') + 'liboc_logger.so']                        
+
+jdk_env = Environment(ENV=os.environ)
+jdk_env['BUILDERS']['Gradle'] = Builder(action = env.get('ANDROID_GRADLE') + 
+    ' build -bservice/easy-setup/sampleapp/mediator/android-samsung/EasySetup/build.gradle -PTARGET_ARCH=%s -PRELEASE=%s --stacktrace' %(ANDROID_TARGET_ARCH, ANDROID_RELEASE),
+    emitter = ensure_libs)
+jdk_env['BUILD_DIR'] = env.get('BUILD_DIR')
+cmdBuildEasysetupSCApp=jdk_env.Gradle(target="EasySetup/app/apk", 
+    source="EasySetup/app/src/main/java/org/iotivity/service/easysetup/EasysetupActivity.java")
+
+Depends(cmdBuildEasysetupSCApp, env.get('baseAAR'))
\ No newline at end of file
index 6b2e149..a7549d1 100644 (file)
Binary files a/service/easy-setup/sampleapp/mediator/android/EasySetup/app/src/main/assets/oic_svr_db_client.dat and b/service/easy-setup/sampleapp/mediator/android/EasySetup/app/src/main/assets/oic_svr_db_client.dat differ
index 24857ce..5bc15fc 100644 (file)
                             "rel": "",
                             "rt": ["oic.wk.p"],
                             "if": ["oic.if.baseline", "oic.if.r"]
-                        },
-                        {
-                            "href": "/oic/sec/acl",
-                            "rel": "",
-                            "rt": ["oic.r.acl"],
-                            "if": ["oic.if.baseline"]
-                        },
-                        {
-                            "href": "/oic/res/types/d",
-                            "rel": "",
-                            "rt": ["oic.wk.res"],
-                            "if": ["oic.if.baseline"]
                         }
                     ],
                     "permission": 2
index 0271ae5..650f44d 100755 (executable)
@@ -472,7 +472,7 @@ public class EasysetupActivity extends Activity
                         });
 
                         try {
-                            String requestUri = OcPlatform.WELL_KNOWN_QUERY + "?rt=" + ESConstants.OC_RSRVD_ES_RES_TYPE_PROV;
+                            String requestUri = OcPlatform.WELL_KNOWN_QUERY + "?rt=" + ESConstants.OC_RSRVD_ES_RES_TYPE_EASYSETUP;
                             OcPlatform.findResource("",
                                     requestUri,
                                     EnumSet.of(OcConnectivityType.CT_DEFAULT),
diff --git a/service/easy-setup/sampleapp/mediator/linux-samsung/richsdk_sample/SConscript b/service/easy-setup/sampleapp/mediator/linux-samsung/richsdk_sample/SConscript
new file mode 100755 (executable)
index 0000000..8ffaaba
--- /dev/null
@@ -0,0 +1,78 @@
+#******************************************************************
+#
+# Copyright 2016 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.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+Import('env')
+
+mediator_env = env.Clone()
+
+target_os = env.get('TARGET_OS')
+
+######################################################################
+# Build flags
+######################################################################
+mediator_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+
+if env.get('RELEASE'):
+    mediator_env.AppendUnique(CCFLAGS = ['-Os'])
+    mediator_env.AppendUnique(CPPDEFINES = ['NDEBUG'])
+else:
+    mediator_env.AppendUnique(CCFLAGS = ['-g'])
+
+if env.get('LOGGING'):
+    env.AppendUnique(CPPDEFINES = ['TB_LOG'])
+
+env.AppendUnique(CPPDEFINES = ['CPP_MEDIATOR'])
+
+if target_os not in ['windows']:
+    mediator_env.AppendUnique(CXXFLAGS = ['-Wall', '-std=c++0x'])
+
+mediator_env.PrependUnique(CPPPATH = [
+            env.get('SRC_DIR') + '/resource/include',
+            env.get('SRC_DIR') + '/resource/oc_logger/include',
+                       env.get('SRC_DIR') + '/resource/c_common/oic_malloc/include',
+                       env.get('SRC_DIR') + '/resource/csdk/stack/include',
+                       env.get('SRC_DIR') + '/resource/csdk/security/provisioning/include',
+                       env.get('SRC_DIR') + '/resource/csdk/security/provisioning/include/internal',
+                       env.get('SRC_DIR') + '/resource/csdk/logger/include',
+                       env.get('SRC_DIR') + '/resource/csdk/security/include',
+                       env.get('SRC_DIR') + '/resource/csdk/connectivity/api',
+                       env.get('SRC_DIR') + '/extlibs/cjson',
+                       env.get('SRC_DIR') + '/service/easy-setup/mediator/richsdk/inc',
+                       env.get('SRC_DIR') + '/service/easy-setup/mediator/richsdk/src',
+                       env.get('SRC_DIR') + '/service/easy-setup/inc'])
+
+if env.get('SECURED') == '1':
+       mediator_env.PrependUnique(LIBS = ['mbedtls', 'mbedx509','mbedcrypto'])
+
+mediator_env.PrependUnique(LIBS = ['ESMediatorRich', 'oc', 'octbstack', 'oc_logger', 'connectivity_abstraction'])
+
+if env.get('SECURED') == '1':
+       mediator_env.PrependUnique(LIBS = ['ocpmapi', 'ocprovision'])
+
+mediator = mediator_env.Program('mediator_sc', 'mediator_sc.cpp')
+
+i_mediator = mediator_env.Install(env.get('BUILD_DIR'), mediator)
+
+clientdat = mediator_env.Install(env.get('BUILD_DIR') + '/service/easy-setup/sampleapp/mediator/linux-samsung/richsdk_sample',
+                                    env.get('SRC_DIR') + '/service/easy-setup/sampleapp/mediator/linux-samsung/richsdk_sample/oic_svr_db_client.dat')
+
+
+Alias('mediator_rich', [i_mediator, clientdat])
+env.AppendTarget('mediator_rich')
diff --git a/service/easy-setup/sampleapp/mediator/linux-samsung/richsdk_sample/mediator_sc.cpp b/service/easy-setup/sampleapp/mediator/linux-samsung/richsdk_sample/mediator_sc.cpp
new file mode 100755 (executable)
index 0000000..19f2a4b
--- /dev/null
@@ -0,0 +1,461 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <iostream>
+#include <condition_variable>
+
+#include "OCPlatform.h"
+#include "OCApi.h"
+#include "OCProvisioningManager.hpp"
+
+#include "EasySetup.hpp"
+#include "ESSCCommon.h"
+
+#define ES_SAMPLE_APP_TAG "ES_SAMPLE_APP_TAG"
+#define DECLARE_MENU(FUNC, ...) { #FUNC, FUNC }
+
+#define JSON_DB_PATH "./oic_svr_db_client.dat"
+
+using namespace OC;
+using namespace OIC::Service;
+
+static std::shared_ptr<RemoteEnrollee> remoteEnrollee = nullptr;
+static std::shared_ptr<OC::OCResource> curResource = nullptr;
+
+static std::mutex g_discoverymtx;
+static std::condition_variable g_cond;
+
+
+typedef void (*Runner)();
+
+Runner g_currentRun;
+
+int processUserInput(int min = std::numeric_limits<int>::min(),
+        int max = std::numeric_limits<int>::max())
+{
+    assert(min <= max);
+
+    int input = 0;
+
+    std::cin >> input;
+    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
+
+    if (!std::cin.fail() && min <= input && input <= max)
+    {
+        return input;
+    }
+
+    std::cin.clear();
+    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
+
+    throw std::runtime_error("Invalid Input, please try again");
+}
+
+void printConfiguration(const SCEnrolleeConf& conf)
+{
+    cout << "===========================================" << endl;
+    cout << "\tDevice Name : " << conf.getDeviceName() << endl;
+    cout << "\tModel Number : " << conf.getModelNumber() << endl;
+
+    for(auto it : conf.getWiFiModes())
+    {
+        cout << "\tSupported WiFi modes : " << it << endl;
+    }
+
+    cout << "\tSupported WiFi freq : " << static_cast<int>(conf.getWiFiFreq()) << endl;
+    cout << "\tCloud accessibility: " << conf.isCloudAccessible() << endl;
+    cout << "\tDevice Type: " << conf.getDeviceType() << endl;
+    cout << "\tDevice Sub-Type: " << conf.getDeviceSubType() << endl;
+    cout << "\tRegister Set Device: " << conf.getRegisterSetDevice() << endl;
+    cout << "\tNetwork Provisioning Info: " << conf.getNetworkProvisioningInfo() << endl;
+    cout << "\tPnP Pin: " << conf.getPnpPin() << endl;
+    cout << "\tNetwork Connection State : " << conf.getNetConnectionState() << endl;
+    cout << "\tBSSID : " << conf.getBSSID() << endl;
+    cout << "\tUTC time: " << conf.getUTCDatetime() << endl;
+    cout << "\tRegional time: " << conf.getRegionalDatetime() << endl;
+    cout << "\tEasy Setup Protocol Version: " << conf.getESProtocolVersion() << endl;
+    cout << "===========================================" << endl;
+}
+
+void printStatus(const SCEnrolleeStatus& status)
+{
+    cout << "===========================================" << endl;
+    cout << "\tProvStatus : " << status.getProvStatus() << endl;
+    cout << "\tLastErrCode : " << status.getLastErrCode() << endl;
+    cout << "\tNetwork Connection State : " << status.getNetConnectionState() << endl;
+    cout << "===========================================" << endl;
+}
+
+void provisionSecurityStatusCallback(std::shared_ptr<SecProvisioningStatus> secProvisioningStatus)
+{
+    if(secProvisioningStatus->getESResult() != ES_OK)
+    {
+      cout << "provisionSecurity is failed." << endl;
+      return;
+    }
+    else
+    {
+      cout << "provisionSecurity is success." << endl;
+      cout << "uuid : " << secProvisioningStatus->getDeviceUUID()<< endl;
+    }
+}
+
+void provisionSecurity()
+{
+    try
+    {
+    remoteEnrollee->provisionSecurity((SecurityProvStatusCb)provisionSecurityStatusCallback);
+    }
+    catch (OCException &e)
+    {
+        std::cout << "Exception during provisionSecurity call" << e.reason();
+        return;
+    }
+}
+
+void getStatusCallback(std::shared_ptr< GetEnrolleeStatus > getEnrolleeStatus)
+{
+    if(getEnrolleeStatus->getESResult() != ES_OK)
+    {
+      cout << "getStatus is failed." << endl;
+      return;
+    }
+    else
+    {
+      cout << "getStatus is success." << endl;
+      printStatus(std::move(getEnrolleeStatus->getEnrolleeStatus()));
+    }
+}
+
+
+void getStatus()
+{
+    if(!remoteEnrollee)
+    {
+        return;
+    }
+
+    try
+    {
+        remoteEnrollee->getStatus(getStatusCallback);
+    }
+    catch (OCException &e)
+    {
+        std::cout << "Exception during getConfiguration call" << e.reason();
+        return;
+    }
+}
+
+void getConfigurationCallback(std::shared_ptr< GetConfigurationStatus > getConfigurationStatus)
+{
+    if(getConfigurationStatus->getESResult() != ES_OK)
+    {
+      cout << "GetConfigurationStatus is failed." << endl;
+      return;
+    }
+    else
+    {
+      cout << "GetConfigurationStatus is success." << endl;
+      printConfiguration(std::move(getConfigurationStatus->getEnrolleeConf()));
+    }
+}
+
+void getConfiguration()
+{
+    if(!remoteEnrollee)
+    {
+        return;
+    }
+
+    try
+    {
+        remoteEnrollee->getConfiguration(getConfigurationCallback);
+    }
+    catch (OCException &e)
+    {
+        std::cout << "Exception during getConfiguration call" << e.reason();
+        return;
+    }
+}
+
+void deviceProvisioningStatusCallback(std::shared_ptr< DevicePropProvisioningStatus > provStatus)
+{
+    if(provStatus->getESResult() != ES_OK)
+    {
+      cout << "Device Provisioning is failed." << endl;
+      return;
+    }
+    else
+    {
+      cout << "Device Provisioning is success." << endl;
+    }
+}
+
+void provisionDeviceProperty()
+{
+    if(!remoteEnrollee)
+    {
+        return;
+    }
+
+    SCDeviceProp scDevProp;
+    scDevProp.setWiFiProp("Iotivity_SSID", "Iotivity_PWD", WPA2_PSK, TKIP_AES);
+    scDevProp.setDevConfProp("korean", "Korea", "Location");
+    scDevProp.setDiscoveryChannel(11);
+    scDevProp.setBSSID("aa:aa:aa:aa:aa:aa");
+
+    std::vector<std::string> locations;
+    locations.push_back("addr=Seoul, Rep. of Korea");
+    locations.push_back("zip=02848");
+    locations.push_back("bd=apartment");
+    scDevProp.setSCLocation(locations);
+    scDevProp.setRegisterMobileDevice("{\"wm\":\"00:11:22:33:44:55\",\"pm\":\"00:11:22:33:44:55\",\"bm\":\"00:11:22:33:44:55\",\"dt\":\"0\",\"it\":\"0\"}");
+
+    // Set UTC and regional date
+    time_t t = time(NULL);
+
+    char utcTimeStr[33] = {0};
+    struct tm *utcTime = gmtime(&t);
+    snprintf(utcTimeStr, 33, "[%04d]-[%02d]-[%02d]T[%02d]:[%02d]:[%02d]Z",
+        utcTime->tm_year+1900, utcTime->tm_mon+1, utcTime->tm_mday, utcTime->tm_hour, utcTime->tm_min, utcTime->tm_sec);
+
+    char localTimeStr[33] = {0};
+    struct tm *localTime = localtime(&t);
+    snprintf(localTimeStr, 33, "[%04d]-[%02d]-[%02d]T[%02d]:[%02d]:[%02d]Z",
+        localTime->tm_year+1900, localTime->tm_mon+1, localTime->tm_mday, localTime->tm_hour, localTime->tm_min, localTime->tm_sec);
+
+    scDevProp.setUTCDatetime(utcTimeStr);
+    scDevProp.setRegionalDatetime(localTimeStr);
+
+    try
+    {
+        remoteEnrollee->provisionDeviceProperties(scDevProp, deviceProvisioningStatusCallback);
+    }
+    catch (OCException &e)
+    {
+        std::cout << "Exception during provisionDeviceProperties call" << e.reason();
+        return;
+    }
+}
+
+void cloudProvisioningStatusCallback(std::shared_ptr< CloudPropProvisioningStatus > provStatus)
+{
+    switch (provStatus->getESResult())
+    {
+        case ES_OK:
+            cout << "Cloud Provisioning is success." << endl;
+            break;
+        case ES_SECURE_RESOURCE_DISCOVERY_FAILURE:
+            cout << "Enrollee is not found in a given network." << endl;
+            break;
+        case ES_ACL_PROVISIONING_FAILURE:
+            cout << "ACL provisioning is failed." << endl;
+            break;
+        case ES_CERT_PROVISIONING_FAILURE:
+            cout << "CERT provisioning is failed." << endl;
+            break;
+        default:
+            cout << "Cloud Provisioning is failed." << endl;
+            break;
+    }
+}
+
+void provisionCloudProperty()
+{
+    if(!remoteEnrollee)
+    {
+        return;
+    }
+
+    SCCloudProp cloudProp;
+    cloudProp.setCloudProp("authCode", "authProvider", "ciServer");
+    cloudProp.setCloudID("f002ae8b-c42c-40d3-8b8d-1927c17bd1b3");
+    cloudProp.setCredID(1);
+    cloudProp.setClientID("166135d296");
+
+    try
+    {
+        remoteEnrollee->provisionCloudProperties(cloudProp, cloudProvisioningStatusCallback);
+    }
+    catch (OCException &e)
+    {
+        std::cout << "Exception during provisionCloudProperties call" << e.reason();
+        return;
+    }
+}
+
+void DisplayMenu()
+{
+    constexpr int PROVISION_SECURITY = 1;
+    constexpr int GET_STATUS = 2;
+    constexpr int GET_CONFIGURATION = 3;
+    constexpr int PROVISION_DEVICE_PROPERTY = 4;
+    constexpr int PROVISION_CLOUD_PROPERTY = 5;
+
+    std::cout << "========================================================\n";
+    std::cout << PROVISION_SECURITY << ". Provision Security to Enrollee  \n";
+    std::cout << GET_STATUS << ". Get Status from Enrollee  \n";
+    std::cout << GET_CONFIGURATION << ". Get Configuration from Enrollee  \n";
+    std::cout << PROVISION_DEVICE_PROPERTY << ". Provision Device Property\n";
+    std::cout << PROVISION_CLOUD_PROPERTY << ". Provision Cloud Property  \n";
+    std::cout << "========================================================\n";
+
+    int selection = processUserInput(PROVISION_SECURITY, PROVISION_CLOUD_PROPERTY);
+
+    switch (selection)
+    {
+        case PROVISION_SECURITY:
+            provisionSecurity();
+            break;
+        case GET_STATUS:
+            getStatus();
+            break;
+        case GET_CONFIGURATION:
+            getConfiguration();
+            break;
+        case PROVISION_DEVICE_PROPERTY:
+            provisionDeviceProperty();
+            break;
+        case PROVISION_CLOUD_PROPERTY:
+            provisionCloudProperty();
+            break;
+        default:
+            break;
+    };
+}
+
+// Callback to found resources
+void foundResource(std::shared_ptr<OC::OCResource> resource)
+{
+    std::string resourceURI;
+    std::string hostAddress;
+    try
+    {
+        // Do some operations with resource object.
+        if(resource &&
+           !curResource &&
+           resource->getResourceTypes().at(0) == OC_RSRVD_ES_RES_TYPE_EASYSETUP)
+        {
+            std::cout<<"DISCOVERED Resource:"<<std::endl;
+            // Get the resource URI
+            resourceURI = resource->uri();
+            std::cout << "\tURI of the resource: " << resourceURI << std::endl;
+
+            // Get the resource host address
+            hostAddress = resource->host();
+            std::cout << "\tHost address of the resource: " << hostAddress << std::endl;
+
+            // Get the resource types
+            std::cout << "\tList of resource types: " << std::endl;
+            for(auto &resourceTypes : resource->getResourceTypes())
+            {
+                std::cout << "\t\t" << resourceTypes << std::endl;
+            }
+
+            // Get the resource interfaces
+            std::cout << "\tList of resource interfaces: " << std::endl;
+            for(auto &resourceInterfaces : resource->getResourceInterfaces())
+            {
+                std::cout << "\t\t" << resourceInterfaces << std::endl;
+            }
+
+            if(curResource == nullptr)
+            {
+                remoteEnrollee = EasySetup::getInstance()->createRemoteEnrollee(resource);
+                if(!remoteEnrollee)
+                {
+                    std::cout << "RemoteEnrollee object is failed for some reasons!" << std::endl;
+                }
+                else
+                {
+                    curResource = resource;
+                    std::cout << "RemoteEnrollee object is successfully created!" << std::endl;
+                    g_cond.notify_all();
+                }
+            }
+        }
+    }
+    catch(std::exception &e)
+    {
+        std::cerr << "Exception in foundResource: "<< e.what() << std::endl;
+    }
+}
+
+static FILE* client_open(const char *UNUSED_PARAM, const char *mode)
+{
+    (void)UNUSED_PARAM;
+    return fopen(JSON_DB_PATH, mode);
+}
+
+int main()
+{
+    std::ostringstream requestURI;
+    OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
+
+    PlatformConfig config
+    {
+        OC::ServiceType::InProc, ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::HighQos, &ps
+    };
+
+    OCPlatform::Configure(config);
+
+    try
+    {
+#ifdef __WITH_DTLS__
+        //Initializing the provisioning client stack using the db path provided by the application.
+        OCStackResult result = OCSecure::provisionInit("");
+
+        if (result != OC_STACK_OK)
+        {
+            return -1;
+        }
+#endif
+
+        requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=" << OC_RSRVD_ES_RES_TYPE_EASYSETUP;
+
+        OCPlatform::findResource("", requestURI.str(), CT_DEFAULT, &foundResource);
+        std::cout<< "Finding Resource... " <<std::endl;
+
+        std::unique_lock<std::mutex> lck(g_discoverymtx);
+        g_cond.wait_for(lck, std::chrono::seconds(4));
+
+    }
+    catch(...)
+    {
+        oclog() << "Exception in main";
+    }
+
+    while (true)
+    {
+        try
+        {
+            DisplayMenu();
+        }
+        catch (...)
+        {
+            std::cout << "Exception caught in main";
+        }
+    }
+
+    std::cout << "Stopping the client" << std::endl;
+
+    return 0;
+}
+
diff --git a/service/easy-setup/sampleapp/mediator/linux-samsung/richsdk_sample/oic_svr_db_client.dat b/service/easy-setup/sampleapp/mediator/linux-samsung/richsdk_sample/oic_svr_db_client.dat
new file mode 100755 (executable)
index 0000000..6f5b6f6
Binary files /dev/null and b/service/easy-setup/sampleapp/mediator/linux-samsung/richsdk_sample/oic_svr_db_client.dat differ
index 2f422a2..ccbc795 100644 (file)
@@ -66,13 +66,17 @@ mediator_env.PrependUnique(LIBS = ['ESMediatorRich', 'oc', 'octbstack', 'oc_logg
 if env.get('SECURED') == '1':
        mediator_env.PrependUnique(LIBS = ['ocpmapi', 'ocprovision'])
 
-mediator = mediator_env.Program('mediator_rich', 'mediator_cpp.cpp')
+mediator = mediator_env.Program('mediator', 'mediator.cpp')
+submediator = mediator_env.Program('submediator', 'submediator.cpp')
 
-i_mediator = mediator_env.Install(env.get('BUILD_DIR'), mediator)
+i_mediator = mediator_env.Install(env.get('BUILD_DIR'), [mediator, submediator])
 
 clientdat = mediator_env.Install(env.get('BUILD_DIR') + '/service/easy-setup/sampleapp/mediator/linux/richsdk_sample',
                                     env.get('SRC_DIR') + '/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/oic_svr_db_client.dat')
 
+subclientdat = mediator_env.Install(env.get('BUILD_DIR') + '/service/easy-setup/sampleapp/mediator/linux/richsdk_sample',
+                                    env.get('SRC_DIR') + '/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/oic_svr_db_subclient.dat')
 
-Alias('mediator_rich', [i_mediator, clientdat])
+
+Alias('mediator_rich', [i_mediator, clientdat, subclientdat])
 env.AppendTarget('mediator_rich')
diff --git a/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/mediator.cpp b/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/mediator.cpp
new file mode 100755 (executable)
index 0000000..fb8d3f8
--- /dev/null
@@ -0,0 +1,513 @@
+//******************************************************************
+//
+// 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <iostream>
+#include <condition_variable>
+
+#include "OCPlatform.h"
+#include "OCApi.h"
+#include "OCProvisioningManager.hpp"
+#include "securevirtualresourcetypes.h"
+
+#include "EasySetup.hpp"
+#include "ESRichCommon.h"
+
+#define ES_SAMPLE_APP_TAG "ES_SAMPLE_APP_TAG"
+#define DECLARE_MENU(FUNC, ...) { #FUNC, FUNC }
+
+#define JSON_DB_PATH "./oic_svr_db_client.dat"
+
+using namespace OC;
+using namespace OIC::Service;
+
+static std::shared_ptr<RemoteEnrollee> remoteEnrollee = nullptr;
+static std::shared_ptr<OC::OCResource> curResource = nullptr;
+
+static std::mutex g_discoverymtx;
+static std::condition_variable g_cond;
+
+typedef void (*Runner)();
+
+Runner g_currentRun;
+
+int processUserInput(int min = std::numeric_limits<int>::min(),
+        int max = std::numeric_limits<int>::max())
+{
+    assert(min <= max);
+
+    int input = 0;
+
+    std::cin >> input;
+    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
+
+    if (!std::cin.fail() && min <= input && input <= max)
+    {
+        return input;
+    }
+
+    std::cin.clear();
+    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
+
+    throw std::runtime_error("Invalid Input, please try again");
+}
+
+void printConfiguration(const EnrolleeConf& conf)
+{
+    cout << "===========================================" << endl;
+    cout << "\tProvStatus : " << conf.getProvStatus() << endl;
+    cout << "\tLastErrCode : " << conf.getLastErrCode() << endl;
+    cout << "\tDevice Name : " << conf.getDeviceName() << endl;
+
+    for(auto it : conf.getWiFiModes())
+    {
+        cout << "\tSupported WiFi modes : " << it << endl;
+    }
+
+    cout << "\tSupported WiFi freq : " << static_cast<int>(conf.getWiFiFreq()) << endl;
+    cout << "\tCloud accessibility: " << conf.isCloudAccessible() << endl;
+    cout << "===========================================" << endl;
+}
+
+void printStatus(const EnrolleeStatus& status)
+{
+    cout << "===========================================" << endl;
+    cout << "\tProvStatus : " << status.getProvStatus() << endl;
+    cout << "\tLastErrCode : " << status.getLastErrCode() << endl;
+    cout << "===========================================" << endl;
+}
+
+ESOwnershipTransferData provisionSecurityStatusCallback(std::shared_ptr<SecProvisioningStatus> secProvisioningStatus)
+{
+    cout << "provisionSecurityStatusCallback IN" << endl;
+    cout << "ESResult : " << secProvisioningStatus->getESResult() << std::endl;
+    cout << "Device ID : " << secProvisioningStatus->getDeviceUUID() << std::endl;
+
+    if(secProvisioningStatus->getESResult() == ES_SECURE_RESOURCE_IS_DISCOVERED)
+    {
+#ifdef __WITH_DTLS__
+        cout << "Owned Status : " << secProvisioningStatus->isOwnedDevice() << std::endl;
+        if(secProvisioningStatus->isOwnedDevice())
+        {
+            cout << "Owner ID : " << secProvisioningStatus->getOwnerID() << std::endl;
+        }
+        cout << "OT Method : " << secProvisioningStatus->getSelectedOTMethod() << std::endl;
+#ifdef MULTIPLE_OWNER
+        cout << "MOT Enabled : " << secProvisioningStatus->isMOTEnabled() << std::endl;
+
+        // TEST
+        ESOwnershipTransferData OTData;
+        OTData.setMOTMethod(OIC_PRECONFIG_PIN, "12345678");
+
+        cout << "Enter!" << std::endl;
+        getchar();
+
+        return OTData;
+#endif
+#endif
+    }
+    else if(secProvisioningStatus->getESResult() == ES_OK)
+    {
+        cout << "provisionSecurity is success." << std::endl;
+    }
+    else
+    {
+        cout << "provisionSecurity is failed." << endl;
+    }
+
+    return {};
+}
+
+void provisionSecurity()
+{
+    if(!remoteEnrollee)
+    {
+        std::cout << "RemoteEnrollee is null, retry Discovery EnrolleeResource." << endl;
+        return;
+    }
+
+    try
+    {
+        remoteEnrollee->provisionSecurity((SecurityProvStatusCbWithOption)provisionSecurityStatusCallback);
+    }
+    catch (OCException &e)
+    {
+        std::cout << "Exception during provisionSecurity call" << e.reason();
+        return;
+    }
+}
+
+void getStatusCallback(std::shared_ptr< GetEnrolleeStatus > getEnrolleeStatus)
+{
+    if(getEnrolleeStatus->getESResult() != ES_OK)
+    {
+      cout << "getStatus is failed." << endl;
+      return;
+    }
+    else
+    {
+      cout << "getStatus is success." << endl;
+      printStatus(getEnrolleeStatus->getEnrolleeStatus());
+    }
+}
+
+
+void getStatus()
+{
+    if(!remoteEnrollee)
+    {
+        std::cout << "RemoteEnrollee is null, retry Discovery EnrolleeResource." << endl;
+        return;
+    }
+
+    try
+    {
+        remoteEnrollee->getStatus(getStatusCallback);
+    }
+    catch (OCException &e)
+    {
+        std::cout << "Exception during getConfiguration call" << e.reason();
+        return;
+    }
+}
+
+void getConfigurationCallback(std::shared_ptr< GetConfigurationStatus > getConfigurationStatus)
+{
+    if(getConfigurationStatus->getESResult() != ES_OK)
+    {
+      cout << "GetConfigurationStatus is failed." << endl;
+      return;
+    }
+    else
+    {
+      cout << "GetConfigurationStatus is success." << endl;
+      printConfiguration(getConfigurationStatus->getEnrolleeConf());
+    }
+}
+
+void getConfiguration()
+{
+    if(!remoteEnrollee)
+    {
+        std::cout << "RemoteEnrollee is null, retry Discovery EnrolleeResource." << endl;
+        return;
+    }
+
+    try
+    {
+        remoteEnrollee->getConfiguration(getConfigurationCallback);
+    }
+    catch (OCException &e)
+    {
+        std::cout << "Exception during getConfiguration call" << e.reason();
+        return;
+    }
+}
+
+void deviceProvisioningStatusCallback(std::shared_ptr< DevicePropProvisioningStatus > provStatus)
+{
+    if(provStatus->getESResult() != ES_OK)
+    {
+      cout << "Device Provisioning is failed." << endl;
+      return;
+    }
+    else
+    {
+      cout << "Device Provisioning is success." << endl;
+    }
+}
+
+void provisionDeviceProperty()
+{
+    if(!remoteEnrollee)
+    {
+        std::cout << "RemoteEnrollee is null, retry Discovery EnrolleeResource." << endl;
+        return;
+    }
+
+    DeviceProp devProp;
+    devProp.setWiFiProp("Iotivity_SSID", "Iotivity_PWD", WPA2_PSK, TKIP_AES);
+
+    try
+    {
+        remoteEnrollee->provisionDeviceProperties(devProp, deviceProvisioningStatusCallback);
+    }
+    catch (OCException &e)
+    {
+        std::cout << "Exception during provisionDeviceProperties call" << e.reason();
+        return;
+    }
+}
+
+void connectRequestStatusCallback(std::shared_ptr< ConnectRequestStatus > requestStatus)
+{
+    if(requestStatus->getESResult() != ES_OK)
+    {
+      cout << "Request to connection is failed." << endl;
+      return;
+    }
+    else
+    {
+      cout << "Request to connection is success." << endl;
+    }
+}
+
+void requestToConnect()
+{
+    if(!remoteEnrollee)
+    {
+        std::cout << "RemoteEnrollee is null, retry Discovery EnrolleeResource." << endl;
+        return;
+    }
+
+    try
+    {
+        std::vector<ES_CONNECT_TYPE> types;
+        types.push_back(ES_CONNECT_WIFI);
+        types.push_back(ES_CONNECT_COAPCLOUD);
+        remoteEnrollee->requestToConnect(types, connectRequestStatusCallback);
+    }
+    catch (OCException &e)
+    {
+        std::cout << "Exception during provisionDeviceProperties call" << e.reason();
+        return;
+    }
+}
+
+void cloudProvisioningStatusCallback(std::shared_ptr< CloudPropProvisioningStatus > provStatus)
+{
+    switch (provStatus->getESResult())
+    {
+        case ES_OK:
+            cout << "Cloud Provisioning is success." << endl;
+            break;
+        case ES_SECURE_RESOURCE_DISCOVERY_FAILURE:
+            cout << "Enrollee is not found in a given network." << endl;
+            break;
+        case ES_ACL_PROVISIONING_FAILURE:
+            cout << "ACL provisioning is failed." << endl;
+            break;
+        case ES_CERT_PROVISIONING_FAILURE:
+            cout << "CERT provisioning is failed." << endl;
+            break;
+        default:
+            cout << "Cloud Provisioning is failed." << endl;
+            break;
+    }
+}
+
+void provisionCloudProperty()
+{
+    if(!remoteEnrollee)
+    {
+        std::cout << "RemoteEnrollee is null, retry Discovery EnrolleeResource." << endl;
+        return;
+    }
+
+    CloudProp cloudProp;
+    cloudProp.setCloudPropWithAccessToken("accessToken", OAUTH_TOKENTYPE_BEARER, "authProvider", "ciServer");
+    cloudProp.setCloudID("f002ae8b-c42c-40d3-8b8d-1927c17bd1b3");
+    cloudProp.setCredID(1);
+
+    try
+    {
+        remoteEnrollee->provisionCloudProperties(cloudProp, cloudProvisioningStatusCallback);
+    }
+    catch (OCException &e)
+    {
+        std::cout << "Exception during provisionCloudProperties call" << e.reason();
+        return;
+    }
+}
+
+// Callback to found resources
+void foundResource(std::shared_ptr<OC::OCResource> resource)
+{
+    std::string resourceURI;
+    std::string hostAddress;
+    try
+    {
+        // Do some operations with resource object.
+        if(resource &&
+           !curResource &&
+           resource->getResourceTypes().at(0) == OC_RSRVD_ES_RES_TYPE_EASYSETUP)
+        {
+            std::cout<<"DISCOVERED Resource:"<<std::endl;
+            // Get the resource URI
+            resourceURI = resource->uri();
+            std::cout << "\tURI of the resource: " << resourceURI << std::endl;
+
+            // Get the resource host address
+            hostAddress = resource->host();
+            std::cout << "\tHost address of the resource: " << hostAddress << std::endl;
+
+            // Get the resource types
+            std::cout << "\tList of resource types: " << std::endl;
+            for(auto &resourceTypes : resource->getResourceTypes())
+            {
+                std::cout << "\t\t" << resourceTypes << std::endl;
+            }
+
+            // Get the resource interfaces
+            std::cout << "\tList of resource interfaces: " << std::endl;
+            for(auto &resourceInterfaces : resource->getResourceInterfaces())
+            {
+                std::cout << "\t\t" << resourceInterfaces << std::endl;
+            }
+
+            if(curResource == nullptr)
+            {
+                remoteEnrollee = EasySetup::getInstance()->createRemoteEnrollee(resource);
+                if(!remoteEnrollee)
+                {
+                    std::cout << "RemoteEnrollee object is failed for some reasons!" << std::endl;
+                }
+                else
+                {
+                    curResource = resource;
+                    std::cout << "RemoteEnrollee object is successfully created!" << std::endl;
+                    g_cond.notify_all();
+                }
+            }
+        }
+    }
+    catch(std::exception& e)
+    {
+        std::cerr << "Exception in foundResource: "<< e.what() << std::endl;
+    }
+}
+
+void discoveryEnrolleeResource()
+{
+    try
+    {
+        std::ostringstream requestURI;
+        requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=" << OC_RSRVD_ES_RES_TYPE_EASYSETUP;
+        OCPlatform::findResource("", requestURI.str(), CT_DEFAULT, &foundResource);
+        std::cout<< "Finding Resource... " <<std::endl;
+
+        std::unique_lock<std::mutex> lck(g_discoverymtx);
+        g_cond.wait_for(lck, std::chrono::seconds(5));
+    }
+    catch (OCException &e)
+    {
+        std::cout << "Exception in discoveryEnrolleeResource: "<<e.what();
+    }
+}
+
+void DisplayMenu()
+{
+    constexpr int DISCOVERY_ENROLLEE = 1;
+    constexpr int PROVISION_SECURITY = 2;
+    constexpr int GET_STATUS = 3;
+    constexpr int GET_CONFIGURATION = 4;
+    constexpr int PROVISION_DEVICE_PROPERTY = 5;
+    constexpr int REQUEST_TO_CONNECT = 6;
+    constexpr int PROVISION_CLOUD_PROPERTY = 7;
+
+    std::cout << "========================================================\n";
+    std::cout << DISCOVERY_ENROLLEE << ". Discovery Enrollee Resource \n";
+    std::cout << PROVISION_SECURITY << ". Provision Security to Enrollee  \n";
+    std::cout << GET_STATUS << ". Get Status from Enrollee  \n";
+    std::cout << GET_CONFIGURATION << ". Get Configuration from Enrollee  \n";
+    std::cout << PROVISION_DEVICE_PROPERTY << ". Provision Device Property\n";
+    std::cout << REQUEST_TO_CONNECT << ". Request to Connect  \n";
+    std::cout << PROVISION_CLOUD_PROPERTY << ". Provision Cloud Property  \n";
+    std::cout << "========================================================\n";
+
+    int selection = processUserInput(DISCOVERY_ENROLLEE, PROVISION_CLOUD_PROPERTY);
+
+    switch (selection)
+    {
+        case DISCOVERY_ENROLLEE:
+            discoveryEnrolleeResource();
+            break;
+        case PROVISION_SECURITY:
+            provisionSecurity();
+            break;
+        case GET_STATUS:
+            getStatus();
+            break;
+        case GET_CONFIGURATION:
+            getConfiguration();
+            break;
+        case PROVISION_DEVICE_PROPERTY:
+            provisionDeviceProperty();
+            break;
+        case REQUEST_TO_CONNECT:
+            requestToConnect();
+            break;
+        case PROVISION_CLOUD_PROPERTY:
+            provisionCloudProperty();
+            break;
+        default:
+            break;
+    };
+}
+
+static FILE* client_open(const char *UNUSED_PARAM, const char *mode)
+{
+    (void)UNUSED_PARAM;
+    return fopen(JSON_DB_PATH, mode);
+}
+
+int main()
+{
+    OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
+
+    PlatformConfig config
+    {
+        OC::ServiceType::InProc, ModeType::Both, "0.0.0.0", 0, OC::QualityOfService::HighQos, &ps
+    };
+
+    OCPlatform::Configure(config);
+
+    try
+    {
+#ifdef __WITH_DTLS__
+        //Initializing the provisioning client stack using the db path provided by the application.
+        OCStackResult result = OCSecure::provisionInit("");
+
+        if (result != OC_STACK_OK)
+        {
+            return -1;
+        }
+#endif
+    }catch (...)
+    {
+        std::cout << "Exception in main: " << std::endl;
+    }
+
+    while (true)
+    {
+        try
+        {
+            DisplayMenu();
+        }
+        catch (...)
+        {
+            std::cout << "Exception caught in main " << std::endl;
+        }
+    }
+
+    std::cout << "Stopping the client" << std::endl;
+
+    return 0;
+}
+
diff --git a/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/oic_svr_db_subclient.dat b/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/oic_svr_db_subclient.dat
new file mode 100644 (file)
index 0000000..ae130bc
Binary files /dev/null and b/service/easy-setup/sampleapp/mediator/linux/richsdk_sample/oic_svr_db_subclient.dat differ
@@ -24,6 +24,7 @@
 #include "OCPlatform.h"
 #include "OCApi.h"
 #include "OCProvisioningManager.hpp"
+#include "securevirtualresourcetypes.h"
 
 #include "EasySetup.hpp"
 #include "ESRichCommon.h"
@@ -31,7 +32,7 @@
 #define ES_SAMPLE_APP_TAG "ES_SAMPLE_APP_TAG"
 #define DECLARE_MENU(FUNC, ...) { #FUNC, FUNC }
 
-#define JSON_DB_PATH "./oic_svr_db_client.dat"
+#define JSON_DB_PATH "./oic_svr_db_subclient.dat"
 
 using namespace OC;
 using namespace OIC::Service;
@@ -51,12 +52,15 @@ int processUserInput(int min = std::numeric_limits<int>::min(),
 {
     assert(min <= max);
 
-    int input;
+    int input = 0;
 
     std::cin >> input;
     std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
 
-    if (!std::cin.fail() && min <= input && input <= max) return input;
+    if (!std::cin.fail() && min <= input && input <= max)
+    {
+        return input;
+    }
 
     std::cin.clear();
     std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
@@ -64,11 +68,10 @@ int processUserInput(int min = std::numeric_limits<int>::min(),
     throw std::runtime_error("Invalid Input, please try again");
 }
 
-void printConfiguration(EnrolleeConf conf)
+void printConfiguration(const EnrolleeConf& conf)
 {
     cout << "===========================================" << endl;
     cout << "\tDevice Name : " << conf.getDeviceName() << endl;
-    cout << "\tModel Number : " << conf.getModelNumber() << endl;
 
     for(auto it : conf.getWiFiModes())
     {
@@ -80,7 +83,7 @@ void printConfiguration(EnrolleeConf conf)
     cout << "===========================================" << endl;
 }
 
-void printStatus(EnrolleeStatus status)
+void printStatus(const EnrolleeStatus& status)
 {
     cout << "===========================================" << endl;
     cout << "\tProvStatus : " << status.getProvStatus() << endl;
@@ -88,18 +91,42 @@ void printStatus(EnrolleeStatus status)
     cout << "===========================================" << endl;
 }
 
-void provisionSecurityStatusCallback(std::shared_ptr<SecProvisioningStatus> secProvisioningStatus)
+ESOwnershipTransferData provisionSecurityStatusCallback(std::shared_ptr<SecProvisioningStatus> secProvisioningStatus)
 {
-    if(secProvisioningStatus->getESResult() != ES_OK)
+    cout << "provisionSecurityStatusCallback IN" << endl;
+    cout << "ESResult : " << secProvisioningStatus->getESResult() << std::endl;
+    cout << "Device ID : " << secProvisioningStatus->getDeviceUUID() << std::endl;
+
+    if(secProvisioningStatus->getESResult() == ES_SECURE_RESOURCE_IS_DISCOVERED)
     {
-      cout << "provisionSecurity is failed." << endl;
-      return;
+#ifdef __WITH_DTLS__
+        cout << "Owned Status : " << secProvisioningStatus->isOwnedDevice() << std::endl;
+        cout << "OT Method : " << secProvisioningStatus->getSelectedOTMethod() << std::endl;
+#ifdef MULTIPLE_OWNER
+        cout << "MOT Enabled : " << secProvisioningStatus->isMOTEnabled() << std::endl;
+
+        // TEST
+        ESOwnershipTransferData OTData;
+        OTData.setMOTMethod(OIC_PRECONFIG_PIN, "12345678");
+
+        cout << "Enter!" << std::endl;
+        getchar();
+
+        return OTData;
+#endif
+#endif
+
+    }
+    else if(secProvisioningStatus->getESResult() == ES_OK)
+    {
+        cout << "provisionSecurity is success." << std::endl;
     }
     else
     {
-      cout << "provisionSecurity is success." << endl;
-      cout << "uuid : " << secProvisioningStatus->getDeviceUUID()<< endl;
+        cout << "provisionSecurity is failed." << endl;
     }
+
+    return {};
 }
 
 void provisionSecurity()
@@ -112,7 +139,7 @@ void provisionSecurity()
 
     try
     {
-        remoteEnrollee->provisionSecurity(provisionSecurityStatusCallback);
+        remoteEnrollee->provisionSecurity((SecurityProvStatusCbWithOption)provisionSecurityStatusCallback);
     }
     catch (OCException &e)
     {
@@ -211,7 +238,6 @@ void provisionDeviceProperty()
 
     DeviceProp devProp;
     devProp.setWiFiProp("Iotivity_SSID", "Iotivity_PWD", WPA2_PSK, TKIP_AES);
-    devProp.setDevConfProp("korean", "Korea", "Location");
 
     try
     {
@@ -224,6 +250,41 @@ void provisionDeviceProperty()
     }
 }
 
+void connectRequestStatusCallback(std::shared_ptr< ConnectRequestStatus > requestStatus)
+{
+    if(requestStatus->getESResult() != ES_OK)
+    {
+      cout << "Request to connection is failed." << endl;
+      return;
+    }
+    else
+    {
+      cout << "Request to connection is success." << endl;
+    }
+}
+
+void requestToConnect()
+{
+    if(!remoteEnrollee)
+    {
+        std::cout << "RemoteEnrollee is null, retry Discovery EnrolleeResource." << endl;
+        return;
+    }
+
+    try
+    {
+        std::vector<ES_CONNECT_TYPE> types;
+        types.push_back(ES_CONNECT_WIFI);
+        types.push_back(ES_CONNECT_COAPCLOUD);
+        remoteEnrollee->requestToConnect(types, connectRequestStatusCallback);
+    }
+    catch (OCException &e)
+    {
+        std::cout << "Exception during provisionDeviceProperties call" << e.reason();
+        return;
+    }
+}
+
 void cloudProvisioningStatusCallback(std::shared_ptr< CloudPropProvisioningStatus > provStatus)
 {
     switch (provStatus->getESResult())
@@ -280,7 +341,7 @@ void foundResource(std::shared_ptr<OC::OCResource> resource)
         // Do some operations with resource object.
         if(resource &&
            !curResource &&
-           resource->getResourceTypes().at(0) == OC_RSRVD_ES_RES_TYPE_PROV)
+           resource->getResourceTypes().at(0) == OC_RSRVD_ES_RES_TYPE_EASYSETUP)
         {
             std::cout<<"DISCOVERED Resource:"<<std::endl;
             // Get the resource URI
@@ -329,30 +390,31 @@ void foundResource(std::shared_ptr<OC::OCResource> resource)
 
 void discoveryEnrolleeResource()
 {
-       try
-       {
-           std::ostringstream requestURI;
-        requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=" << OC_RSRVD_ES_RES_TYPE_PROV;
+    try
+    {
+        std::ostringstream requestURI;
+        requestURI << OC_RSRVD_WELL_KNOWN_URI << "?rt=" << OC_RSRVD_ES_RES_TYPE_EASYSETUP;
         OCPlatform::findResource("", requestURI.str(), CT_DEFAULT, &foundResource);
         std::cout<< "Finding Resource... " <<std::endl;
 
         std::unique_lock<std::mutex> lck(g_discoverymtx);
         g_cond.wait_for(lck, std::chrono::seconds(5));
-       }
-       catch (OCException& e)
-       {
-               std::cout << "Exception in discoveryEnrolleeResource: "<<e.what();
-       }
+    }
+    catch (OCException& e)
+    {
+        std::cout << "Exception in discoveryEnrolleeResource: "<<e.what();
+    }
 }
 
 void DisplayMenu()
 {
-       constexpr int DISCOVERY_ENROLLEE = 1;
+    constexpr int DISCOVERY_ENROLLEE = 1;
     constexpr int PROVISION_SECURITY = 2;
     constexpr int GET_STATUS = 3;
     constexpr int GET_CONFIGURATION = 4;
     constexpr int PROVISION_DEVICE_PROPERTY = 5;
-    constexpr int PROVISION_CLOUD_PROPERTY = 6;
+    constexpr int REQUEST_TO_CONNECT = 6;
+    constexpr int PROVISION_CLOUD_PROPERTY = 7;
 
     std::cout << "========================================================\n";
     std::cout << DISCOVERY_ENROLLEE << ". Discovery Enrollee Resource \n";
@@ -360,6 +422,7 @@ void DisplayMenu()
     std::cout << GET_STATUS << ". Get Status from Enrollee  \n";
     std::cout << GET_CONFIGURATION << ". Get Configuration from Enrollee  \n";
     std::cout << PROVISION_DEVICE_PROPERTY << ". Provision Device Property\n";
+    std::cout << REQUEST_TO_CONNECT << ". Request to Connect  \n";
     std::cout << PROVISION_CLOUD_PROPERTY << ". Provision Cloud Property  \n";
     std::cout << "========================================================\n";
 
@@ -382,6 +445,9 @@ void DisplayMenu()
         case PROVISION_DEVICE_PROPERTY:
             provisionDeviceProperty();
             break;
+        case REQUEST_TO_CONNECT:
+            requestToConnect();
+            break;
         case PROVISION_CLOUD_PROPERTY:
             provisionCloudProperty();
             break;
@@ -411,16 +477,16 @@ int main()
     {
 #ifdef __WITH_DTLS__
         //Initializing the provisioning client stack using the db path provided by the application.
-        OCStackResult result = OCSecure::provisionInit("");
+        OCStackResult result = OCSecure::provisionInit("PDM_sub.db");
 
         if (result != OC_STACK_OK)
         {
             return -1;
         }
 #endif
-    }catch(OCException& e)
+    }catch (...)
     {
-        std::cout << "Exception in main: "<<e.what();
+        std::cout << "Exception in main: " << std::endl;
     }
 
     while (true)
@@ -429,9 +495,9 @@ int main()
         {
             DisplayMenu();
         }
-        catch (const std::exception& e)
+        catch (...)
         {
-            std::cout << "Exception caught in main " << e.what() << std::endl;
+            std::cout << "Exception caught in main " << std::endl;
         }
     }
 
index 745f801..ab2dcf9 100755 (executable)
@@ -81,12 +81,30 @@ if target_os == 'tizen':
        notification_env.AppendUnique(CPPDEFINES = ['__TIZEN__'])
        # notification_env.ParseConfig('pkg-config --cflags --libs sqlite3')
 
+if target_os == 'ios':
+       if 'CLIENT' in notification_env.get('RD_MODE'):
+               notification_env.AppendUnique(CPPDEFINES = ['RD_CLIENT'])
+
 if env.get('WITH_CLOUD') == True:
        notification_env.AppendUnique(CPPDEFINES = ['WITH_CLOUD'])
 
 if env.get('SECURED') == '1':
        notification_env.AppendUnique(CPPDEFINES = ['SECURED'])
 
+with_mq = env.get('WITH_MQ')
+if 'SUB' in with_mq:
+    notification_env.AppendUnique(CPPDEFINES = ['MQ_SUBSCRIBER', 'WITH_MQ'])
+    print "MQ SUB support"
+
+if 'PUB' in with_mq:
+    notification_env.AppendUnique(CPPDEFINES = ['MQ_PUBLISHER', 'WITH_MQ'])
+    print "MQ PUB support"
+
+if 'BROKER' in with_mq:
+    notification_env.AppendUnique(CPPDEFINES = ['MQ_BROKER', 'WITH_MQ'])
+    print "MQ Broker support"
+
+
 ######################################################################
 # Source files and Targets
 ######################################################################
@@ -98,18 +116,20 @@ if target_os == 'android':
 if target_os == 'android':
        notification_consumer_env.AppendUnique(LINKFLAGS = ['-Wl,-soname,libnotification_consumer.so'])
 
+notification_common_obj = notification_provider_env.SharedObject(env.Glob('src/common/*.c'))
+
 notification_provider_src = [
-       env.Glob('src/provider/*.c'), env.Glob('src/common/*.c')]
+       env.Glob('src/provider/*.c'), notification_common_obj]
 notification_consumer_src = [
-       env.Glob('src/consumer/*.c'), env.Glob('src/common/*.c')]
+       env.Glob('src/consumer/*.c'), notification_common_obj]
 
 if target_os not in ['ios']:
-       providersdk = notification_provider_env.SharedLibrary('notification_provider', notification_provider_src)
-       notification_provider_env.InstallTarget(providersdk, 'libnotification_provider')
-       notification_provider_env.UserInstallTargetLib(providersdk, 'libnotification_provider')
-       consumersdk = notification_consumer_env.SharedLibrary('notification_consumer', notification_consumer_src)
-       notification_consumer_env.InstallTarget(consumersdk, 'libnotification_consumer')
-       notification_consumer_env.UserInstallTargetLib(consumersdk, 'libnotification_consumer')
+    providersdk = notification_provider_env.SharedLibrary('notification_provider', notification_provider_src)
+    notification_provider_env.InstallTarget(providersdk, 'libnotification_provider')
+    notification_provider_env.UserInstallTargetLib(providersdk, 'libnotification_provider')
+    consumersdk = notification_consumer_env.SharedLibrary('notification_consumer', notification_consumer_src)
+    notification_consumer_env.InstallTarget(consumersdk, 'libnotification_consumer')
+    notification_consumer_env.UserInstallTargetLib(consumersdk, 'libnotification_consumer')
 
 providersdk = notification_provider_env.StaticLibrary('notification_provider', notification_provider_src)
 notification_provider_env.InstallTarget(providersdk, 'libnotification_provider')
@@ -138,4 +158,4 @@ if target_os == 'android':
     SConscript('android/SConscript')
 
 # Go to build sample apps
-SConscript('examples/SConscript')
+#SConscript('examples/SConscript')
index 7a52422..09f14ff 100755 (executable)
@@ -57,7 +57,7 @@ jdk_env['BUILDERS']['Gradle'] = Builder(action = env.get('ANDROID_GRADLE') +
 jdk_env['BUILD_DIR'] = env.get('BUILD_DIR')
 cmdBuildNotification = jdk_env.Gradle(target="notification-service/objs",
     source="notification-service/src/main/java/org/iotivity/service/ns/consumer/ConsumerService.java")
-
+jdk_env.Clean(cmdBuildNotification, './build')
 Depends(cmdBuildNotification, env.get('baseAAR'))
 
 env.AppendUnique(notificationAAR = cmdBuildNotification)
index df5318f..4766ff0 100755 (executable)
@@ -23,28 +23,26 @@ package org.iotivity.service.ns.common;
 import android.util.Log;
 
 /**
-  * @class   MediaContents
 * @brief   This class provides implementation of Notification MediaContents object.
-  */
-public class MediaContents
-{
-    private static final String LOG_TAG = "NotificationService_MediaContents";
-
-    public String mIconImage = null;
-
-    public MediaContents(String iconImage)
-    {
-        Log.i (LOG_TAG, "MediaContents()");
+ *
* This class provides implementation of Notification MediaContents object.
+ *
+ */
+public class MediaContents {
+
+    private static final String LOG_TAG    = "NotificationService_MediaContents";
+
+    private String               mIconImage = null;
+
+    public MediaContents(String iconImage) {
+        Log.i(LOG_TAG, "MediaContents()");
         mIconImage = iconImage;
     }
 
-    public String getIconImage()
-    {
+    public String getIconImage() {
         return mIconImage;
     }
 
-    public void setIconImage(String iconImage)
-    {
+    public void setIconImage(String iconImage) {
         mIconImage = iconImage;
     }
 }
index f2f2057..fb19713 100755 (executable)
@@ -24,153 +24,133 @@ import android.util.Log;
 import org.iotivity.base.OcRepresentation;
 
 /**
-  * @class   Message
-  * @brief   This class provides implementation of Notification Message object.
-  */
-public class Message
-{
+ *
+ * This class provides implementation of Notification Message object.
+ *
+ */
+public class Message {
+
     private static final String LOG_TAG = "NotificationService_Message";
 
-    public enum MessageType
-    {
+    /**
+     * This enum is used to represent different types of notification messages
+     */
+    public enum MessageType {
         ALERT(1),
         NOTICE(2),
         EVENT(3),
         INFO(4),
         WARNING(5);
+
         private int type;
 
-        private MessageType(int type)
-        {
+        private MessageType(int type) {
             this.type = type;
         }
 
-        public int getMessageType()
-        {
+        public int getMessageType() {
             return this.type;
         }
     };
-    public long mMessageId                     = 0;
-    public String mProviderId                  = null;
 
-    public String mSourceName                  = null;
-    public MessageType mType                   = MessageType.ALERT;
-    public String mTime                        = null;
-    public long mTTL                           = 0;
-    public String mTitle                       = null;
-    public String mContentText                 = null;
-    public MediaContents mMediaContents        = null;
-    public String mTopic                       = null;
-    public OcRepresentation mExtraInfo         = null;
+    private long             mMessageId     = 0;
+    private String           mProviderId    = null;
 
-    private long mNativeHandle                 = 0;
+    private String           mSourceName    = null;
+    private MessageType      mType          = MessageType.ALERT;
+    private String           mTime          = null;
+    private long             mTTL           = 0;
+    private String           mTitle         = null;
+    private String           mContentText   = null;
+    private MediaContents    mMediaContents = null;
+    private String           mTopic         = null;
+    private OcRepresentation mExtraInfo     = null;
 
-    public Message(String title, String contentText, String sourceName)
-    {
-        Log.i (LOG_TAG, "Message()");
+    public Message(String title, String contentText, String sourceName) {
+        Log.i(LOG_TAG, "Message()");
 
         mTitle = title;
         mContentText = contentText;
         mSourceName = sourceName;
     }
 
-    public long getMessageId()
-    {
+    public long getMessageId() {
         return mMessageId;
     }
 
-    public String getProviderId()
-    {
+    public String getProviderId() {
         return mProviderId;
     }
 
-    public String getSourceName ()
-    {
+    public String getSourceName() {
         return mSourceName;
     }
 
-    public MessageType getType()
-    {
+    public MessageType getType() {
         return mType;
     }
 
-    public String getTime()
-    {
+    public String getTime() {
         return mTime;
     }
 
-    public long getTTL()
-    {
+    public long getTTL() {
         return mTTL;
     }
 
-    public String getTitle()
-    {
+    public String getTitle() {
         return mTitle;
     }
 
-    public String getContentText()
-    {
+    public String getContentText() {
         return mContentText;
     }
 
-    public MediaContents getMediaContents()
-    {
+    public MediaContents getMediaContents() {
         return mMediaContents;
     }
 
-    public String getTopic()
-    {
+    public String getTopic() {
         return mTopic;
     }
 
-    public OcRepresentation getExtraInfo()
-    {
+    public OcRepresentation getExtraInfo() {
         return mExtraInfo;
     }
 
-    public void setSourceName (String sourceName)
-    {
+    public void setSourceName(String sourceName) {
         mSourceName = sourceName;
     }
 
-    public void setType(MessageType type)
-    {
+    public void setType(MessageType type) {
         mType = type;
     }
 
-    public void setTime(String time)
-    {
+    public void setTime(String time) {
         mTime = time;
     }
 
-    public void setTTL(long ttl)
-    {
+    public void setTTL(long ttl) {
         mTTL = ttl;
     }
 
-    public void setTitle(String title)
-    {
+    public void setTitle(String title) {
         mTitle = title;
     }
 
-    public void setContentText(String contextText)
-    {
+    public void setContentText(String contextText) {
         mContentText = contextText;
     }
 
-    public void setMediaContents(MediaContents mediaContents)
-    {
+    public void setMediaContents(MediaContents mediaContents) {
         mMediaContents = mediaContents;
     }
 
-    public void setTopic(String topic)
-    {
+    public void setTopic(String topic) {
         mTopic = topic;
     }
 
-    public void setExtraInfo(OcRepresentation extraInfo)
-    {
+    public void setExtraInfo(OcRepresentation extraInfo) {
         mExtraInfo = extraInfo;
     }
 }
index ee73d6c..ef2c50d 100755 (executable)
 
 package org.iotivity.service.ns.common;
 
-public enum NSErrorCode
-{
+/**
+ *
+ * This enum provides details of error code messages thrown in NSException.
+ *
+ */
+public enum NSErrorCode {
     OK("OK", ""),
     ERROR("ERROR", ""),
     SUCCESS("SUCCESS", ""),
@@ -29,43 +33,37 @@ public enum NSErrorCode
     ALLOW("ALLOW", ""),
     DENY("DENY", ""),
     JNI_EXCEPTION("JNI_EXCEPTION", "Generic Java binder error"),
-    JNI_NO_NATIVE_OBJECT("JNI_NO_NATIVE_OBJECT", ""),
-    JNI_INVALID_VALUE("JNI_INVALID_VALUE", ""),;
+    JNI_NO_NATIVE_OBJECT("JNI_NO_NATIVE_POINTER", ""),
+    JNI_INVALID_VALUE("JNI_INVALID_VALUE", ""),
+    NATIVE_EXCEPTION("NATIVE_EXCEPTION", "");
 
     private String error;
     private String description;
 
-    private NSErrorCode(String error, String description)
-{
-    this.error = error;
-    this.description = description;
-}
+    private NSErrorCode(String error, String description) {
+        this.error = error;
+        this.description = description;
+    }
 
-public String getError()
-{
-    return error;
-}
+    public String getError() {
+        return error;
+    }
 
-public String getDescription()
-{
-    return description;
-}
+    public String getDescription() {
+        return description;
+    }
 
-public static NSErrorCode get(String errorCode)
-{
-    for (NSErrorCode eCode : NSErrorCode.values())
-    {
-        if (eCode.getError().equals(errorCode))
-        {
-            return eCode;
+    public static NSErrorCode get(String errorCode) {
+        for (NSErrorCode eCode : NSErrorCode.values()) {
+            if (eCode.getError().equals(errorCode)) {
+                return eCode;
+            }
         }
+        throw new IllegalArgumentException("Unexpected NSErrorCode value");
     }
-    throw new IllegalArgumentException("Unexpected NSErrorCode value");
-}
 
-@Override
-public String toString()
-{
-    return error + (description.isEmpty() ? "" : " : " + description);
+    @Override
+    public String toString() {
+        return error + (description.isEmpty() ? "" : " : " + description);
+    }
 }
-}
\ No newline at end of file
index b6b7649..6b639f5 100755 (executable)
 
 package org.iotivity.service.ns.common;
 
-public class NSException extends Exception
-{
+/**
+ *
+ * This class provides implementation of exceptions thrown by API's.
+ *
+ */
+public class NSException extends Exception {
+
     private NSErrorCode errorCode;
 
-    public NSException(NSErrorCode errorCode, String errMessage)
-    {
+    public NSException(NSErrorCode errorCode, String errMessage) {
         super(errMessage + " " + errorCode.toString());
         this.errorCode = errorCode;
     }
 
-    private NSException(String error, String errMessage)
-    {
+    private NSException(String error, String errMessage) {
         super(errMessage + " " + error);
         this.errorCode = NSErrorCode.get(error);
     }
 
-    public NSErrorCode getErrorCode()
-    {
+    public NSErrorCode getErrorCode() {
         return errorCode;
     }
 
-    private static void addStackTrace(Throwable throwable,
-                                      String file,
-                                      String functionName,
-                                      int line)
-    {
+    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("<native>", functionName, file, line);
+        newStack[0] = new StackTraceElement("<native>", functionName, file,
+                line);
         throwable.setStackTrace(newStack);
     }
 
-    private void setNativeExceptionLocation(String file, String functionName, int line)
-    {
+    private void setNativeExceptionLocation(String file, String functionName,
+            int line) {
         NSException.addStackTrace(this, file, functionName, line);
     }
 }
\ No newline at end of file
index f0b55bb..aa94b65 100755 (executable)
@@ -23,55 +23,54 @@ package org.iotivity.service.ns.common;
 import android.util.Log;
 
 /**
-  * @class   SyncInfo
-  * @brief   This class provides implementation of Notification SyncInfo object.
-  */
-public class SyncInfo
-{
+ *
+ * This class provides implementation of Notification SyncInfo object.
+ *
+ */
+public class SyncInfo {
+
     private static final String LOG_TAG = "NotificationService_SyncInfo";
 
-    public enum SyncType
-    {
+    /**
+     * This enum is used to inform about read status of notification message
+     */
+    public enum SyncType {
         UNREAD(0),
         READ(1),
         DELETED(2);
+
         private int type;
 
-    private SyncType(int type)
-    {
-        this.type = type;
-    }
+        private SyncType(int type) {
+            this.type = type;
+        }
 
-    public int getSyncType()
-    {
-        return this.type;
-    }
+        public int getSyncType() {
+            return this.type;
+        }
     };
-    public long mMessageId              = 0;
-    public String mProviderId           = null;
-    public SyncType mState              = SyncType.UNREAD;
 
-    public SyncInfo(long messageId, String providerId, SyncType state)
-    {
-        Log.i (LOG_TAG, "SyncInfo()");
+    private long     mMessageId  = 0;
+    private String   mProviderId = null;
+    private SyncType mState      = SyncType.UNREAD;
+
+    public SyncInfo(long messageId, String providerId, SyncType state) {
+        Log.i(LOG_TAG, "SyncInfo()");
 
         mMessageId = messageId;
         mProviderId = providerId;
         mState = state;
     }
 
-    public long getMessageId()
-    {
+    public long getMessageId() {
         return mMessageId;
     }
 
-    public String getProviderId()
-    {
+    public String getProviderId() {
         return mProviderId;
     }
 
-    public SyncType getState()
-    {
+    public SyncType getState() {
         return mState;
     }
 }
index 2ac3556..e949d2c 100644 (file)
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
 package org.iotivity.service.ns.common;
+
 import android.util.Log;
+
 /**
-  * @class   Topic
-  * @brief   This class provides implementation of Notification Topic object.
-  */
-public class Topic
-{
+ *
+ * This class provides implementation of Notification Topic object.
+ *
+ */
+public class Topic {
+
     private static final String LOG_TAG = "NotificationService_Topic";
 
-    public enum TopicState
-    {
-        UNSUBSCRIBED (0),
-        SUBSCRIBED (1);
+    /**
+     * This enum is used to represent subscribtion status for this Topic
+     * resource
+     */
+    public enum TopicState {
+        UNSUBSCRIBED(0),
+        SUBSCRIBED(1);
+
         private int type;
 
-        private TopicState(int type)
-        {
+        private TopicState(int type) {
             this.type = type;
         }
 
-        public int getTopicState()
-        {
+        public int getTopicState() {
             return this.type;
         }
 
     };
-    public String mTopicName    = null;
-    public TopicState mState    = TopicState.UNSUBSCRIBED;
 
-    public Topic(String topicName, TopicState state)
-    {
-        Log.i (LOG_TAG, "Topic()");
+    private String     mTopicName = null;
+    private TopicState mState     = TopicState.UNSUBSCRIBED;
+
+    public Topic(String topicName, TopicState state) {
+        Log.i(LOG_TAG, "Topic()");
 
         mTopicName = topicName;
         mState = state;
     }
 
-    public String getTopicName()
-    {
+    public String getTopicName() {
         return mTopicName;
     }
 
-    public void setTopicName(String topicName)
-    {
+    public void setTopicName(String topicName) {
         mTopicName = topicName;
     }
 
-    public TopicState getState()
-    {
+    public TopicState getState() {
         return mState;
     }
 
-    public void setState(TopicState state)
-    {
+    public void setState(TopicState state) {
         mState = state;
     }
 
index 8572ccc..62c288e 100644 (file)
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
 package org.iotivity.service.ns.common;
+
 import android.util.Log;
 import java.util.Vector;
 import java.util.Iterator;
+
 /**
-  * @class   TopicsList
-  * @brief   This class provides implementation of Topics List
-  */
-public class TopicsList
-{
-    private static final String LOG_TAG = "NotificationService_TopicList";
-
-    public Vector<Topic> mTopicsList = new  Vector<Topic>();
-
-    public void addTopic(String topicname, Topic.TopicState state)
-    {
-        mTopicsList.add(new Topic(topicname,state));
+ *
+ * This class provides implementation of Topics List.
+ *
+ */
+public class TopicsList {
+
+    private static final String LOG_TAG     = "NotificationService_TopicList";
+
+    private Vector<Topic>        mTopicsList = new Vector<Topic>();
+
+    public void addTopic(String topicname, Topic.TopicState state) {
+        mTopicsList.add(new Topic(topicname, state));
     }
 
-    public void removeTopic(String topicName)
-    {
-        Iterator <Topic> it = getTopicsList().iterator();
-        while(it.hasNext())
-        {
+    public void removeTopic(String topicName) {
+        Iterator<Topic> it = getTopicsList().iterator();
+        while (it.hasNext()) {
             Topic element = it.next();
-            if(element.getTopicName().equals(topicName))
-            {
+            if (element.getTopicName().equals(topicName)) {
                 mTopicsList.remove(element);
             }
         }
     }
 
-    public Vector<Topic>  getTopicsList()
-    {
+    public Vector<Topic> getTopicsList() {
         return mTopicsList;
     }
 
 }
-
index 58bf57a..50e4980 100755 (executable)
@@ -25,15 +25,15 @@ import org.iotivity.service.ns.common.*;
 import java.util.Vector;
 
 /**
-  * @class   ConsumerService
-  * @brief   This class provides a set of Java APIs for Notification Consumer.
-  */
-public class ConsumerService
-{
+ *
+ * This class provides a set of Java APIs for Notification ConsumerService.
+ *
+ */
+public class ConsumerService {
+
     private static final String LOG_TAG = "ConsumerService";
 
-    static
-    {
+    static {
         System.loadLibrary("gnustl_shared");
         System.loadLibrary("oc_logger");
         System.loadLibrary("connectivity_abstraction");
@@ -47,74 +47,99 @@ public class ConsumerService
     }
 
     private static ConsumerService instance;
-    static
-    {
+    static {
         instance = new ConsumerService();
     }
 
     /**
-      * API for getting instance of ConsumerService
-      * @return ConsumerService singleton instance created
-      */
-    public static ConsumerService getInstance()
-    {
+     * API for getting instance of ConsumerService
+     *
+     * @return ConsumerService singleton instance created
+     */
+    public static ConsumerService getInstance() {
         return instance;
     }
 
-   /**
-     * Start ConsumerService
-     * @param onProviderDiscoveredListener - OnProviderDiscoveredListener Callback Interface
+    /**
+     * This API will Start ConsumerService
+     *
+     * @param onProviderDiscoveredListener
+     *            OnProviderDiscoveredListener Callback Interface
+     *
+     * @throws NSException
+     *             if the parameter passed is null
      */
-    public void start(
-        OnProviderDiscoveredListener onProviderDiscoveredListener
-    ) throws NSException
-    {
+    public void start(OnProviderDiscoveredListener onProviderDiscoveredListener)
+            throws NSException {
         nativeStart(onProviderDiscoveredListener);
     }
 
     /**
-      * Stop ConsumerService
-      */
-    public void stop() throws NSException
-    {
+     * This API will Stop ConsumerService
+     */
+    public void stop() throws NSException {
         nativeStop();
     }
 
     /**
-      * Request to publish resource to cloud server
-      * @param[in]  serverAddress combined with IP address and port number using delimiter :
-      * @return  result code
-      */
-    public void enableRemoteService(String serverAddress) throws NSException
-    {
+     * Request to publish resource to cloud server
+     *
+     * @param serverAddress
+     *            serverAddress combined with IP address and port number using
+     *            delimiter
+     */
+    public void enableRemoteService(String serverAddress) throws NSException {
         nativeEnableRemoteService(serverAddress);
     }
 
     /**
-      * Request discovery manually
-      */
-    public void rescanProvider() throws NSException
-    {
+     * Request to subscribe to MQ server
+     *
+     * @param servAdd
+     *            servAdd combined with IP address and port number and MQ broker
+     *            uri using delimiter
+     * @param topicName
+     *            the interest Topic name for subscription
+     *
+     * @throws NSException failed to subscribe to MQ server
+     */
+    public void subscribeMQService(String servAdd, String topicName)
+            throws NSException {
+        nativeSubscribeMQService(servAdd, topicName);
+    }
+
+    /**
+     * This API is called to request discovery manually
+     */
+    public void rescanProvider() throws NSException {
         nativeRescanProvider();
     }
 
     /**
-      * Interface to implement callback function to receive provider on discovery
-      */
-    public interface OnProviderDiscoveredListener
-    {
+     * Interface to implement callback function to receive provider on discovery
+     */
+    public interface OnProviderDiscoveredListener {
+
         /**
-          * Callback function to receive provider on discovery
-          * @param provider - Provider object
-          */
+         * Callback function to receive provider on discovery
+         *
+         * @param provider
+         *            Provider object
+         */
         public void onProviderDiscovered(Provider provider);
     }
 
-    private native void nativeStart (
-        OnProviderDiscoveredListener onProviderDiscoveredListener
-    ) throws NSException;
+    private native void nativeStart(
+            OnProviderDiscoveredListener onProviderDiscoveredListener)
+            throws NSException;
 
     private native void nativeStop() throws NSException;
-    private native void nativeEnableRemoteService(String serverAddress) throws NSException;
+
+    private native void nativeEnableRemoteService(String serverAddress)
+            throws NSException;
+
+    private native void nativeSubscribeMQService(String servAdd,
+            String topicName) throws NSException;
+
     private native void nativeRescanProvider() throws NSException;
 }
index 3dda268..3a40293 100755 (executable)
@@ -25,169 +25,229 @@ import org.iotivity.service.ns.common.*;
 import java.util.Vector;
 
 /**
-  * @class   Provider
-  * @brief   This class provides implementation of Notification Provider object.
-  */
-public class Provider
-{
+ *
+ * This class provides implementation of Notification Provider object.
+ *
+ */
+public class Provider {
+
     private static final String LOG_TAG = "ConsumerService_Provider";
 
     /**
-      * ProviderState of Notification resource
-      */
-    public enum ProviderState
-    {
+     * Enum for defining different state of provider object
+     */
+    public enum ProviderState {
         ALLOW(1),
         DENY(2),
         TOPIC(3),
         STOPPED(12);
+
         private int state;
 
-        private ProviderState(int state)
-        {
+        private ProviderState(int state) {
             this.state = state;
         }
 
-        public int getProviderState()
-        {
+        public int getProviderState() {
             return this.state;
         }
     };
 
-    public String mProviderId        = null;
-    private long mNativeHandle       = 0;
+    private String mProviderId   = null;
+    private long  mNativeHandle = 0;
 
     /**
-      * Constructor of Provider.
-      * @param providerId - providerId of Provider.
-      */
-    public Provider(String providerId)
-    {
-        Log.i (LOG_TAG, "Provider()");
+     * Constructor of Provider.
+     *
+     * @param providerId
+     *            unique Id of Provider
+     */
+    public Provider(String providerId) {
+        Log.i(LOG_TAG, "Provider()");
 
         mProviderId = providerId;
     }
 
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            nativeDispose();
+        } catch (Throwable t) {
+            throw t;
+        } finally {
+            super.finalize();
+        }
+    }
     /**
-      * API for getting providerId.
-      * @return ConsumerId as string.
-      */
-    public String getProviderId()
-    {
-        return mProviderId ;
+     * API for getting providerId
+     *
+     * @return ConsumerId as string
+     */
+    public String getProviderId() {
+        return mProviderId;
     }
 
     /**
-      * API for getting for getting Topic List.
-      * @return TopicsList.
-      */
-    public TopicsList getTopicList() throws NSException
-    {
+     * API for getting for getting Topic List
+     *
+     * @return TopicsList
+     */
+    public TopicsList getTopicList() throws NSException {
         return nativeGetTopicList();
     }
 
     /**
-      * API for getting for getting ProviderState.
-      * @return ProviderState.
-      */
-    public ProviderState getProviderState() throws NSException
-    {
+     * API for getting for getting ProviderState
+     *
+     * @return ProviderState
+     */
+    public ProviderState getProviderState() throws NSException {
         return nativeGetProviderState();
     }
 
     /**
-      * API for for requesting subscription of Notification service.
-      */
-    public void subscribe() throws NSException
-    {
+     * API for requesting subscription of Notification service
+     * This API should be called with a valid Provider object obtained from Discovery callback.
+     * The API should not be called when the Provider is in STOPPED state.
+     *
+     * Discovery APIs to discover Providers are as below.
+     * Start/rescanProvider for D2D,
+     * enableRemoteService for D2S,
+     *
+     * @throws NSException failure to subscribe
+     */
+    public void subscribe() throws NSException {
         nativeSubscribe();
     }
 
     /**
-      * API for for requesting subscription status from Provider of Notification service.
-      */
-    public boolean isSubscribed () throws NSException
-    {
+     * API for requesting unsubscription of Notification service
+     *
+     * This API should be called with a valid Provider object obtained from Discovery callback.
+     * The API should not be called when the Provider is in STOPPED state.
+     *
+     * @throws NSException failure to subscribe
+     */
+    public void unsubscribe() throws NSException {
+        nativeUnsubscribe();
+    }
+
+    /**
+     * API for requesting subscription status from Provider of Notification
+     * service
+     */
+    public boolean isSubscribed() throws NSException {
         return nativeIsSubscribed();
     }
 
     /**
-      * This method is for Sending SyncInfo of Notification service.
-      * @param messageId - id of  message.
-      * @param syncType - SyncType of Notification service.
-      */
-    public void sendSyncInfo(long messageId, SyncInfo.SyncType syncType) throws NSException
-    {
+     * This method is for Sending SyncInfo of Notification service.
+     *
+     * @param messageId
+     *            unique Id of message
+     * @param syncType
+     *            SyncType of Notification service
+     */
+    public void sendSyncInfo(long messageId, SyncInfo.SyncType syncType)
+            throws NSException {
         nativeSendSyncInfo(messageId, syncType.ordinal());
     }
 
     /**
-      * This method is for registering for listeners of Notification .
-      * @param onProviderStateListener - OnProviderStateListener callback Interface.
-      * @param onMessageReceivedListner - OnMessageReceivedListner callback Interface.
-      * @param onSyncInfoReceivedListner - OnSyncInfoReceivedListner callback Interface.
-      */
+     * This method is for registering for listeners of Notification .
+     *
+     * @param onProviderStateListener
+     *            OnProviderStateListener callback Interface
+     * @param onMessageReceivedListner
+     *            OnMessageReceivedListner callback Interface
+     * @param onSyncInfoReceivedListner
+     *            OnSyncInfoReceivedListner callback Interface
+     */
     public void setListener(OnProviderStateListener onProviderStateListener,
-                            OnMessageReceivedListner onMessageReceivedListner,
-                            OnSyncInfoReceivedListner onSyncInfoReceivedListner) throws NSException
-    {
-        nativeSetListener(onProviderStateListener, onMessageReceivedListner, onSyncInfoReceivedListner);
+            OnMessageReceivedListener onMessageReceivedListener,
+            OnSyncInfoReceivedListener onSyncInfoReceivedListener)
+            throws NSException {
+        nativeSetListener(onProviderStateListener, onMessageReceivedListener,
+                onSyncInfoReceivedListener);
     }
 
     /**
-      * Update Topic list that is wanted to be subscribed from provider
-      * @param topicsList - TopicsList of interested Topics.
-      * @return :: result code  100 = OK , 200 = ERROR , 300 = SUCCESS , 400 = FAIL
-      */
-    public int updateTopicList(TopicsList topicsList) throws NSException
-    {
-        return nativeUpdateTopicList(topicsList);
+     * Update Topic list that is wanted to be subscribed from provider
+     *
+     * @param topicsList
+     *            TopicsList of interested Topics
+     *
+     * @throws NSException failure to update topic list. 
+     */
+    public void updateTopicList(TopicsList topicsList) throws NSException {
+        nativeUpdateTopicList(topicsList);
     }
 
     /**
-      * Interface to implement callback function to receive provider state information
-      */
-    public interface OnProviderStateListener
-    {
+     * Interface to implement callback function to receive provider state
+     * information
+     */
+    public interface OnProviderStateListener {
+
         /**
-          * Callback function to receive provider state information
-          * @param state - ProviderState
-          */
+         * Callback function to receive provider state information
+         *
+         * @param state
+         *            ProviderState
+         */
         public void onProviderStateReceived(ProviderState state);
     }
 
     /**
-      * Interface to implement callback function to receive Notification Message
-      */
-    public interface OnMessageReceivedListner
-    {
+     * Interface to implement callback function to receive Notification Message
+     */
+    public interface OnMessageReceivedListener {
+
         /**
-          * Callback function to receive Notification Message
-          * @param message - Notification Message
-          */
+         * Callback function to receive Notification Message.
+         *
+         * @param message
+         *            Notification Message
+         */
         public void onMessageReceived(Message message);
     }
 
     /**
-      * Interface to implement callback function to receive message read synchronization
-      */
-    public interface OnSyncInfoReceivedListner
-    {
+     * Interface to implement callback function to receive message read
+     * synchronization
+     */
+    public interface OnSyncInfoReceivedListener {
+
         /**
-          * Callback function to receive message read synchronization
-          * @param sync - SyncInfo
-          */
+         * Callback function to receive message read synchronization
+         *
+         * @param sync
+         *            SyncInfo
+         */
         public void onSyncInfoReceived(SyncInfo sync);
     }
 
     private native void nativeSubscribe() throws NSException;
-    private native void nativeSendSyncInfo(long messageId, int syncType) throws NSException;
-    private native void nativeSetListener(OnProviderStateListener onProviderStateListener,
-                                      OnMessageReceivedListner onMessageReceivedListner,
-                                      OnSyncInfoReceivedListner onSyncInfoReceivedListner) throws NSException;
-    public native TopicsList  nativeGetTopicList() throws NSException;
-    private native int nativeUpdateTopicList(TopicsList topicsList) throws NSException;
+    private native void nativeUnsubscribe() throws NSException;
+
+    private native void nativeSendSyncInfo(long messageId, int syncType)
+            throws NSException;
+
+    private native void nativeSetListener(
+            OnProviderStateListener onProviderStateListener,
+            OnMessageReceivedListener onMessageReceivedListener,
+            OnSyncInfoReceivedListener onSyncInfoReceivedListener)
+            throws NSException;
+
+    private native TopicsList nativeGetTopicList() throws NSException;
+
+    private native void nativeUpdateTopicList(TopicsList topicsList)
+            throws NSException;
+
     private native ProviderState nativeGetProviderState() throws NSException;
-    public native boolean  nativeIsSubscribed() throws NSException;
+
+    private native boolean nativeIsSubscribed() throws NSException;
+
+    private native void nativeDispose();
 
 }
old mode 100644 (file)
new mode 100755 (executable)
index 5abf280..64210c4
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 package org.iotivity.service.ns.provider;
+
 import org.iotivity.service.ns.common.*;
 import java.util.Vector;
+
 /**
-  * @class   Consumer
 * @brief   This class provides implementation of Notification Consumer object.
-  */
-public class Consumer
-{
+ *
* This class provides implementation of Notification Consumer object.
+ *
+ */
+public class Consumer {
 
-    public String mConsumerId = null;
+    private String mConsumerId = null;
 
     /**
-      * Constructor of Consumer.
-      */
-    public Consumer(final String consumerId)
-    {
+     * Constructor of Consumer
+     */
+    public Consumer(final String consumerId) {
         mConsumerId = consumerId;
     }
 
     /**
-      * API for getting consumerId
-      * @return ConsumerId as string
-      */
-    public String getConsumerId( )
-    {
+     * API for getting consumerId
+     *
+     * @return ConsumerId as string
+     */
+    public String getConsumerId() {
         return mConsumerId;
     }
 
     /**
-      * API for accepting Subscription request.
-      * This function is valid only when subControllability is set true.
-      * @param accepted - boolean variable representing Subscription response as TRUE/FALSE.
-      * @return :: result code  100 = OK , 200 = ERROR , 300 = SUCCESS , 400 = FAIL
-      */
-    public int acceptSubscription(boolean accepted) throws NSException
-    {
-        return nativeAcceptSubscription(mConsumerId, accepted);
+     * API for accepting Subscription request. This function is valid only when
+     * subControllability is set true.
+     *
+     * @param accepted
+     *            boolean variable representing Subscription response as
+     *            TRUE/FALSE.
+     *
+     * @throws NSException failure accepting subscription request
+     */
+    public void acceptSubscription(boolean accepted) throws NSException {
+        nativeAcceptSubscription(mConsumerId, accepted);
     }
 
     /**
-      * Select a topic for a consumer
-      * @param  topicName - Topic name to select
-      * @return :: result code
-      */
-    public int setTopic(String topicName) throws NSException
-    {
-        return nativeSetConsumerTopic(mConsumerId, topicName);
+     * Select a topic for a consumer
+     *
+     * @param topicName
+     *            Topic name to select
+     *
+     * @throws NSException failure selecting a topic
+     */
+    public void setTopic(String topicName) throws NSException {
+        nativeSetConsumerTopic(mConsumerId, topicName);
     }
 
     /**
-      * Unselect a topic for a consumer
-      * @param  topicName - Topic name to Unselect
-      * @return :: result code
-      */
-    public int unsetTopic(String topicName) throws NSException
-    {
-        return nativeUnsetConsumerTopic(mConsumerId, topicName);
+     * Unselect a topic for a consumer
+     *
+     * @param topicName
+     *            Topic name to Unselect
+     *
+     * @throws NSException failure unselecting topic
+     */
+    public void unsetTopic(String topicName) throws NSException {
+        nativeUnsetConsumerTopic(mConsumerId, topicName);
     }
 
     /**
-      * Request topic list with selection state for the consumer
-      * @return :: Topic list
-      */
-    public TopicsList getConsumerTopicList() throws NSException
-    {
+     * Request topic list with selection state for the consumer
+     *
+     * @return Topic list
+     */
+    public TopicsList getConsumerTopicList() throws NSException {
         return nativeGetConsumerTopicList(mConsumerId);
     }
 
-    public native int  nativeAcceptSubscription(String  consumerId, boolean accepted) throws NSException;
-    public native int  nativeSetConsumerTopic(String consumerId, String topicName) throws NSException;
-    public native int  nativeUnsetConsumerTopic(String consumerId, String topicName) throws NSException;
-    public native TopicsList  nativeGetConsumerTopicList(String consumerId) throws NSException;
-}
\ No newline at end of file
+    private native void nativeAcceptSubscription(String consumerId,
+            boolean accepted) throws NSException;
+
+    private native void nativeSetConsumerTopic(String consumerId,
+            String topicName) throws NSException;
+
+    private native void nativeUnsetConsumerTopic(String consumerId,
+            String topicName) throws NSException;
+
+    private native TopicsList nativeGetConsumerTopicList(String consumerId)
+            throws NSException;
+}
old mode 100644 (file)
new mode 100755 (executable)
index b15ba46..b7ae317
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 package org.iotivity.service.ns.provider;
+
 import org.iotivity.service.ns.common.*;
 import java.util.Vector;
+
 /**
-  * @class   ProviderService
-  * @brief   This class provides a set of Java APIs for Notification ProviderService.
-  */
-public class ProviderService
-{
-
-    static
-    {
+ *
+ * This class provides a set of Java APIs for Notification ProviderService.
+ *
+ */
+public class ProviderService {
+
+    static {
         System.loadLibrary("gnustl_shared");
         System.loadLibrary("oc_logger");
         System.loadLibrary("connectivity_abstraction");
@@ -43,166 +44,228 @@ public class ProviderService
 
     private static ProviderService instance;
 
-    static
-    {
+    static {
         instance = new ProviderService();
     }
 
     /**
-      * API for getting instance of ProviderService
-      * @return ProviderService singleton instance created
-      */
-    public static ProviderService getInstance()
-    {
+     * API for getting instance of ProviderService
+     *
+     * @return ProviderService singleton instance created
+     */
+    public static ProviderService getInstance() {
         return instance;
     }
 
     /**
-      * Start ProviderService
-      * @param subscribedListener - OnConsumerSubscribedListener Callback
-      * @param messageSynchronized - OnMessageSynchronizedListener Callback
-      * @param subControllability - Set the policy for notification servcie which checks whether
-      * provider is capable of denying the subscription of notification message from consumer and
-      * getting controllabliity to set consumer topic list.
-      * If true, provider is able to control subscription request and consumer topic list.
-      * Otherwise(policy is false), consumer can do the same.
-      * @param userInfo -  User defined information such as device friendly name
-      * @param resourceSecurity -  Set on/off for secure resource channel setting
-      * @return :: result code  100 = OK , 200 = ERROR , 300 = SUCCESS , 400 = FAIL
-      */
-    public int start(OnConsumerSubscribedListener  subscribedListener,
-                     OnMessageSynchronizedListener  messageSynchronized,
-                     boolean subControllability, String userInfo,
-                     boolean resourceSecurity) throws NSException
-    {
-        return nativeStart(subscribedListener, messageSynchronized,
-                            subControllability, userInfo, resourceSecurity);
+     * Start ProviderService
+     *
+     * @param subscribedListener
+     *            OnConsumerSubscribedListener Callback
+     * @param messageSynchronized
+     *            OnMessageSynchronizedListener Callback
+     * @param subControllability
+     *            Set the policy for notification servcie which checks whether
+     *            provider is capable of denying the subscription of
+     *            notification message from consumer and getting controllabliity
+     *            to set consumer topic list. If true, provider is able to
+     *            control subscription request and consumer topic list.
+     *            Otherwise(policy is false), consumer can do the same.
+     * @param userInfo
+     *            User defined information such as device friendly name
+     * @param resourceSecurity
+     *            Set on/off for secure resource channel setting
+     *
+     * @throws NSException
+     *             if any callback parameter passed is null
+     */
+    public void start(OnConsumerSubscribedListener subscribedListener,
+            OnMessageSynchronizedListener messageSynchronized,
+            boolean subControllability, String userInfo,
+            boolean resourceSecurity) throws NSException {
+        nativeStart(subscribedListener, messageSynchronized,
+                subControllability, userInfo, resourceSecurity);
     }
 
     /**
-      * Stop ProviderService
-      * @return :: result code
-      */
-    public int stop() throws NSException
-    {
-        return nativeStop();
+     * Stop ProviderService
+     *
+     * @throws NSException failed to stop ProviderService
+     */
+    public void stop() throws NSException {
+        nativeStop();
     }
 
     /**
-      * Send notification message to all subscribers
-      * @param  message - Notification message including id, title, contentText
-      * @return :: result code
-      */
-    public int   sendMessage(Message message) throws NSException
-    {
-        return nativeSendMessage(message);
+     * Send notification message to all subscribers
+     *
+     * @param message
+     *            Notification message including id, title, contentText
+     *
+     * @throws NSException failed to send notification message
+     */
+    public void sendMessage(Message message) throws NSException {
+        nativeSendMessage(message);
     }
 
     /**
-      * Send read-check to provider in order to synchronize notification status with other consumers
-      * @param  messageId -  ID of Notification message to synchronize the status
-      * @param  syncType - SyncType of the SyncInfo message
-      */
-    public void sendSyncInfo ( long messageId , SyncInfo.SyncType syncType) throws NSException
-    {
+     * Send read-check to provider in order to synchronize notification status
+     * with other consumers
+     *
+     * @param messageId
+     *            unique Id of Notification message to synchronize the status
+     * @param syncType
+     *            SyncType of the SyncInfo message
+     */
+    public void sendSyncInfo(long messageId, SyncInfo.SyncType syncType)
+            throws NSException {
         nativeSendSyncInfo(messageId, syncType.ordinal());
     }
 
     /**
-      * Initialize Message class, Mandatory fields which are messge id and provider(device) id are filled with.
-      * @return Message
-      */
-    public Message createMessage () throws NSException
-    {
+     * Initialize Message class, Mandatory fields which are messge id and
+     * provider(device) id are filled with
+     *
+     * @return Message
+     */
+    public Message createMessage() throws NSException {
         return nativeCreateMessage();
     }
 
     /**
-      * Request to publish resource to cloud server
-      * @param[in]  servAdd combined with IP address and port number using delimiter :
-      * @return  result code
-      */
-    public int   enableRemoteService(String servAdd) throws NSException
-    {
-        return nativeEnableRemoteService(servAdd);
+     * Request to publish resource to cloud server
+     *
+     * @param servAdd
+     *            servAdd combined with IP address and port number using
+     *            delimiter
+     *
+     * @throws NSException failed to publish resource
+     */
+    public void enableRemoteService(String servAdd) throws NSException {
+        nativeEnableRemoteService(servAdd);
+    }
+
+    /**
+     * Request to cancel remote service using cloud server
+     *
+     * @param servAdd
+     *            servAdd combined with IP address and port number using
+     *            delimiter
+     *
+     * @throws NSException failed to publish resource
+     */
+    public void disableRemoteService(String servAdd) throws NSException {
+        nativeDisableRemoteService(servAdd);
     }
 
     /**
-      * Request to cancel remote service using cloud server
-      * @param[in]  servAdd combined with IP address and port number using delimiter :
-      * @return  result code
-      */
-    public int  disableRemoteService(String servAdd) throws NSException
-    {
-        return nativeDisableRemoteService(servAdd);
+     * Request to subscribe to MQ server
+     *
+     * @param servAdd
+     *            servAdd combined with IP address and port number and MQ broker
+     *            uri using delimiter
+     * @param topicName
+     *            the interest Topic name for subscription
+     *
+     * @throws NSException failed to subscribe to MQ server
+     */
+    public void subscribeMQService(String servAdd, String topicName)
+            throws NSException {
+        nativeSubscribeMQService(servAdd, topicName);
     }
 
     /**
-      * Add topic to topic list
-      * @param  topicName - Topic name to add
-      * @return :: result code
-      */
-    public int registerTopic(String topicName) throws NSException
-    {
-        return nativeRegisterTopic(topicName);
+     * Add topic to topic list
+     *
+     * @param topicName
+     *            Topic name to add
+     *
+     * @throws NSException failed to add topic
+     */
+    public void registerTopic(String topicName) throws NSException {
+        nativeRegisterTopic(topicName);
     }
 
     /**
-      * Delete topic from topic list
-      * @param  topicName - Topic name to add
-      * @return :: result code
-      */
-    public int unregisterTopic(String topicName) throws NSException
-    {
-        return nativeUnregisterTopic(topicName);
+     * Delete topic from topic list
+     *
+     * @param topicName
+     *            Topic name to add
+     *
+     * @throws NSException failed to delete topic
+     */
+    public void unregisterTopic(String topicName) throws NSException {
+        nativeUnregisterTopic(topicName);
     }
 
     /**
-      * Request topics list already registered by provider user
-      * @return :: Topic list
-      */
-    public TopicsList getRegisteredTopicList() throws NSException
-    {
+     * Request topics list already registered by provider user
+     *
+     * @throws NSException failed to get topics list
+     */
+    public TopicsList getRegisteredTopicList() throws NSException {
         return nativeGetRegisteredTopicList();
     }
 
     /**
-      * Interface to implement callback function to receive subscription request of consumer
-      */
-    public interface OnConsumerSubscribedListener
-    {
+     * Interface to implement callback function to receive subscription request
+     * of consumer
+     */
+    public interface OnConsumerSubscribedListener {
 
         /**
-          * Callback function to receive subscription request of consumer
-          * @param consumer - Consumer who subscribes the notification message resource
-          */
+         * Callback function to receive subscription request of consumer
+         *
+         * @param consumer
+         *            Consumer who subscribes the notification message resource
+         */
         public void onConsumerSubscribed(Consumer consumer);
     }
 
     /**
-      * Interface to implement callback function to receive the status of the message synchronization
-      */
-    public interface OnMessageSynchronizedListener
-    {
+     * Interface to implement callback function to receive the status of the
+     * message synchronization
+     */
+    public interface OnMessageSynchronizedListener {
 
         /**
-          * Callback function to receive the status of the message synchronization
-          * @param syncInfo - Synchronization information of the notification message
-          */
+         * Callback function to receive the status of the message
+         * synchronization
+         *
+         * @param syncInfo
+         *            Synchronization information of the notification message
+         */
         public void onMessageSynchronized(SyncInfo syncInfo);
     }
 
-    public native int  nativeStart(OnConsumerSubscribedListener subscribedListener,
-                                                 OnMessageSynchronizedListener messageSynchronized,
-                                                 boolean subControllability, String userInfo,
-                                                 boolean resourceSecurity) throws NSException;
-    public native int  nativeStop() throws NSException;
-    public native int  nativeSendMessage(Message message) throws NSException;
-    public native void  nativeSendSyncInfo( long messageId , int type) throws NSException;
-    public native Message nativeCreateMessage() throws NSException;
-    public native int  nativeEnableRemoteService(String servAdd) throws NSException;
-    public native int  nativeDisableRemoteService(String servAdd) throws NSException;
-    public native int  nativeRegisterTopic(String topicName) throws NSException;
-    public native int  nativeUnregisterTopic(String topicName) throws NSException;
-    public native TopicsList  nativeGetRegisteredTopicList() throws NSException;
+    private native void nativeStart(
+            OnConsumerSubscribedListener subscribedListener,
+            OnMessageSynchronizedListener messageSynchronized,
+            boolean subControllability, String userInfo,
+            boolean resourceSecurity) throws NSException;
+
+    private native void nativeStop() throws NSException;
+
+    private native void nativeSendMessage(Message message) throws NSException;
+
+    private native void nativeSendSyncInfo(long messageId, int type)
+            throws NSException;
+
+    private native Message nativeCreateMessage() throws NSException;
+
+    private native void nativeEnableRemoteService(String servAdd)
+            throws NSException;
+
+    private native void nativeDisableRemoteService(String servAdd)
+            throws NSException;
+
+    private native void nativeSubscribeMQService(String servAdd, String topicName)
+            throws NSException;
+
+    private native void nativeRegisterTopic(String topicName) throws NSException;
+
+    private native void nativeUnregisterTopic(String topicName)
+            throws NSException;
+
+    private native TopicsList nativeGetRegisteredTopicList() throws NSException;
 }
index 61cfe77..7def9d8 100755 (executable)
@@ -21,6 +21,12 @@ LOCAL_SRC_FILES := $(OIC_LIB_PATH)/libocstack-jni.so
 include $(PREBUILT_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
+OIC_LIB_PATH := $(ROOT_PATH)/out/android/$(TARGET_ARCH_ABI)/$(APP_OPTIM)
+LOCAL_MODULE := res_directory
+LOCAL_SRC_FILES := $(OIC_LIB_PATH)/libresource_directory.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
 LOCAL_MODULE := notification_consumer_jni
 LOCAL_CPPFLAGS := -std=c++0x -frtti -fexceptions
 LOCAL_LDLIBS := -llog
index 5f8bea9..3be2935 100755 (executable)
@@ -48,6 +48,8 @@ static const char *NSResultToChar(const int nsresult)
             return "JNI_NO_NATIVE_POINTER";\r
         case JNI_INVALID_VALUE:\r
             return "JNI_INVALID_VALUE";\r
+        case NATIVE_EXCEPTION:\r
+            return "NATIVE_EXCEPTION";\r
         default:\r
             return "";\r
     }\r
@@ -57,6 +59,7 @@ static const char *NSResultToChar(const int nsresult)
 jobject getNSException(JNIEnv *env, const char *file, const char *functionName,\r
                        const int line, const int code, const char *message)\r
 {\r
+    NS_LOGE ("Failed : %s" , message );\r
     const char *codeChar = NSResultToChar(code);\r
     if (codeChar[0] == '\0')\r
     {\r
@@ -93,7 +96,7 @@ int NSExceptionInit(JNIEnv *env)
 {\r
     if (!env)\r
     {\r
-        LOGE ("JNIEnv is null");\r
+        NS_LOGE ("JNIEnv is null");\r
         return JNI_ERR;\r
     }\r
 \r
@@ -102,7 +105,7 @@ int NSExceptionInit(JNIEnv *env)
                                   "org/iotivity/service/ns/common/NSException");\r
     if (!localNSException)\r
     {\r
-        LOGE ("Failed to get local NSException");\r
+        NS_LOGE ("Failed to get local NSException");\r
         return JNI_ERR;\r
     }\r
     g_cls_NSException = (jclass)env->NewGlobalRef(localNSException);\r
@@ -112,7 +115,7 @@ int NSExceptionInit(JNIEnv *env)
                              "<init>", "(Ljava/lang/String;Ljava/lang/String;)V");\r
     if (!g_mid_NSException_ctor)\r
     {\r
-        LOGE ("Failed to Get MethodID");\r
+        NS_LOGE ("Failed to Get MethodID");\r
         return JNI_ERR;\r
     }\r
 \r
@@ -121,7 +124,7 @@ int NSExceptionInit(JNIEnv *env)
             "(Ljava/lang/String;Ljava/lang/String;I)V");\r
     if (!g_mid_NSException_setNativeExceptionLocation)\r
     {\r
-        LOGE ("Failed to Get MethodID");\r
+        NS_LOGE ("Failed to Get MethodID");\r
         return JNI_ERR;\r
     }\r
 \r
index 595d355..b4061ae 100755 (executable)
 \r
 #include <jni.h>\r
 #include <android/log.h>\r
+#include "JniSharedObjectHolder.h"\r
 \r
 \r
-#define  LOG_TAG    "Notification_Common"\r
+#define  NSTAG    "NotificationService_JNI"\r
 \r
 #define JNI_CURRENT_VERSION JNI_VERSION_1_6\r
 \r
+#define NS_LOGI(...) __android_log_print(ANDROID_LOG_INFO, NSTAG, __VA_ARGS__)\r
+#define NS_LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, NSTAG, __VA_ARGS__)\r
+#define NS_LOGE(...) __android_log_print(ANDROID_LOG_ERROR, NSTAG, __VA_ARGS__)\r
+\r
 #ifdef __cplusplus\r
 extern "C" {\r
 #endif\r
@@ -36,6 +41,7 @@ extern "C" {
 #define JNI_EXCEPTION 1000\r
 #define JNI_NO_NATIVE_POINTER 1001\r
 #define JNI_INVALID_VALUE 1002\r
+#define NATIVE_EXCEPTION 1003\r
 \r
 #define JNI_NS_OK 100\r
 #define JNI_NS_ERROR 200\r
@@ -58,4 +64,4 @@ int NSExceptionInit(JNIEnv *env);
 }\r
 #endif\r
 \r
-#endif // _JNI_NOTIFICATION_COMMON_H_
\ No newline at end of file
+#endif // _JNI_NOTIFICATION_COMMON_H_\r
diff --git a/service/notification/android/notification-service/src/main/jni/common/JniSharedObjectHolder.h b/service/notification/android/notification-service/src/main/jni/common/JniSharedObjectHolder.h
new file mode 100755 (executable)
index 0000000..b330e82
--- /dev/null
@@ -0,0 +1,49 @@
+/******************************************************************
+ *
+ * Copyright 2017 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 JNI_SHARED_OBJECT_HOLDER_H_
+#define JNI_SHARED_OBJECT_HOLDER_H_
+
+#include <memory>
+
+template <typename T>
+class JniSharedObjectHolder
+{
+    public:
+        std::shared_ptr<T> get()
+        {
+            return m_sharedObject;
+        }
+
+        static JniSharedObjectHolder *create(std::shared_ptr<T> &sharedObject)
+        {
+            return new JniSharedObjectHolder(sharedObject);
+        }
+
+    private:
+        JniSharedObjectHolder(std::shared_ptr<T> &sharedObject)
+        {
+            m_sharedObject = sharedObject;
+        }
+
+        std::shared_ptr<T> m_sharedObject;
+};
+
+#endif
index ad4a123..7abe708 100755 (executable)
@@ -20,6 +20,7 @@
 \r
 #include "JniNotificationConsumer.h"\r
 #include "NSConsumerService.h"\r
+#include "NSException.h"\r
 #include "JniOcRepresentation.h"\r
 \r
 static JavaVM *g_jvm_consumer = NULL;\r
@@ -54,7 +55,7 @@ static JNIEnv *GetJNIEnv(jint *ret)
         case JNI_EDETACHED:\r
             if (g_jvm_consumer->AttachCurrentThread(&env, NULL) != JNI_OK)\r
             {\r
-                LOGE ("Failed to get the environment");\r
+                NS_LOGE ("Failed to get the environment");\r
                 return NULL;\r
             }\r
             else\r
@@ -62,99 +63,116 @@ static JNIEnv *GetJNIEnv(jint *ret)
                 return env;\r
             }\r
         case JNI_EVERSION:\r
-            LOGE ("JNI version is not supported");\r
+            NS_LOGE ("JNI version is not supported");\r
+            return NULL;\r
         default:\r
-            LOGE ("Failed to get the environment");\r
+            NS_LOGE ("Failed to get the environment");\r
             return NULL;\r
     }\r
 }\r
 \r
 jobject getJavaProviderState(JNIEnv *env, OIC::Service::NSProviderState state)\r
 {\r
-    LOGD ("ConsumerService_getJavaProviderState - IN");\r
+    NS_LOGD ("ConsumerService_getJavaProviderState - IN");\r
+    jobject providerState = NULL;\r
     switch (state)\r
     {\r
         case OIC::Service::NSProviderState::ALLOW:\r
             {\r
                 static jfieldID fieldID = env->GetStaticFieldID(g_cls_ProviderState,\r
                                           "ALLOW", "Lorg/iotivity/service/ns/consumer/Provider$ProviderState;");\r
-                return env->GetStaticObjectField(g_cls_ProviderState, fieldID);\r
+                providerState = env->GetStaticObjectField(g_cls_ProviderState, fieldID);\r
+                break;\r
             }\r
         case OIC::Service::NSProviderState::DENY:\r
             {\r
                 static jfieldID fieldID = env->GetStaticFieldID(g_cls_ProviderState,\r
                                           "DENY", "Lorg/iotivity/service/ns/consumer/Provider$ProviderState;");\r
-                return env->GetStaticObjectField(g_cls_ProviderState, fieldID);\r
+                providerState = env->GetStaticObjectField(g_cls_ProviderState, fieldID);\r
+                break;\r
             }\r
         case OIC::Service::NSProviderState::TOPIC:\r
             {\r
                 static jfieldID fieldID = env->GetStaticFieldID(g_cls_ProviderState,\r
                                           "TOPIC", "Lorg/iotivity/service/ns/consumer/Provider$ProviderState;");\r
-                return env->GetStaticObjectField(g_cls_ProviderState, fieldID);\r
+                providerState = env->GetStaticObjectField(g_cls_ProviderState, fieldID);\r
+                break;\r
             }\r
         case OIC::Service::NSProviderState::STOPPED:\r
             {\r
                 static jfieldID fieldID = env->GetStaticFieldID(g_cls_ProviderState,\r
                                           "STOPPED", "Lorg/iotivity/service/ns/consumer/Provider$ProviderState;");\r
-                return env->GetStaticObjectField(g_cls_ProviderState, fieldID);\r
+                providerState = env->GetStaticObjectField(g_cls_ProviderState, fieldID);\r
+                break;\r
             }\r
         default:\r
-            return NULL;\r
+            {\r
+                providerState = NULL;\r
+                break;\r
+            }\r
     }\r
-    LOGD ("ConsumerService_getJavaProviderState - OUT");\r
-    return NULL;\r
+    NS_LOGD ("ConsumerService_getJavaProviderState - OUT");\r
+    return providerState;\r
 }\r
 \r
 jobject getJavaSyncType(JNIEnv *env, OIC::Service::NSSyncInfo::NSSyncType nsType)\r
 {\r
-    LOGD ("ConsumerService_getJavaSyncType - IN");\r
+    NS_LOGD ("ConsumerService_getJavaSyncType - IN");\r
 \r
     // SyncType\r
     jclass cls_SyncType = (jclass) (env->NewLocalRef(g_cls_SyncType));\r
     if (!cls_SyncType)\r
     {\r
-        LOGE ("Failed to Get ObjectClass for SyncType");\r
+        NS_LOGE ("Failed to Get ObjectClass for SyncType");\r
         return NULL;\r
     }\r
+    jobject syncType = NULL;\r
     switch (nsType)\r
     {\r
         case OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_UNREAD:\r
             {\r
                 static jfieldID fieldID = env->GetStaticFieldID(cls_SyncType,\r
                                           "UNREAD", "Lorg/iotivity/service/ns/common/SyncInfo$SyncType;");\r
-                return env->GetStaticObjectField(cls_SyncType, fieldID);\r
+                syncType = env->GetStaticObjectField(cls_SyncType, fieldID);\r
+                break;\r
             }\r
         case OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_READ :\r
             {\r
                 static jfieldID fieldID = env->GetStaticFieldID(cls_SyncType,\r
                                           "READ", "Lorg/iotivity/service/ns/common/SyncInfo$SyncType;");\r
-                return env->GetStaticObjectField(cls_SyncType, fieldID);\r
+                syncType = env->GetStaticObjectField(cls_SyncType, fieldID);\r
+                break;\r
             }\r
         case OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_DELETED :\r
             {\r
                 static jfieldID fieldID = env->GetStaticFieldID(cls_SyncType,\r
                                           "DELETED", "Lorg/iotivity/service/ns/common/SyncInfo$SyncType;");\r
-                return env->GetStaticObjectField(cls_SyncType, fieldID);\r
+                syncType = env->GetStaticObjectField(cls_SyncType, fieldID);\r
+                break;\r
             }\r
         default:\r
-            return NULL;\r
+            {\r
+                syncType = NULL;\r
+                break;\r
+            }\r
     }\r
 \r
-    LOGD ("ConsumerService_getJavaSyncType - OUT");\r
-    return NULL;\r
+    NS_LOGD ("ConsumerService_getJavaSyncType - OUT");\r
+    return syncType;\r
 }\r
 \r
 jobject getJavaTopicState(JNIEnv *env, OIC::Service::NSTopic::NSTopicState nsState)\r
 {\r
-    LOGD ("ConsumerService_getJavaTopicState - IN");\r
+    NS_LOGD ("ConsumerService_getJavaTopicState - IN");\r
 \r
     // TopicState\r
     jclass cls_topicState = (jclass) (env->NewLocalRef(g_cls_TopicState));\r
     if (!cls_topicState)\r
     {\r
-        LOGE ("Failed to Get ObjectClass for TopicState Type");\r
+        NS_LOGE ("Failed to Get ObjectClass for TopicState Type");\r
         return NULL;\r
     }\r
+    jobject topicState = NULL;\r
 \r
     switch (nsState)\r
     {\r
@@ -162,72 +180,77 @@ jobject getJavaTopicState(JNIEnv *env, OIC::Service::NSTopic::NSTopicState nsSta
             {\r
                 static jfieldID fieldID = env->GetStaticFieldID(cls_topicState,\r
                                           "UNSUBSCRIBED", "Lorg/iotivity/service/ns/common/Topic$TopicState;");\r
-                return env->GetStaticObjectField(cls_topicState, fieldID);\r
+                topicState = env->GetStaticObjectField(cls_topicState, fieldID);\r
+                break;\r
             }\r
         case OIC::Service::NSTopic::NSTopicState::SUBSCRIBED:\r
             {\r
                 static jfieldID fieldID = env->GetStaticFieldID(cls_topicState,\r
                                           "SUBSCRIBED", "Lorg/iotivity/service/ns/common/Topic$TopicState;");\r
-                return env->GetStaticObjectField(cls_topicState, fieldID);\r
+                topicState = env->GetStaticObjectField(cls_topicState, fieldID);\r
+                break;\r
             }\r
         default:\r
-            return NULL;\r
+            {\r
+                topicState = NULL;\r
+                break;\r
+            }\r
     }\r
 \r
-    LOGD ("ConsumerService_getJavaTopicState - OUT");\r
-    return NULL;\r
+    NS_LOGD ("ConsumerService_getJavaTopicState - OUT");\r
+    return topicState;\r
 }\r
 \r
-jobject getJavaTopicsList(JNIEnv *env, OIC::Service::NSTopicsList *topicList)\r
+jobject getJavaTopicsList(JNIEnv *env, std::shared_ptr<OIC::Service::NSTopicsList> topicList)\r
 {\r
-    LOGD ("ConsumerService_getJavaTopicsList - IN");\r
+    NS_LOGD ("ConsumerService_getJavaTopicsList - IN");\r
     jclass cls_topicList = (jclass) (env->NewLocalRef(g_cls_TopicsList));\r
     if (!cls_topicList)\r
     {\r
-        LOGE ("Failed to Get ObjectClass for TopicsList");\r
+        NS_LOGE ("Failed to Get ObjectClass for TopicsList");\r
         return NULL;\r
     }\r
     jmethodID mid_topicList = env->GetMethodID(cls_topicList, "<init>", "()V");\r
     if (!mid_topicList)\r
     {\r
-        LOGE ("Failed to Get MethodID for TopicsList<init>");\r
+        NS_LOGE ("Failed to Get MethodID for TopicsList<init>");\r
         return NULL;\r
     }\r
     jobject obj_topicList = env->NewObject(cls_topicList, mid_topicList);\r
     if (!obj_topicList)\r
     {\r
-        LOGE ("Failed to Get object for TopicsList");\r
+        NS_LOGE ("Failed to Get object for TopicsList");\r
         return NULL;\r
     }\r
     jmethodID mid_addTopic = env->GetMethodID(cls_topicList, "addTopic",\r
                              "(Ljava/lang/String;Lorg/iotivity/service/ns/common/Topic$TopicState;)V");\r
     if (!mid_addTopic)\r
     {\r
-        LOGE ("Failed to Get MethodID for addTopic");\r
+        NS_LOGE ("Failed to Get MethodID for addTopic");\r
         return NULL;\r
     }\r
     for (auto it : topicList->getTopicsList())\r
     {\r
-        jobject jState = getJavaTopicState(env, it->getState());\r
-        std::string topicName = it->getTopicName();\r
+        jobject jState = getJavaTopicState(env, it.getState());\r
+        std::string topicName = it.getTopicName();\r
         jstring jTopicName = env->NewStringUTF(topicName.c_str());\r
         env->CallVoidMethod(obj_topicList, mid_addTopic, jTopicName, jState);\r
     }\r
     env->DeleteLocalRef(cls_topicList);\r
-    LOGD ("ConsumerService_getJavaTopicsList - OUT");\r
+    NS_LOGD ("ConsumerService_getJavaTopicsList - OUT");\r
     return obj_topicList;\r
 }\r
 \r
 bool getNativeTopicState(JNIEnv *env,  jobject jTopic , OIC::Service::NSTopic::NSTopicState &state )\r
 {\r
-    LOGD ("ConsumerService_getNativeTopicState - IN");\r
+    NS_LOGD ("ConsumerService_getNativeTopicState - IN");\r
 \r
     jclass cls_topic = env->GetObjectClass( jTopic);\r
     // TopicState\r
     jclass cls_TopicState = (jclass) (env->NewLocalRef(g_cls_TopicState));\r
     if (!cls_TopicState)\r
     {\r
-        LOGE ("Failed to Get ObjectClass for cls_TopicState Type");\r
+        NS_LOGE ("Failed to Get ObjectClass for cls_TopicState Type");\r
         return false;\r
     }\r
     jmethodID mid = env->GetMethodID(cls_TopicState, "ordinal", "()I");\r
@@ -235,110 +258,111 @@ bool getNativeTopicState(JNIEnv *env,  jobject jTopic , OIC::Service::NSTopic::N
                                           "Lorg/iotivity/service/ns/common/Topic$TopicState;");\r
     if (fid_state == NULL)\r
     {\r
-        LOGE("Error: jfieldID for state type  is null");\r
+        NS_LOGE ("Error: jfieldID for state type  is null");\r
         return false;\r
     }\r
     jobject jobj = env->GetObjectField( jTopic, fid_state);\r
     if (jobj == NULL)\r
     {\r
-        LOGE("Error: object of field  state Type is null");\r
+        NS_LOGE ("Error: object of field  state Type is null");\r
         return false;\r
     }\r
     jint jState = env->CallIntMethod(jobj, mid);\r
     state = (OIC::Service::NSTopic::NSTopicState) jState;\r
-    LOGD ("ConsumerService_getNativeTopicState - OUT");\r
+    NS_LOGD ("ConsumerService_getNativeTopicState - OUT");\r
     return true;\r
 \r
 }\r
 \r
 const char *getNativeTopicName(JNIEnv *env,  jobject jTopic)\r
 {\r
-    LOGD ("ConsumerService_getNativeTopicName - IN");\r
+    NS_LOGD ("ConsumerService_getNativeTopicName - IN");\r
     jclass cls_topic = env->GetObjectClass( jTopic);\r
     if (cls_topic == NULL)\r
     {\r
-        LOGE("Error: Class for Topic is null");\r
+        NS_LOGE ("Error: Class for Topic is null");\r
         return nullptr;\r
     }\r
     jfieldID fid_name = env->GetFieldID( cls_topic, "mTopicName", "Ljava/lang/String;");\r
     if (fid_name == NULL)\r
     {\r
-        LOGE("Error: jfieldID for Topic Name  is null");\r
+        NS_LOGE ("Error: jfieldID for Topic Name  is null");\r
         return nullptr;\r
     }\r
     jstring jTopicName = (jstring) env->GetObjectField( jTopic, fid_name);\r
-    const char *topicName;\r
+    const char *topicName = NULL;\r
     if (jTopicName)\r
     {\r
         topicName = env->GetStringUTFChars( jTopicName, NULL);\r
     }\r
     else\r
     {\r
-        LOGI("Info: topicName is null");\r
+        NS_LOGI (TAG, "Info: topicName is null");\r
     }\r
-    LOGD ("ConsumerService_getNativeTopicName - OUT");\r
+    NS_LOGD ("ConsumerService_getNativeTopicName - OUT");\r
     return topicName;\r
 \r
 }\r
 \r
-OIC::Service::NSTopicsList *getNativeTopicsList(JNIEnv *env, jobject jTopicList)\r
+std::shared_ptr<OIC::Service::NSTopicsList> getNativeTopicsList(JNIEnv *env, jobject jTopicList)\r
 {\r
-    LOGD ("ConsumerService_getNativeTopicsList - IN");\r
+    NS_LOGD ("ConsumerService_getNativeTopicsList - IN");\r
 \r
     jclass cls_topicList = env->GetObjectClass( jTopicList);\r
     if (cls_topicList == NULL)\r
     {\r
-        LOGE("Error: Class for Topic List  is null");\r
+        NS_LOGE ("Error: Class for Topic List  is null");\r
         return nullptr;\r
     }\r
     jfieldID fid_list = env->GetFieldID( cls_topicList, "mTopicsList", "Ljava/util/Vector;");\r
     if (fid_list == NULL)\r
     {\r
-        LOGE("Error: jfieldID for Topic List  is null");\r
+        NS_LOGE ("Error: jfieldID for Topic List  is null");\r
         return nullptr;\r
     }\r
     jobject jobj = env->GetObjectField( jTopicList, fid_list);\r
     if (jobj == NULL)\r
     {\r
-        LOGE("Error: object of field  Topic List is null");\r
+        NS_LOGE ("Error: object of field  Topic List is null");\r
         return nullptr;\r
     }\r
     jclass cls_vec = env->FindClass("java/util/Vector");\r
     if (cls_vec == NULL)\r
     {\r
-        LOGE("Error: Class for Vector not found");\r
+        NS_LOGE ("Error: Class for Vector not found");\r
         return nullptr;\r
     }\r
     jmethodID sizeMethod = env->GetMethodID(cls_vec,  "size", "()I");\r
     if (sizeMethod == NULL)\r
     {\r
-        LOGE("Error: MethodId for Vector Size  not found");\r
+        NS_LOGE ("Error: MethodId for Vector Size  not found");\r
         return nullptr;\r
     }\r
     int size = env->CallIntMethod(jobj, sizeMethod);\r
     jmethodID getMethod = env->GetMethodID(cls_vec,  "get", "(I)Ljava/lang/Object;");\r
     if (getMethod == NULL)\r
     {\r
-        LOGE("Error: MethodId for Vector get  not found");\r
+        NS_LOGE ("Error: MethodId for Vector get  not found");\r
         return nullptr;\r
     }\r
-    OIC::Service::NSTopicsList *nsTopicList = new OIC::Service::NSTopicsList();\r
+    std::shared_ptr<OIC::Service::NSTopicsList> nsTopicList =\r
+        std::make_shared<OIC::Service::NSTopicsList>();\r
     for (int index = 0; index < size; index++)\r
     {\r
         jobject topicObj = env->CallObjectMethod(jobj, getMethod, index);\r
         if (topicObj == NULL)\r
         {\r
-            LOGE("Error: object of field  Topic  is null");\r
+            NS_LOGE ("Error: object of field  Topic  is null");\r
             return nullptr;\r
         }\r
         const char *name =  getNativeTopicName(env, topicObj);\r
         if (name == nullptr)\r
         {\r
-            LOGE("Error: Couldn't find topic Name");\r
+            NS_LOGE ("Error: Couldn't find topic Name");\r
             return nullptr;\r
         }\r
         std::string topicName(name);\r
-        OIC::Service::NSTopic::NSTopicState state;\r
+        OIC::Service::NSTopic::NSTopicState state = OIC::Service::NSTopic::NSTopicState::UNSUBSCRIBED;\r
         if (!getNativeTopicState(env, topicObj, state))\r
         {\r
             return nullptr;\r
@@ -348,149 +372,124 @@ OIC::Service::NSTopicsList *getNativeTopicsList(JNIEnv *env, jobject jTopicList)
 \r
     env->DeleteLocalRef(cls_vec);\r
     env->DeleteLocalRef(cls_topicList);\r
-    LOGD ("ConsumerService_getNativeTopicsList - OUT");\r
+    NS_LOGD ("ConsumerService_getNativeTopicsList - OUT");\r
     return nsTopicList;\r
 }\r
 \r
-OIC::Service::NSProvider *getNativeProvider(JNIEnv *env, jobject jObj)\r
+jobject getJavaProvider(JNIEnv *env, std::shared_ptr<OIC::Service::NSProvider> provider)\r
 {\r
-    LOGD ("ConsumerService_getNativeProvider - IN");\r
-    jclass providerClass = env->GetObjectClass(jObj);\r
-    if (!providerClass)\r
-    {\r
-        ThrowNSException(NS_ERROR, "Failed to Get ObjectClass for Provider");\r
-        return NULL;\r
-    }\r
-    jfieldID jproviderId = env->GetFieldID(providerClass, "mProviderId", "Ljava/lang/String;");\r
-    if (!jproviderId)\r
-    {\r
-        ThrowNSException(NS_ERROR, "Failed to get providerId for Provider");\r
-        return NULL;\r
-    }\r
-    jstring jprovider_id = (jstring) env->GetObjectField(jObj, jproviderId);\r
-    if (!jprovider_id)\r
-    {\r
-        ThrowNSException(NS_ERROR, "ProviderId cannot be null");\r
-        return NULL;\r
-    }\r
+    NS_LOGD ("ConsumerService_getJavaProvider - IN");\r
+    NS_LOGD ("ProviderId : %s\n", provider->getProviderId().c_str());\r
 \r
-    const char *providerId = env->GetStringUTFChars(jprovider_id, 0);\r
-    LOGD ("ProviderId : %s\n", providerId);\r
-\r
-    OIC::Service::NSProvider *provider =\r
-        OIC::Service::NSConsumerService::getInstance()->getProvider(std::string(providerId));\r
-    if (provider == nullptr)\r
+    jstring jProviderId = env->NewStringUTF(provider->getProviderId().c_str());\r
+    auto *objectHolder = JniSharedObjectHolder<OIC::Service::NSProvider>::create(provider);\r
+    if (!objectHolder)\r
     {\r
-        ThrowNSException(NS_ERROR, "Provider with Given Id doesn't exist");\r
+        NS_LOGE ("Failed to create new Object Holder for Provider");\r
         return NULL;\r
     }\r
-    env->ReleaseStringUTFChars(jprovider_id, providerId);\r
-    LOGD ("ConsumerService_getNativeProvider - OUT");\r
-    return provider;\r
-}\r
-\r
-jobject getJavaProvider(JNIEnv *env, OIC::Service::NSProvider *provider)\r
-{\r
-    LOGD ("ConsumerService_getJavaProvider - IN");\r
-    LOGD ("ProviderId : %s\n", provider->getProviderId().c_str());\r
-\r
-    jstring jProviderId = env->NewStringUTF(provider->getProviderId().c_str());\r
-    jlong pProvider = (long)provider;\r
+    jlong pProvider = (long)objectHolder;\r
 \r
     jclass cls_provider = (jclass) (env->NewLocalRef(g_cls_Provider));\r
     if (!cls_provider)\r
     {\r
-        LOGE ("Failed to Get ObjectClass for Provider");\r
+        NS_LOGE ("Failed to Get ObjectClass for Provider");\r
         return NULL;\r
     }\r
     jmethodID mid_provider = env->GetMethodID(\r
                                  cls_provider, "<init>", "(Ljava/lang/String;)V");\r
     if (!mid_provider)\r
     {\r
-        LOGE ("Failed to Get MethodID for Provider<init>");\r
+        NS_LOGE ("Failed to Get MethodID for Provider<init>");\r
         return NULL;\r
     }\r
     jobject obj_provider = env->NewObject(cls_provider, mid_provider, jProviderId);\r
     if (!obj_provider)\r
     {\r
-        LOGE("Failed to create new Object for Provider");\r
+        NS_LOGE ("Failed to create new Object for Provider");\r
         return NULL;\r
     }\r
 \r
     jfieldID nativeHandle = env->GetFieldID(cls_provider, "mNativeHandle", "J");\r
     if (!nativeHandle)\r
     {\r
-        LOGE("Failed to get nativeHandle for Provider");\r
+        NS_LOGE ("Failed to get nativeHandle for Provider");\r
         return NULL;\r
     }\r
     env->SetLongField(obj_provider, nativeHandle, pProvider);\r
 \r
     env->DeleteLocalRef(cls_provider);\r
-    LOGD ("ConsumerService_getJavaProvider - OUT");\r
+    NS_LOGD ("ConsumerService_getJavaProvider - OUT");\r
     return obj_provider;\r
 }\r
 \r
 jobject getJavaMessageType(JNIEnv *env, OIC::Service::NSMessage::NSMessageType type)\r
 {\r
-    LOGD ("ConsumerService_getJavaMessageType - IN");\r
+    NS_LOGD ("ConsumerService_getJavaMessageType - IN");\r
+    jobject messageType = NULL;\r
     switch (type)\r
     {\r
         case OIC::Service::NSMessage::NSMessageType::NS_MESSAGE_ALERT:\r
             {\r
                 static jfieldID fieldID = env->GetStaticFieldID(g_cls_Message_Type,\r
                                           "ALERT", "Lorg/iotivity/service/ns/common/Message$MessageType;");\r
-                return env->GetStaticObjectField(g_cls_Message_Type, fieldID);\r
+                messageType = env->GetStaticObjectField(g_cls_Message_Type, fieldID);\r
+                break;\r
             }\r
         case OIC::Service::NSMessage::NSMessageType::NS_MESSAGE_NOTICE:\r
             {\r
                 static jfieldID fieldID = env->GetStaticFieldID(g_cls_Message_Type,\r
                                           "NOTICE", "Lorg/iotivity/service/ns/common/Message$MessageType;");\r
-                return env->GetStaticObjectField(g_cls_Message_Type, fieldID);\r
+                messageType = env->GetStaticObjectField(g_cls_Message_Type, fieldID);\r
+                break;\r
             }\r
         case OIC::Service::NSMessage::NSMessageType::NS_MESSAGE_EVENT:\r
             {\r
                 static jfieldID fieldID = env->GetStaticFieldID(g_cls_Message_Type,\r
                                           "EVENT", "Lorg/iotivity/service/ns/common/Message$MessageType;");\r
-                return env->GetStaticObjectField(g_cls_Message_Type, fieldID);\r
+                messageType = env->GetStaticObjectField(g_cls_Message_Type, fieldID);\r
+                break;\r
             }\r
         case OIC::Service::NSMessage::NSMessageType::NS_MESSAGE_INFO:\r
             {\r
                 static jfieldID fieldID = env->GetStaticFieldID(g_cls_Message_Type,\r
                                           "INFO", "Lorg/iotivity/service/ns/common/Message$MessageType;");\r
-                return env->GetStaticObjectField(g_cls_Message_Type, fieldID);\r
+                messageType = env->GetStaticObjectField(g_cls_Message_Type, fieldID);\r
+                break;\r
             }\r
         default:\r
-            return NULL;\r
+            {\r
+                messageType = NULL;\r
+                break;\r
+            }\r
     }\r
-    LOGD ("ConsumerService_getJavaMessageType - OUT");\r
-    return NULL;\r
+    NS_LOGD ("ConsumerService_getJavaMessageType - OUT");\r
+    return messageType;\r
 }\r
 \r
-jobject getJavaMessage(JNIEnv *env, OIC::Service::NSMessage *message)\r
+jobject getJavaMessage(JNIEnv *env, OIC::Service::NSMessage message)\r
 {\r
-    LOGD ("ConsumerService_getJavaMessage - IN");\r
-\r
-    LOGD ("id : %llu\n", message->getMessageId());\r
-    LOGD ("title : %s\n", message->getTitle().c_str());\r
-    LOGD ("content : %s\n", message->getContentText().c_str());\r
-    LOGD ("source : %s\n", message->getSourceName().c_str());\r
+    NS_LOGD ("ConsumerService_getJavaMessage - IN");\r
 \r
-    jlong jMessageId = (jlong) message->getMessageId();\r
-    jstring jProviderId = env->NewStringUTF(message->getProviderId().c_str());\r
-    jstring jTitle = env->NewStringUTF(message->getTitle().c_str());\r
-    jstring jContentText = env->NewStringUTF(message->getContentText().c_str());\r
-    jstring jSourceName = env->NewStringUTF(message->getSourceName().c_str());\r
-    jstring jTopic = env->NewStringUTF(message->getTopic().c_str());\r
+    NS_LOGD ("id : %llu\n", message.getMessageId());\r
+    NS_LOGD ("title : %s\n", message.getTitle().c_str());\r
+    NS_LOGD ("content : %s\n", message.getContentText().c_str());\r
+    NS_LOGD ("source : %s\n", message.getSourceName().c_str());\r
 \r
-    jstring jTime = env->NewStringUTF(message->getTime().c_str());\r
-    jlong jTTL = (jlong) message->getTTL();\r
+    jlong jMessageId = (jlong) message.getMessageId();\r
+    jstring jProviderId = env->NewStringUTF(message.getProviderId().c_str());\r
+    jstring jTitle = env->NewStringUTF(message.getTitle().c_str());\r
+    jstring jContentText = env->NewStringUTF(message.getContentText().c_str());\r
+    jstring jSourceName = env->NewStringUTF(message.getSourceName().c_str());\r
+    jstring jTopic = env->NewStringUTF(message.getTopic().c_str());\r
 \r
-    jlong pMessage = (long) message;\r
+    jstring jTime = env->NewStringUTF(message.getTime().c_str());\r
+    jlong jTTL = (jlong) message.getTTL();\r
 \r
     jclass cls_message = (jclass) (env->NewLocalRef(g_cls_Message));\r
     if (!cls_message)\r
     {\r
-        LOGE ("Failed to Get ObjectClass for Message");\r
+        NS_LOGE ("Failed to Get ObjectClass for Message");\r
         return NULL ;\r
     }\r
     jmethodID mid_message = env->GetMethodID(\r
@@ -498,28 +497,21 @@ jobject getJavaMessage(JNIEnv *env, OIC::Service::NSMessage *message)
                                 "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");\r
     if (!mid_message)\r
     {\r
-        LOGE ("Failed to Get MethodID for Message<init>");\r
+        NS_LOGE ("Failed to Get MethodID for Message<init>");\r
         return NULL;\r
     }\r
     jobject obj_message = env->NewObject(cls_message, mid_message,\r
                                          jTitle, jContentText, jSourceName);\r
     if (!obj_message)\r
     {\r
-        LOGE ("Failed to Get Java Object for Message");\r
-        return NULL;\r
-    }\r
-    jfieldID fid_nativeHandle = env->GetFieldID(cls_message, "mNativeHandle", "J");\r
-    if (!fid_nativeHandle)\r
-    {\r
-        LOGE("Failed to get nativeHandle for Message");\r
+        NS_LOGE ("Failed to Get Java Object for Message");\r
         return NULL;\r
     }\r
-    env->SetLongField(obj_message, fid_nativeHandle, pMessage);\r
 \r
     jfieldID fid_messageId = env->GetFieldID(cls_message, "mMessageId", "J");\r
     if (!fid_messageId)\r
     {\r
-        LOGE("Failed to get field MessageID for Message");\r
+        NS_LOGE ("Failed to get field MessageID for Message");\r
         return NULL;\r
     }\r
     env->SetLongField(obj_message, fid_messageId, jMessageId);\r
@@ -527,7 +519,7 @@ jobject getJavaMessage(JNIEnv *env, OIC::Service::NSMessage *message)
     jfieldID fid_providerId = env->GetFieldID(cls_message, "mProviderId", "Ljava/lang/String;");\r
     if (!fid_providerId)\r
     {\r
-        LOGE("Failed to get field ProviderID for Message");\r
+        NS_LOGE ("Failed to get field ProviderID for Message");\r
         return NULL;\r
     }\r
     env->SetObjectField(obj_message, fid_providerId, jProviderId);\r
@@ -535,7 +527,7 @@ jobject getJavaMessage(JNIEnv *env, OIC::Service::NSMessage *message)
     jfieldID fid_time = env->GetFieldID(cls_message, "mTime", "Ljava/lang/String;");\r
     if (!fid_time)\r
     {\r
-        LOGE("Failed to get field Time for Message");\r
+        NS_LOGE ("Failed to get field Time for Message");\r
         return NULL;\r
     }\r
     env->SetObjectField(obj_message, fid_time, jTime);\r
@@ -543,7 +535,7 @@ jobject getJavaMessage(JNIEnv *env, OIC::Service::NSMessage *message)
     jfieldID fid_ttl = env->GetFieldID(cls_message, "mTTL", "J");\r
     if (!fid_ttl)\r
     {\r
-        LOGE("Failed to get field TTL for Message");\r
+        NS_LOGE ("Failed to get field TTL for Message");\r
         return NULL;\r
     }\r
     env->SetLongField(obj_message, fid_ttl, jTTL);\r
@@ -551,26 +543,26 @@ jobject getJavaMessage(JNIEnv *env, OIC::Service::NSMessage *message)
     jfieldID fid_topic = env->GetFieldID(cls_message, "mTopic", "Ljava/lang/String;");\r
     if (!fid_topic)\r
     {\r
-        LOGE("Failed to get mTopic for Message");\r
+        NS_LOGE ("Failed to get mTopic for Message");\r
         return NULL;\r
     }\r
     env->SetObjectField(obj_message, fid_topic, jTopic);\r
 \r
-    OIC::Service::NSMediaContents *mediaCont = message->getMediaContents();\r
+    OIC::Service::NSMediaContents *mediaCont = message.getMediaContents();\r
     if (mediaCont != nullptr)\r
     {\r
         jstring jIconImage = env->NewStringUTF(mediaCont->getIconImage().c_str());\r
         jclass cls_mediaContents = (jclass) (env->NewLocalRef(g_cls_MediaContents));\r
         if (!cls_mediaContents)\r
         {\r
-            LOGE ("Failed to Get ObjectClass for MediaContents");\r
+            NS_LOGE ("Failed to Get ObjectClass for MediaContents");\r
             return NULL;\r
         }\r
         jmethodID mid_mediaContents = env->GetMethodID(\r
                                           cls_mediaContents, "<init>", "(Ljava/lang/String;)V");\r
         if (!mid_mediaContents)\r
         {\r
-            LOGE ("Failed to Get MethodID for MediaContents<init>");\r
+            NS_LOGE ("Failed to Get MethodID for MediaContents<init>");\r
             return NULL;\r
         }\r
         jobject obj_mediaContents = env->NewObject(cls_mediaContents, mid_mediaContents,\r
@@ -580,86 +572,98 @@ jobject getJavaMessage(JNIEnv *env, OIC::Service::NSMessage *message)
                                      "Lorg/iotivity/service/ns/common/MediaContents;");\r
         if (!fid_mediaContents)\r
         {\r
-            LOGE("Failed to get field mediaContents for Message");\r
+            NS_LOGE ("Failed to get field mediaContents for Message");\r
             return NULL;\r
         }\r
         env->SetObjectField(obj_message, fid_mediaContents, obj_mediaContents);\r
 \r
     }\r
 \r
-    jobject jType = getJavaMessageType(env, message->getType());\r
+    jobject jType = getJavaMessageType(env, message.getType());\r
     if (jType)\r
     {\r
         jfieldID fid_type = env->GetFieldID(cls_message, "mType",\r
                                             "Lorg/iotivity/service/ns/common/Message$MessageType;");\r
         if (!fid_type)\r
         {\r
-            LOGE("Failed to get field Type for Message");\r
+            NS_LOGE ("Failed to get field Type for Message");\r
             return NULL;\r
         }\r
         env->SetObjectField(obj_message, fid_type, jType);\r
     }\r
 \r
-    LOGD("Reading OCRepresentation Object from Native");\r
+    NS_LOGD ("Reading OCRepresentation Object from Native");\r
 \r
-    OC::OCRepresentation *ocRepresentation = new OC::OCRepresentation(message->getExtraInfo());\r
+    OC::OCRepresentation *ocRepresentation = new OC::OCRepresentation(message.getExtraInfo());\r
     jlong handle = reinterpret_cast<jlong>(ocRepresentation);\r
     jobject jRepresentation = env->NewObject(g_cls_OcRepresentation, g_mid_OcRepresentation_N_ctor_bool,\r
                               handle, true);\r
     if (!jRepresentation)\r
     {\r
-        LOGE("Failed to create OcRepresentation");\r
+        NS_LOGE ("Failed to create OcRepresentation");\r
         delete ocRepresentation;\r
     }\r
     else\r
     {\r
-        LOGD("Created OCRepresentation Object from Native");\r
+        NS_LOGD ("Created OCRepresentation Object from Native");\r
     }\r
     jfieldID fid_extraInfo = env->GetFieldID(cls_message, "mExtraInfo",\r
                              "Lorg/iotivity/base/OcRepresentation;");\r
     if (!fid_extraInfo)\r
     {\r
-        LOGE("Failed to get mExtraInfo for Message");\r
+        NS_LOGE ("Failed to get mExtraInfo for Message");\r
         delete ocRepresentation;\r
         return NULL;\r
     }\r
-    LOGD ("setting extraInfo field");\r
+    NS_LOGD ("setting extraInfo field");\r
     env->SetObjectField(obj_message, fid_extraInfo, jRepresentation);\r
 \r
     env->DeleteLocalRef(cls_message);\r
-    LOGD ("ConsumerService_getJavaMessage - OUT");\r
+    NS_LOGD ("ConsumerService_getJavaMessage - OUT");\r
     return obj_message;\r
 }\r
 \r
-void onDiscoverProvider(OIC::Service::NSProvider *provider)\r
+void onDiscoverProvider(std::shared_ptr<OIC::Service::NSProvider> provider)\r
 {\r
-    LOGD ("ConsumerService_onDiscoverProvider - IN");\r
+    NS_LOGD ("ConsumerService_onDiscoverProvider - IN");\r
 \r
-    jint envRet;\r
+    jint envRet = 0;;\r
     JNIEnv *env = GetJNIEnv(&envRet);\r
-    if (NULL == env) return ;\r
+    if (NULL == env)\r
+    {\r
+        return ;\r
+    }\r
 \r
     jobject jDiscoverListener = (jobject) env->NewLocalRef(g_obj_discoverListener);\r
     if (!jDiscoverListener)\r
     {\r
-        LOGE ("Failed to Get jDiscoverListener");\r
-        if (JNI_EDETACHED == envRet) g_jvm_consumer->DetachCurrentThread();\r
+        NS_LOGE ("Failed to Get jDiscoverListener");\r
+        if (JNI_EDETACHED == envRet)\r
+        {\r
+            g_jvm_consumer->DetachCurrentThread();\r
+        }\r
         return ;\r
     }\r
 \r
     jobject obj_provider = getJavaProvider(env, provider);\r
     if (!obj_provider)\r
     {\r
-        LOGE ("Failed to Get Provider Object");\r
-        if (JNI_EDETACHED == envRet) g_jvm_consumer->DetachCurrentThread();\r
+        NS_LOGE ("Failed to Get Provider Object");\r
+        if (JNI_EDETACHED == envRet)\r
+        {\r
+            g_jvm_consumer->DetachCurrentThread();\r
+        }\r
         return ;\r
     }\r
 \r
     jclass cls = env->GetObjectClass(jDiscoverListener);\r
     if (!cls)\r
     {\r
-        LOGE ("Failed to Get ObjectClass for jDiscoverListener");\r
-        if (JNI_EDETACHED == envRet) g_jvm_consumer->DetachCurrentThread();\r
+        NS_LOGE ("Failed to Get ObjectClass for jDiscoverListener");\r
+        if (JNI_EDETACHED == envRet)\r
+        {\r
+            g_jvm_consumer->DetachCurrentThread();\r
+        }\r
         return ;\r
     }\r
     jmethodID mid = env->GetMethodID(\r
@@ -668,47 +672,65 @@ void onDiscoverProvider(OIC::Service::NSProvider *provider)
                         "(Lorg/iotivity/service/ns/consumer/Provider;)V");\r
     if (!mid)\r
     {\r
-        LOGE ("Failed to Get MethodID for onProviderDiscovered");\r
-        if (JNI_EDETACHED == envRet) g_jvm_consumer->DetachCurrentThread();\r
+        NS_LOGE ("Failed to Get MethodID for onProviderDiscovered");\r
+        if (JNI_EDETACHED == envRet)\r
+        {\r
+            g_jvm_consumer->DetachCurrentThread();\r
+        }\r
         return ;\r
     }\r
 \r
     env->CallVoidMethod(jDiscoverListener, mid, obj_provider);\r
 \r
     env->DeleteLocalRef(jDiscoverListener);\r
-    if (JNI_EDETACHED == envRet) g_jvm_consumer->DetachCurrentThread();\r
-    LOGD ("ConsumerService_onDiscoverProvider - OUT");\r
+    if (JNI_EDETACHED == envRet)\r
+    {\r
+        g_jvm_consumer->DetachCurrentThread();\r
+    }\r
+    NS_LOGD ("ConsumerService_onDiscoverProvider - OUT");\r
     return ;\r
 }\r
 \r
 void onProviderState( OIC::Service::NSProviderState state)\r
 {\r
-    LOGD ("ConsumerService_onProviderState -IN");\r
+    NS_LOGD ("ConsumerService_onProviderState -IN");\r
 \r
-    jint envRet;\r
+    jint envRet = 0;;\r
     JNIEnv *env = GetJNIEnv(&envRet);\r
-    if (NULL == env) return ;\r
+    if (NULL == env)\r
+    {\r
+        return ;\r
+    }\r
 \r
     jobject jAcceptListener = (jobject) env->NewLocalRef(g_obj_acceptListener);\r
     if (!jAcceptListener)\r
     {\r
-        LOGE ("Failed to Get jAcceptListener");\r
-        if (JNI_EDETACHED == envRet) g_jvm_consumer->DetachCurrentThread();\r
+        NS_LOGE ("Failed to Get jAcceptListener");\r
+        if (JNI_EDETACHED == envRet)\r
+        {\r
+            g_jvm_consumer->DetachCurrentThread();\r
+        }\r
         return ;\r
     }\r
     jobject obj_state = getJavaProviderState(env, state);\r
     if (!obj_state)\r
     {\r
-        LOGE ("Failed to Get ProviderState Object");\r
-        if (JNI_EDETACHED == envRet) g_jvm_consumer->DetachCurrentThread();\r
+        NS_LOGE ("Failed to Get ProviderState Object");\r
+        if (JNI_EDETACHED == envRet)\r
+        {\r
+            g_jvm_consumer->DetachCurrentThread();\r
+        }\r
         return ;\r
     }\r
 \r
     jclass cls = env->GetObjectClass(jAcceptListener);\r
     if (!cls)\r
     {\r
-        LOGE ("Failed to Get ObjectClass for jAcceptListener");\r
-        if (JNI_EDETACHED == envRet) g_jvm_consumer->DetachCurrentThread();\r
+        NS_LOGE ("Failed to Get ObjectClass for jAcceptListener");\r
+        if (JNI_EDETACHED == envRet)\r
+        {\r
+            g_jvm_consumer->DetachCurrentThread();\r
+        }\r
         return ;\r
     }\r
     jmethodID mid = env->GetMethodID(\r
@@ -717,47 +739,65 @@ void onProviderState( OIC::Service::NSProviderState state)
                         "(Lorg/iotivity/service/ns/consumer/Provider$ProviderState;)V");\r
     if (!mid)\r
     {\r
-        LOGE ("Failed to Get MethodID for onProviderState");\r
-        if (JNI_EDETACHED == envRet) g_jvm_consumer->DetachCurrentThread();\r
+        NS_LOGE ("Failed to Get MethodID for onProviderState");\r
+        if (JNI_EDETACHED == envRet)\r
+        {\r
+            g_jvm_consumer->DetachCurrentThread();\r
+        }\r
         return ;\r
     }\r
     env->CallVoidMethod(jAcceptListener, mid, obj_state);\r
 \r
     env->DeleteLocalRef(jAcceptListener);\r
-    if (JNI_EDETACHED == envRet) g_jvm_consumer->DetachCurrentThread();\r
-    LOGD ("ConsumerService_onProviderState -OUT");\r
+    if (JNI_EDETACHED == envRet)\r
+    {\r
+        g_jvm_consumer->DetachCurrentThread();\r
+    }\r
+    NS_LOGD ("ConsumerService_onProviderState -OUT");\r
     return ;\r
 \r
 }\r
 \r
-void onMessagePosted(OIC::Service::NSMessage *message)\r
+void onMessagePosted(OIC::Service::NSMessage message)\r
 {\r
-    LOGD ("ConsumerService_onMessagePosted -IN");\r
+    NS_LOGD ("ConsumerService_onMessagePosted -IN");\r
 \r
-    jint envRet;\r
+    jint envRet = 0;;\r
     JNIEnv *env = GetJNIEnv(&envRet);\r
-    if (NULL == env) return ;\r
+    if (NULL == env)\r
+    {\r
+        return ;\r
+    }\r
 \r
     jobject jPostListener = (jobject) env->NewLocalRef(g_obj_postListener);\r
     if (!jPostListener)\r
     {\r
-        LOGE ("Failed to Get jPostListener");\r
-        if (JNI_EDETACHED == envRet) g_jvm_consumer->DetachCurrentThread();\r
+        NS_LOGE ("Failed to Get jPostListener");\r
+        if (JNI_EDETACHED == envRet)\r
+        {\r
+            g_jvm_consumer->DetachCurrentThread();\r
+        }\r
         return ;\r
     }\r
 \r
     jobject obj_message = getJavaMessage( env, message);\r
     if (!obj_message)\r
     {\r
-        LOGE ("Failed to Get Message Object");\r
-        if (JNI_EDETACHED == envRet) g_jvm_consumer->DetachCurrentThread();\r
+        NS_LOGE ("Failed to Get Message Object");\r
+        if (JNI_EDETACHED == envRet)\r
+        {\r
+            g_jvm_consumer->DetachCurrentThread();\r
+        }\r
         return ;\r
     }\r
     jclass cls = env->GetObjectClass(jPostListener);\r
     if (!cls)\r
     {\r
-        LOGE ("Failed to Get ObjectClass for jPostListener");\r
-        if (JNI_EDETACHED == envRet) g_jvm_consumer->DetachCurrentThread();\r
+        NS_LOGE ("Failed to Get ObjectClass for jPostListener");\r
+        if (JNI_EDETACHED == envRet)\r
+        {\r
+            g_jvm_consumer->DetachCurrentThread();\r
+        }\r
         return ;\r
     }\r
     jmethodID mid = env->GetMethodID(\r
@@ -766,53 +806,71 @@ void onMessagePosted(OIC::Service::NSMessage *message)
                         "(Lorg/iotivity/service/ns/common/Message;)V");\r
     if (!mid)\r
     {\r
-        LOGE ("Failed to Get MethodID for onMessageReceived");\r
-        if (JNI_EDETACHED == envRet) g_jvm_consumer->DetachCurrentThread();\r
+        NS_LOGE ("Failed to Get MethodID for onMessageReceived");\r
+        if (JNI_EDETACHED == envRet)\r
+        {\r
+            g_jvm_consumer->DetachCurrentThread();\r
+        }\r
         return ;\r
     }\r
 \r
     env->CallVoidMethod(jPostListener, mid, obj_message);\r
 \r
     env->DeleteLocalRef(jPostListener);\r
-    if (JNI_EDETACHED == envRet) g_jvm_consumer->DetachCurrentThread();\r
-    LOGD ("ConsumerService_onMessagePosted -OUT");\r
+    if (JNI_EDETACHED == envRet)\r
+    {\r
+        g_jvm_consumer->DetachCurrentThread();\r
+    }\r
+    NS_LOGD ("ConsumerService_onMessagePosted -OUT");\r
     return ;\r
 }\r
 \r
-void onSyncInfoReceived(OIC::Service::NSSyncInfo *sync)\r
+void onSyncInfoReceived(OIC::Service::NSSyncInfo sync)\r
 {\r
-    LOGD ("ConsumerService_onSyncInfoReceived - IN");\r
+    NS_LOGD ("ConsumerService_onSyncInfoReceived - IN");\r
 \r
-    jint envRet;\r
+    jint envRet = 0;\r
     JNIEnv *env = GetJNIEnv(&envRet);\r
-    if (NULL == env) return ;\r
+    if (NULL == env)\r
+    {\r
+        return ;\r
+    }\r
 \r
     jobject jSyncListener = (jobject) env->NewLocalRef(g_obj_syncListener);\r
     if (!jSyncListener)\r
     {\r
-        LOGE ("Failed to Get jSyncListener");\r
-        if (JNI_EDETACHED == envRet) g_jvm_consumer->DetachCurrentThread();\r
+        NS_LOGE ("Failed to Get jSyncListener");\r
+        if (JNI_EDETACHED == envRet)\r
+        {\r
+            g_jvm_consumer->DetachCurrentThread();\r
+        }\r
         return ;\r
     }\r
 \r
-    LOGD ("Sync ID : %llu\n", sync->getMessageId());\r
-    LOGD ("Sync ProviderId : %s\n", sync->getProviderId().c_str());\r
-    LOGD ("Sync STATE : %d\n", (int) sync->getState());\r
+    NS_LOGD ("Sync ID : %llu\n", sync.getMessageId());\r
+    NS_LOGD ("Sync ProviderId : %s\n", sync.getProviderId().c_str());\r
+    NS_LOGD ("Sync STATE : %d\n", (int) sync.getState());\r
 \r
-    jlong jMessageId = (jlong) sync->getMessageId();\r
-    jstring jProviderId = env->NewStringUTF(sync->getProviderId().c_str());\r
-    jobject syncType = getJavaSyncType(env, sync->getState());\r
+    jlong jMessageId = (jlong) sync.getMessageId();\r
+    jstring jProviderId = env->NewStringUTF(sync.getProviderId().c_str());\r
+    jobject syncType = getJavaSyncType(env, sync.getState());\r
     if (!syncType)\r
     {\r
-        LOGE ("Failed to Get syncType for SyncInfo");\r
-        if (JNI_EDETACHED == envRet) g_jvm_consumer->DetachCurrentThread();\r
+        NS_LOGE ("Failed to Get syncType for SyncInfo");\r
+        if (JNI_EDETACHED == envRet)\r
+        {\r
+            g_jvm_consumer->DetachCurrentThread();\r
+        }\r
         return ;\r
     }\r
     jclass cls_SyncInfo = (jclass) (env->NewLocalRef(g_cls_SyncInfo));\r
     if (!cls_SyncInfo)\r
     {\r
-        LOGE ("Failed to Get ObjectClass for SyncInfo");\r
-        if (JNI_EDETACHED == envRet) g_jvm_consumer->DetachCurrentThread();\r
+        NS_LOGE ("Failed to Get ObjectClass for SyncInfo");\r
+        if (JNI_EDETACHED == envRet)\r
+        {\r
+            g_jvm_consumer->DetachCurrentThread();\r
+        }\r
         return ;\r
     }\r
     jmethodID mid_syncInfo = env->GetMethodID(\r
@@ -821,8 +879,11 @@ void onSyncInfoReceived(OIC::Service::NSSyncInfo *sync)
                                  "(JLjava/lang/String;Lorg/iotivity/service/ns/common/SyncInfo$SyncType;)V");\r
     if (!mid_syncInfo)\r
     {\r
-        LOGE ("Failed to Get MethodID for SyncInfo");\r
-        if (JNI_EDETACHED == envRet) g_jvm_consumer->DetachCurrentThread();\r
+        NS_LOGE ("Failed to Get MethodID for SyncInfo");\r
+        if (JNI_EDETACHED == envRet)\r
+        {\r
+            g_jvm_consumer->DetachCurrentThread();\r
+        }\r
         return ;\r
     }\r
 \r
@@ -830,16 +891,22 @@ void onSyncInfoReceived(OIC::Service::NSSyncInfo *sync)
                                            jMessageId, jProviderId, syncType);\r
     if (!obj_syncInfo)\r
     {\r
-        LOGE ("Failed to Get Object for SyncInfo");\r
-        if (JNI_EDETACHED == envRet) g_jvm_consumer->DetachCurrentThread();\r
+        NS_LOGE ("Failed to Get Object for SyncInfo");\r
+        if (JNI_EDETACHED == envRet)\r
+        {\r
+            g_jvm_consumer->DetachCurrentThread();\r
+        }\r
         return ;\r
     }\r
 \r
     jclass cls = env->GetObjectClass(jSyncListener);\r
     if (!cls)\r
     {\r
-        LOGE ("Failed to Get ObjectClass for jSyncListener");\r
-        if (JNI_EDETACHED == envRet) g_jvm_consumer->DetachCurrentThread();\r
+        NS_LOGE ("Failed to Get ObjectClass for jSyncListener");\r
+        if (JNI_EDETACHED == envRet)\r
+        {\r
+            g_jvm_consumer->DetachCurrentThread();\r
+        }\r
         return ;\r
     }\r
     jmethodID mid = env->GetMethodID(\r
@@ -848,8 +915,11 @@ void onSyncInfoReceived(OIC::Service::NSSyncInfo *sync)
                         "(Lorg/iotivity/service/ns/common/SyncInfo;)V");\r
     if (!mid)\r
     {\r
-        LOGE ("Failed to Get MethodID for onSyncInfoReceived");\r
-        if (JNI_EDETACHED == envRet) g_jvm_consumer->DetachCurrentThread();\r
+        NS_LOGE ("Failed to Get MethodID for onSyncInfoReceived");\r
+        if (JNI_EDETACHED == envRet)\r
+        {\r
+            g_jvm_consumer->DetachCurrentThread();\r
+        }\r
         return ;\r
     }\r
 \r
@@ -857,19 +927,22 @@ void onSyncInfoReceived(OIC::Service::NSSyncInfo *sync)
 \r
     env->DeleteLocalRef(jSyncListener);\r
     env->DeleteLocalRef(cls_SyncInfo);\r
-    if (JNI_EDETACHED == envRet) g_jvm_consumer->DetachCurrentThread();\r
-    LOGD ("ConsumerService_onSyncInfoReceived - OUT");\r
+    if (JNI_EDETACHED == envRet)\r
+    {\r
+        g_jvm_consumer->DetachCurrentThread();\r
+    }\r
+    NS_LOGD ("ConsumerService_onSyncInfoReceived - OUT");\r
     return ;\r
 }\r
 \r
 JNIEXPORT void JNICALL Java_org_iotivity_service_ns_consumer_ConsumerService_nativeStart\r
 (JNIEnv *env, jobject jObj, jobject jDiscoverListener)\r
 {\r
-    LOGD ("ConsumerService_StartConsumer - IN");\r
+    NS_LOGD ("ConsumerService_StartConsumer - IN");\r
     if (!jDiscoverListener)\r
     {\r
-        ThrowNSException(NS_ERROR, "Listener cannot be null");\r
-        return ;\r
+        ThrowNSException(JNI_INVALID_VALUE, "Listener cannot be null");\r
+        return;\r
     }\r
     if (g_obj_discoverListener != NULL)\r
     {\r
@@ -877,8 +950,15 @@ JNIEXPORT void JNICALL Java_org_iotivity_service_ns_consumer_ConsumerService_nat
     }\r
     g_obj_discoverListener = (jobject) env->NewGlobalRef(jDiscoverListener);\r
 \r
-    OIC::Service::NSConsumerService::getInstance()->start(onDiscoverProvider);\r
-    LOGD ("ConsumerService_StartConsumer - OUT");\r
+    OIC::Service::NSResult result  = OIC::Service::NSConsumerService::getInstance()->start(\r
+                                         onDiscoverProvider);\r
+\r
+    if (result !=  OIC::Service::NSResult::OK)\r
+    {\r
+        ThrowNSException((int) result, "Fail to start ConsumerService");\r
+        return;\r
+    }\r
+    NS_LOGD ("ConsumerService_StartConsumer - OUT");\r
     return;\r
 \r
 }\r
@@ -886,7 +966,7 @@ JNIEXPORT void JNICALL Java_org_iotivity_service_ns_consumer_ConsumerService_nat
 JNIEXPORT void JNICALL Java_org_iotivity_service_ns_consumer_ConsumerService_nativeStop\r
 (JNIEnv *env, jobject jObj)\r
 {\r
-    LOGD ("ConsumerService_StopConsumer - IN");\r
+    NS_LOGD ("ConsumerService_StopConsumer - IN");\r
 \r
     env->DeleteGlobalRef(g_obj_postListener);\r
     env->DeleteGlobalRef(g_obj_syncListener);\r
@@ -896,35 +976,87 @@ JNIEXPORT void JNICALL Java_org_iotivity_service_ns_consumer_ConsumerService_nat
     g_obj_syncListener = NULL;\r
     g_obj_discoverListener = NULL;\r
     g_obj_acceptListener = NULL;\r
-    OIC::Service::NSConsumerService::getInstance()->stop();\r
-    LOGD ("ConsumerService_StopConsumer - OUT");\r
+    OIC::Service::NSResult result  = OIC::Service::NSConsumerService::getInstance()->stop();\r
+\r
+    if (result !=  OIC::Service::NSResult::OK)\r
+    {\r
+        ThrowNSException((int) result, "Fail to Stop ConsumerService");\r
+        return;\r
+    }\r
+    NS_LOGD ("ConsumerService_StopConsumer - OUT");\r
     return;\r
 }\r
 \r
-JNIEXPORT jint JNICALL\r
+JNIEXPORT void JNICALL\r
 Java_org_iotivity_service_ns_consumer_ConsumerService_nativeEnableRemoteService\r
 (JNIEnv *env, jobject jObj, jstring jServerAddress)\r
 {\r
-    LOGD ("ConsumerService_EnableRemoteService - IN");\r
+    NS_LOGD ("ConsumerService_EnableRemoteService - IN");\r
     if (!jServerAddress)\r
     {\r
-        ThrowNSException(NS_ERROR, "EnableRemoteService server address NULL");\r
-        return (jint) OIC::Service::NSResult::ERROR;\r
+        ThrowNSException(JNI_INVALID_VALUE, "EnableRemoteService server address NULL");\r
+        return;\r
     }\r
     const char *serverAddress = env->GetStringUTFChars(jServerAddress, 0);\r
-    OIC::Service::NSResult res =\r
+    OIC::Service::NSResult result =\r
         OIC::Service::NSConsumerService::getInstance()->enableRemoteService(std::string(serverAddress));\r
+\r
+    if (result !=  OIC::Service::NSResult::OK)\r
+    {\r
+        ThrowNSException((int) result, "Fail to EnableRemoteService");\r
+        return;\r
+    }\r
     env->ReleaseStringUTFChars(jServerAddress, serverAddress);\r
-    LOGD ("ConsumerService_EnableRemoteService - OUT");\r
-    return (jint) res;\r
+    NS_LOGD ("ConsumerService_EnableRemoteService - OUT");\r
+    return;\r
+}\r
+\r
+JNIEXPORT void JNICALL\r
+Java_org_iotivity_service_ns_consumer_ConsumerService_nativeSubscribeMQService\r
+(JNIEnv *env, jobject jObj, jstring jserverAddress, jstring jTopicName)\r
+{\r
+    NS_LOGD ("ConsumerService: nativeSubscribeMQService - IN");\r
+    if (!jserverAddress)\r
+    {\r
+        ThrowNSException(JNI_INVALID_VALUE, "Server Address Can't be NULL");\r
+        return;\r
+    }\r
+    if (!jTopicName)\r
+    {\r
+        ThrowNSException(JNI_INVALID_VALUE, "TopicName Can't be NULL");\r
+        return;\r
+    }\r
+\r
+    const char *address = env->GetStringUTFChars( jserverAddress, NULL);\r
+    std::string servAddress(address);\r
+    const char *topic = env->GetStringUTFChars( jTopicName, NULL);\r
+    std::string topicName(topic);\r
+\r
+    OIC::Service::NSResult result  =\r
+        OIC::Service::NSConsumerService::getInstance()->subscribeMQService(\r
+            servAddress, topicName);\r
+    if (result !=  OIC::Service::NSResult::OK)\r
+    {\r
+        ThrowNSException((int) result, "Fail to Subscribe to MQ Service");\r
+        return;\r
+    }\r
+    env->ReleaseStringUTFChars(jserverAddress, address);\r
+    env->ReleaseStringUTFChars(jTopicName, topic);\r
+    NS_LOGD ("ConsumerService: nativeSubscribeMQService - OUT");\r
+    return;\r
 }\r
 \r
 JNIEXPORT void JNICALL Java_org_iotivity_service_ns_consumer_ConsumerService_nativeRescanProvider\r
 (JNIEnv *env, jobject jObj)\r
 {\r
-    LOGD ("ConsumerService_RescanProvider - IN");\r
-    OIC::Service::NSConsumerService::getInstance()->rescanProvider();\r
-    LOGD ("ConsumerService_RescanProvider - OUT");\r
+    NS_LOGD ("ConsumerService_RescanProvider - IN");\r
+    OIC::Service::NSResult result  = OIC::Service::NSConsumerService::getInstance()->rescanProvider();\r
+    if (result !=  OIC::Service::NSResult::OK)\r
+    {\r
+        ThrowNSException((int) result, "Fail to RescanProvider");\r
+        return;\r
+    }\r
+    NS_LOGD ("ConsumerService_RescanProvider - OUT");\r
     return;\r
 \r
 }\r
@@ -932,89 +1064,156 @@ JNIEXPORT void JNICALL Java_org_iotivity_service_ns_consumer_ConsumerService_nat
 JNIEXPORT void JNICALL Java_org_iotivity_service_ns_consumer_Provider_nativeSubscribe\r
 (JNIEnv *env, jobject jObj)\r
 {\r
-    LOGD ("Provider_Subscribe -IN");\r
+    NS_LOGD ("Provider_Subscribe -IN");\r
+    OIC::Service::NSResult result  = OIC::Service::NSResult::ERROR;\r
     jclass providerClass = env->GetObjectClass(jObj);\r
     if (!providerClass)\r
     {\r
-        ThrowNSException(NS_ERROR, "Failed to Get ObjectClass for Provider");\r
+        ThrowNSException(JNI_INVALID_VALUE, "Failed to Get ObjectClass for Provider");\r
         return ;\r
     }\r
 \r
     jfieldID nativeHandle = env->GetFieldID(providerClass, "mNativeHandle", "J");\r
     if (!nativeHandle)\r
     {\r
-        ThrowNSException(NS_ERROR, "Failed to get nativeHandle for Provider");\r
+        ThrowNSException(JNI_INVALID_VALUE, "Failed to get nativeHandle for Provider");\r
         return ;\r
     }\r
     jlong jProvider = env->GetLongField(jObj, nativeHandle);\r
     if (jProvider)\r
     {\r
-        LOGD ("calling subscribe on mNativeHandle");\r
-        OIC::Service::NSProvider *provider = (OIC::Service::NSProvider *) (jProvider);\r
-        provider->subscribe();\r
+        NS_LOGD ("calling subscribe on mNativeHandle");\r
+        JniSharedObjectHolder<OIC::Service::NSProvider> *objectHolder =\r
+            reinterpret_cast<JniSharedObjectHolder<OIC::Service::NSProvider> *>(jProvider);\r
+        try\r
+        {\r
+            result  = objectHolder->get()->subscribe();\r
+        }\r
+        catch (OIC::Service::NSException ex)\r
+        {\r
+            ThrowNSException(NATIVE_EXCEPTION, ex.what());\r
+            return;\r
+        }\r
     }\r
     else\r
     {\r
-        OIC::Service::NSProvider *provider = getNativeProvider(env, jObj);\r
-        if (provider == nullptr)\r
+        NS_LOGE ("Couldn't find Provider");\r
+        ThrowNSException(JNI_NO_NATIVE_POINTER, "Fail to find native Provider");\r
+    }\r
+    if (result !=  OIC::Service::NSResult::OK)\r
+    {\r
+        ThrowNSException((int) result, "Fail to Subscribe Provider");\r
+        return;\r
+    }\r
+    NS_LOGD ("Provider_Subscribe -OUT");\r
+    return;\r
+}\r
+\r
+JNIEXPORT void JNICALL Java_org_iotivity_service_ns_consumer_Provider_nativeUnsubscribe\r
+(JNIEnv *env, jobject jObj)\r
+{\r
+    NS_LOGD ("Provider_UnSubscribe -IN");\r
+    OIC::Service::NSResult result  = OIC::Service::NSResult::ERROR;\r
+    jclass providerClass = env->GetObjectClass(jObj);\r
+    if (!providerClass)\r
+    {\r
+        ThrowNSException(JNI_INVALID_VALUE, "Failed to Get ObjectClass for Provider");\r
+        return ;\r
+    }\r
+\r
+    jfieldID nativeHandle = env->GetFieldID(providerClass, "mNativeHandle", "J");\r
+    if (!nativeHandle)\r
+    {\r
+        ThrowNSException(JNI_INVALID_VALUE, "Failed to get nativeHandle for Provider");\r
+        return ;\r
+    }\r
+    jlong jProvider = env->GetLongField(jObj, nativeHandle);\r
+    if (jProvider)\r
+    {\r
+        NS_LOGD ("calling subscribe on mNativeHandle");\r
+        JniSharedObjectHolder<OIC::Service::NSProvider> *objectHolder =\r
+            reinterpret_cast<JniSharedObjectHolder<OIC::Service::NSProvider> *>(jProvider);\r
+        try\r
+        {\r
+            result  = objectHolder->get()->unsubscribe();\r
+        }\r
+        catch (OIC::Service::NSException ex)\r
         {\r
-            ThrowNSException(NS_ERROR, "Provider with Given Id doesn't exist");\r
+            ThrowNSException(NATIVE_EXCEPTION, ex.what());\r
             return;\r
         }\r
-        LOGD ("calling subscribe on ProviderID");\r
-        provider->subscribe();\r
     }\r
-    LOGD ("Provider_Subscribe -OUT");\r
+    else\r
+    {\r
+        NS_LOGE ("Couldn't find Provider");\r
+        ThrowNSException(JNI_NO_NATIVE_POINTER, "Fail to find native Provider");\r
+    }\r
+    if (result !=  OIC::Service::NSResult::OK)\r
+    {\r
+        ThrowNSException((int) result, "Fail to UnSubscribe Provider");\r
+        return;\r
+    }\r
+    NS_LOGD ("Provider_UnSubscribe -OUT");\r
     return;\r
 }\r
 \r
 JNIEXPORT void JNICALL Java_org_iotivity_service_ns_consumer_Provider_nativeSendSyncInfo\r
 (JNIEnv *env, jobject jObj, jlong jMessageId, jint jSyncType)\r
 {\r
-    LOGD ("Provider_SendSyncInfo - IN");\r
+    NS_LOGD ("Provider_SendSyncInfo - IN");\r
+    OIC::Service::NSResult result  = OIC::Service::NSResult::ERROR;\r
     if (!jMessageId)\r
     {\r
-        ThrowNSException(NS_ERROR, "MessageId cannot be 0");\r
+        ThrowNSException(JNI_INVALID_VALUE, "MessageId cannot be 0");\r
         return ;\r
     }\r
 \r
     jclass providerClass = env->GetObjectClass(jObj);\r
     if (!providerClass)\r
     {\r
-        ThrowNSException(NS_ERROR, "Failed to Get ObjectClass for Provider");\r
+        ThrowNSException(JNI_INVALID_VALUE, "Failed to Get ObjectClass for Provider");\r
         return ;\r
     }\r
 \r
     jfieldID nativeHandle = env->GetFieldID(providerClass, "mNativeHandle", "J");\r
     if (!nativeHandle)\r
     {\r
-        ThrowNSException(NS_ERROR, "Failed to get nativeHandle for Provider");\r
+        ThrowNSException(JNI_INVALID_VALUE, "Failed to get nativeHandle for Provider");\r
         return ;\r
     }\r
     uint64_t messageId = (uint64_t) jMessageId;\r
 \r
-    LOGD("!!!!!!jMessageId: %lld", jMessageId);\r
-    LOGD("!!!!!!messageId: %lld", messageId);\r
+    NS_LOGD ("!!!!!!jMessageId: %lld", jMessageId);\r
+    NS_LOGD ("!!!!!!messageId: %lld", messageId);\r
 \r
     jlong jProvider = env->GetLongField(jObj, nativeHandle);\r
     if (jProvider)\r
     {\r
-        LOGD ("calling SendSyncInfo on mNativeHandle");\r
-        OIC::Service::NSProvider *provider = (OIC::Service::NSProvider *) (jProvider);\r
-        provider->sendSyncInfo(messageId, (OIC::Service::NSSyncInfo::NSSyncType)jSyncType);\r
-    }\r
-    else\r
-    {\r
-        OIC::Service::NSProvider *provider = getNativeProvider(env, jObj);\r
-        if (provider == nullptr)\r
+        NS_LOGD ("calling SendSyncInfo on mNativeHandle");\r
+        JniSharedObjectHolder<OIC::Service::NSProvider> *objectHolder =\r
+            reinterpret_cast<JniSharedObjectHolder<OIC::Service::NSProvider> *>(jProvider);\r
+        try\r
         {\r
-            ThrowNSException(NS_ERROR, "Provider with Given Id doesn't exist");\r
+            result  = objectHolder->get()->sendSyncInfo(messageId,\r
+                      (OIC::Service::NSSyncInfo::NSSyncType)jSyncType);\r
+        }\r
+        catch (OIC::Service::NSException ex)\r
+        {\r
+            ThrowNSException(NATIVE_EXCEPTION, ex.what());\r
             return;\r
         }\r
-        LOGD ("calling SendSyncInfo on ProviderID");\r
-        provider->sendSyncInfo(messageId, (OIC::Service::NSSyncInfo::NSSyncType)jSyncType);\r
     }\r
-    LOGD ("Provider_SendSyncInfo - OUT");\r
+    else\r
+    {\r
+        NS_LOGE ("Couldn't find Provider");\r
+        ThrowNSException(JNI_NO_NATIVE_POINTER, "Fail to find native Provider");\r
+    }\r
+    if (result !=  OIC::Service::NSResult::OK)\r
+    {\r
+        ThrowNSException((int) result, "Fail to Send sync info");\r
+        return;\r
+    }\r
+    NS_LOGD ("Provider_SendSyncInfo - OUT");\r
     return;\r
 }\r
 \r
@@ -1022,30 +1221,30 @@ JNIEXPORT void JNICALL Java_org_iotivity_service_ns_consumer_Provider_nativeSend
 JNIEXPORT void JNICALL Java_org_iotivity_service_ns_consumer_Provider_nativeSetListener\r
 (JNIEnv *env, jobject jObj, jobject jAcceptListener, jobject jPostListener, jobject jSyncListener)\r
 {\r
-    LOGD ("Provider_SetListener - IN");\r
+    NS_LOGD ("Provider_SetListener - IN");\r
     if (!jPostListener || !jSyncListener || !jAcceptListener)\r
     {\r
-        ThrowNSException(NS_ERROR, "Listener cannot be null");\r
+        ThrowNSException(JNI_INVALID_VALUE, "Listener cannot be null");\r
         return ;\r
     }\r
 \r
     jclass providerClass = env->GetObjectClass(jObj);\r
     if (!providerClass)\r
     {\r
-        ThrowNSException(NS_ERROR, "Failed to Get ObjectClass for Provider");\r
+        ThrowNSException(JNI_INVALID_VALUE, "Failed to Get ObjectClass for Provider");\r
         return ;\r
     }\r
 \r
     jfieldID nativeHandle = env->GetFieldID(providerClass, "mNativeHandle", "J");\r
     if (!nativeHandle)\r
     {\r
-        ThrowNSException(NS_ERROR, "Failed to get nativeHandle for Provider");\r
+        ThrowNSException(JNI_INVALID_VALUE, "Failed to get nativeHandle for Provider");\r
         return ;\r
     }\r
     jlong jProvider = env->GetLongField(jObj, nativeHandle);\r
     if (jProvider)\r
     {\r
-        LOGD ("calling SetListener on mNativeHandle");\r
+        NS_LOGD ("calling SetListener on mNativeHandle");\r
         if (g_obj_acceptListener != NULL)\r
         {\r
             env->DeleteGlobalRef(g_obj_acceptListener);\r
@@ -1062,234 +1261,248 @@ JNIEXPORT void JNICALL Java_org_iotivity_service_ns_consumer_Provider_nativeSetL
         g_obj_postListener = (jobject) env->NewGlobalRef(jPostListener);\r
         g_obj_syncListener = (jobject) env->NewGlobalRef(jSyncListener);\r
 \r
-        OIC::Service::NSProvider *provider = (OIC::Service::NSProvider *) (jProvider);\r
-        provider->setListener(onProviderState, onMessagePosted, onSyncInfoReceived);\r
+        JniSharedObjectHolder<OIC::Service::NSProvider> *objectHolder =\r
+            reinterpret_cast<JniSharedObjectHolder<OIC::Service::NSProvider> *>(jProvider);\r
+        objectHolder->get()->setListener(onProviderState, onMessagePosted, onSyncInfoReceived);\r
     }\r
     else\r
     {\r
-        OIC::Service::NSProvider *provider = getNativeProvider(env, jObj);\r
-        if (provider == nullptr)\r
-        {\r
-            ThrowNSException(NS_ERROR, "Provider with Given Id doesn't exist");\r
-            return;\r
-        }\r
-        LOGD ("calling SetListener on ProviderID");\r
-        if (g_obj_acceptListener != NULL)\r
-        {\r
-            env->DeleteGlobalRef(g_obj_acceptListener);\r
-        }\r
-        if (g_obj_postListener != NULL)\r
-        {\r
-            env->DeleteGlobalRef(g_obj_postListener);\r
-        }\r
-        if (g_obj_syncListener != NULL)\r
-        {\r
-            env->DeleteGlobalRef(g_obj_syncListener);\r
-        }\r
-        g_obj_acceptListener = (jobject) env->NewGlobalRef(jAcceptListener);\r
-        g_obj_postListener = (jobject) env->NewGlobalRef(jPostListener);\r
-        g_obj_syncListener = (jobject) env->NewGlobalRef(jSyncListener);\r
-\r
-        provider->setListener(onProviderState, onMessagePosted, onSyncInfoReceived);\r
+        NS_LOGE ("Couldn't find Provider");\r
+        ThrowNSException(JNI_NO_NATIVE_POINTER, "Fail to find native Provider");\r
     }\r
-    LOGD ("Provider_SetListener - OUT");\r
+    NS_LOGD ("Provider_SetListener - OUT");\r
     return;\r
 }\r
 \r
 JNIEXPORT jobject JNICALL Java_org_iotivity_service_ns_consumer_Provider_nativeGetTopicList\r
 (JNIEnv *env, jobject jObj)\r
 {\r
-    LOGD("Provider_nativeGetTopicList - IN");\r
+    NS_LOGD ("Provider_nativeGetTopicList - IN");\r
     jclass providerClass = env->GetObjectClass(jObj);\r
     if (!providerClass)\r
     {\r
-        ThrowNSException(NS_ERROR, "Failed to Get ObjectClass for Provider");\r
+        ThrowNSException(JNI_INVALID_VALUE, "Failed to Get ObjectClass for Provider");\r
         return NULL;\r
     }\r
 \r
     jfieldID nativeHandle = env->GetFieldID(providerClass, "mNativeHandle", "J");\r
     if (!nativeHandle)\r
     {\r
-        ThrowNSException(NS_ERROR, "Failed to get nativeHandle for Provider");\r
+        ThrowNSException(JNI_INVALID_VALUE, "Failed to get nativeHandle for Provider");\r
         return NULL;\r
     }\r
     jlong jProvider = env->GetLongField(jObj, nativeHandle);\r
-    OIC::Service::NSTopicsList *topicList;\r
+    std::shared_ptr<OIC::Service::NSTopicsList> topicList = nullptr;\r
     if (jProvider)\r
     {\r
-        LOGD ("calling subscribe on mNativeHandle");\r
-        OIC::Service::NSProvider *provider = (OIC::Service::NSProvider *) (jProvider);\r
-        topicList = provider->getTopicList();\r
-    }\r
-    else\r
-    {\r
-        OIC::Service::NSProvider *provider = getNativeProvider(env, jObj);\r
-        if (provider == nullptr)\r
+        NS_LOGD ("calling subscribe on mNativeHandle");\r
+        JniSharedObjectHolder<OIC::Service::NSProvider> *objectHolder =\r
+            reinterpret_cast<JniSharedObjectHolder<OIC::Service::NSProvider> *>(jProvider);\r
+        try\r
         {\r
-            ThrowNSException(NS_ERROR, "Provider with Given Id doesn't exist");\r
+            topicList = objectHolder->get()->getTopicList();\r
+        }\r
+        catch (OIC::Service::NSException ex)\r
+        {\r
+            ThrowNSException(NATIVE_EXCEPTION, ex.what());\r
             return NULL;\r
         }\r
-        LOGD ("calling subscribe on ProviderID");\r
-        topicList = provider->getTopicList();\r
+    }\r
+    else\r
+    {\r
+        NS_LOGE ("Couldn't find Provider");\r
+        ThrowNSException(JNI_NO_NATIVE_POINTER, "Fail to find native Provider");\r
     }\r
     if (topicList == nullptr)\r
     {\r
-        ThrowNSException(NS_ERROR, "Topic List doesn't exist");\r
+        ThrowNSException(JNI_INVALID_VALUE, "Topic List doesn't exist");\r
         return NULL;\r
     }\r
 \r
     jobject obj_topicList = getJavaTopicsList(env, topicList);\r
 \r
-    LOGD("Provider_nativeGetTopicList - OUT");\r
+    NS_LOGD ("Provider_nativeGetTopicList - OUT");\r
     return obj_topicList;\r
 }\r
 \r
-JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_consumer_Provider_nativeUpdateTopicList\r
+JNIEXPORT void JNICALL Java_org_iotivity_service_ns_consumer_Provider_nativeUpdateTopicList\r
 (JNIEnv *env, jobject jObj, jobject jTopicsList)\r
 {\r
-    LOGD("Provider_nativeUpdateTopicList -IN");\r
+    NS_LOGD ("Provider_nativeUpdateTopicList -IN");\r
     if (!jTopicsList)\r
     {\r
-        LOGI("Fail to update Interest Topics - Topic List is null");\r
-        ThrowNSException(NS_ERROR, "TopicList cannot be null");\r
-        return (jint) OIC::Service::NSResult::ERROR;\r
+        ThrowNSException(JNI_INVALID_VALUE, "TopicList cannot be null");\r
+        return;\r
     }\r
-    OIC::Service::NSTopicsList *nsTopicsList = getNativeTopicsList(env, jTopicsList);\r
+    std::shared_ptr<OIC::Service::NSTopicsList> nsTopicsList = getNativeTopicsList(env, jTopicsList);\r
     if (nsTopicsList == nullptr)\r
     {\r
-        ThrowNSException(NS_ERROR, "NSTopicList cannot be created ");\r
-        return (jint) OIC::Service::NSResult::ERROR;\r
+        ThrowNSException(JNI_INVALID_VALUE, "NSTopicList cannot be created ");\r
+        return;\r
     }\r
 \r
     jclass providerClass = env->GetObjectClass(jObj);\r
     if (!providerClass)\r
     {\r
-        ThrowNSException(NS_ERROR, "Failed to Get ObjectClass for Provider");\r
-        return  (jint) OIC::Service::NSResult::ERROR;\r
+        ThrowNSException(JNI_INVALID_VALUE, "Failed to Get ObjectClass for Provider");\r
+        return;\r
     }\r
 \r
     jfieldID nativeHandle = env->GetFieldID(providerClass, "mNativeHandle", "J");\r
     if (!nativeHandle)\r
     {\r
-        ThrowNSException(NS_ERROR, "Failed to get nativeHandle for Provider");\r
-        return  (jint) OIC::Service::NSResult::ERROR;\r
+        ThrowNSException(JNI_INVALID_VALUE, "Failed to get nativeHandle for Provider");\r
+        return;\r
     }\r
     jlong jProvider = env->GetLongField(jObj, nativeHandle);\r
-    OIC::Service::NSResult result;\r
+    OIC::Service::NSResult result = OIC::Service::NSResult::ERROR;\r
     if (jProvider)\r
     {\r
-        LOGD ("calling subscribe on mNativeHandle");\r
-        OIC::Service::NSProvider *provider = (OIC::Service::NSProvider *) (jProvider);\r
-        result = provider->updateTopicList(nsTopicsList);\r
+        NS_LOGD ("calling subscribe on mNativeHandle");\r
+        JniSharedObjectHolder<OIC::Service::NSProvider> *objectHolder =\r
+            reinterpret_cast<JniSharedObjectHolder<OIC::Service::NSProvider> *>(jProvider);\r
+        try\r
+        {\r
+            result = objectHolder->get()->updateTopicList(nsTopicsList);\r
+        }\r
+        catch (OIC::Service::NSException ex)\r
+        {\r
+            ThrowNSException(NATIVE_EXCEPTION, ex.what());\r
+            return;\r
+        }\r
     }\r
     else\r
     {\r
-        OIC::Service::NSProvider *provider = getNativeProvider(env, jObj);\r
-        if (provider == nullptr)\r
-        {\r
-            ThrowNSException(NS_ERROR, "Provider with Given Id doesn't exist");\r
-            return (jint) OIC::Service::NSResult::ERROR;\r
-        }\r
-        LOGD ("calling subscribe on ProviderID");\r
-        result = provider->updateTopicList(nsTopicsList);\r
+        NS_LOGE ("Couldn't find Provider");\r
+        ThrowNSException(JNI_NO_NATIVE_POINTER, "Fail to find native Provider");\r
     }\r
     if (result !=  OIC::Service::NSResult::OK)\r
     {\r
-        LOGI("Fail to Update Interest Topics");\r
+        ThrowNSException((int) result, "Fail to Update Interest Topics");\r
+        return;\r
     }\r
-    LOGD("Provider_nativeUpdateTopicList -OUT");\r
-    return (jint) result;\r
+    NS_LOGD ("Provider_nativeUpdateTopicList -OUT");\r
+    return;\r
 }\r
 \r
 JNIEXPORT jobject JNICALL Java_org_iotivity_service_ns_consumer_Provider_nativeGetProviderState\r
 (JNIEnv *env, jobject jObj)\r
 {\r
-    LOGD("Provider_nativeGetProviderState - IN");\r
+    NS_LOGD ("Provider_nativeGetProviderState - IN");\r
     jclass providerClass = env->GetObjectClass(jObj);\r
     if (!providerClass)\r
     {\r
-        ThrowNSException(NS_ERROR, "Failed to Get ObjectClass for Provider");\r
+        ThrowNSException(JNI_INVALID_VALUE, "Failed to Get ObjectClass for Provider");\r
         return NULL;\r
     }\r
 \r
     jfieldID nativeHandle = env->GetFieldID(providerClass, "mNativeHandle", "J");\r
     if (!nativeHandle)\r
     {\r
-        ThrowNSException(NS_ERROR, "Failed to get nativeHandle for Provider");\r
+        ThrowNSException(JNI_INVALID_VALUE, "Failed to get nativeHandle for Provider");\r
         return NULL;\r
     }\r
     jlong jProvider = env->GetLongField(jObj, nativeHandle);\r
-    OIC::Service::NSProviderState state;\r
+    OIC::Service::NSProviderState state = OIC::Service::NSProviderState::DENY;\r
     if (jProvider)\r
     {\r
-        LOGD ("calling getProviderState on mNativeHandle");\r
-        OIC::Service::NSProvider *provider = (OIC::Service::NSProvider *) (jProvider);\r
-        state = provider->getProviderState();\r
-    }\r
-    else\r
-    {\r
-        OIC::Service::NSProvider *provider = getNativeProvider(env, jObj);\r
-        if (provider == nullptr)\r
+        NS_LOGD ("calling getProviderState on mNativeHandle");\r
+        JniSharedObjectHolder<OIC::Service::NSProvider> *objectHolder =\r
+            reinterpret_cast<JniSharedObjectHolder<OIC::Service::NSProvider> *>(jProvider);\r
+        try\r
+        {\r
+            state = objectHolder->get()->getProviderState();\r
+        }\r
+        catch (OIC::Service::NSException ex)\r
         {\r
-            ThrowNSException(NS_ERROR, "Provider with Given Id doesn't exist");\r
+            ThrowNSException(NATIVE_EXCEPTION, ex.what());\r
             return NULL;\r
         }\r
-        LOGD ("calling getProviderState on ProviderID");\r
-        state = provider->getProviderState();\r
+    }\r
+    else\r
+    {\r
+        NS_LOGE ("Couldn't find Provider");\r
+        ThrowNSException(JNI_NO_NATIVE_POINTER, "Fail to find native Provider");\r
     }\r
     jobject obj_state = getJavaProviderState(env, state);\r
 \r
-    LOGD("Provider_nativeGetProviderState - OUT");\r
+    NS_LOGD ("Provider_nativeGetProviderState - OUT");\r
     return obj_state;\r
 }\r
 \r
 JNIEXPORT jboolean JNICALL Java_org_iotivity_service_ns_consumer_Provider_nativeIsSubscribed\r
 (JNIEnv *env, jobject jObj)\r
 {\r
-    LOGD("nativeIsSubscribed - IN");\r
+    NS_LOGD ("nativeIsSubscribed - IN");\r
     jclass providerClass = env->GetObjectClass(jObj);\r
     if (!providerClass)\r
     {\r
-        ThrowNSException(NS_ERROR, "Failed to Get ObjectClass for Provider");\r
+        ThrowNSException(JNI_INVALID_VALUE, "Failed to Get ObjectClass for Provider");\r
         return (jboolean)false;\r
     }\r
 \r
     jfieldID nativeHandle = env->GetFieldID(providerClass, "mNativeHandle", "J");\r
     if (!nativeHandle)\r
     {\r
-        ThrowNSException(NS_ERROR, "Failed to get nativeHandle for Provider");\r
+        ThrowNSException(JNI_INVALID_VALUE, "Failed to get nativeHandle for Provider");\r
         return (jboolean)false;\r
     }\r
     jlong jProvider = env->GetLongField(jObj, nativeHandle);\r
     if (jProvider)\r
     {\r
-        LOGD ("calling isSubscribe on mNativeHandle");\r
-        OIC::Service::NSProvider *provider = (OIC::Service::NSProvider *) (jProvider);\r
-        return (jboolean) provider->isSubscribed();\r
-    }\r
-    else\r
-    {\r
-        OIC::Service::NSProvider *provider = getNativeProvider(env, jObj);\r
-        if (provider == nullptr)\r
+        NS_LOGD ("calling isSubscribe on mNativeHandle");\r
+        JniSharedObjectHolder<OIC::Service::NSProvider> *objectHolder =\r
+            reinterpret_cast<JniSharedObjectHolder<OIC::Service::NSProvider> *>(jProvider);\r
+        try\r
+        {\r
+            return (jboolean) objectHolder->get()->isSubscribed();\r
+        }\r
+        catch (OIC::Service::NSException ex)\r
         {\r
-            ThrowNSException(NS_ERROR, "Provider with Given Id doesn't exist");\r
+            ThrowNSException(NATIVE_EXCEPTION, ex.what());\r
             return (jboolean)false;\r
         }\r
-        LOGD ("calling isSubscribe on ProviderID");\r
-        return (jboolean) provider->isSubscribed();\r
+    }\r
+    else\r
+    {\r
+        NS_LOGE ("Couldn't find Provider");\r
+        ThrowNSException(JNI_NO_NATIVE_POINTER, "Fail to find native Provider");\r
     }\r
 }\r
 \r
+JNIEXPORT void JNICALL\r
+Java_org_iotivity_service_ns_consumer_Provider_nativeDispose\r
+(JNIEnv *env, jobject object)\r
+{\r
+    jclass cls_provider = (jclass) (env->NewLocalRef(g_cls_Provider));\r
+    if (!cls_provider)\r
+    {\r
+        NS_LOGE ("Failed to Get ObjectClass for Provider");\r
+        return;\r
+    }\r
+    jfieldID nativeHandle = env->GetFieldID(cls_provider, "mNativeHandle", "J");\r
+    if (!nativeHandle)\r
+    {\r
+        NS_LOGE ("Failed to get nativeHandle for Provider");\r
+        return;\r
+    }\r
+    jlong handle = env->GetLongField(object, nativeHandle);\r
+    JniSharedObjectHolder<OIC::Service::NSProvider> *objectHolder =\r
+        reinterpret_cast<JniSharedObjectHolder<OIC::Service::NSProvider> *>(handle);\r
+    delete objectHolder;\r
+    return;\r
+}\r
+\r
 // JNI OnLoad\r
 JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)\r
 {\r
-    LOGD("ConsumerService_JNI_OnLoad");\r
+    NS_LOGD ("ConsumerService_JNI_OnLoad");\r
     g_jvm_consumer = jvm;\r
 \r
-    JNIEnv *env;\r
+    JNIEnv *env = NULL;\r
     if (jvm->GetEnv((void **)&env, JNI_CURRENT_VERSION) != JNI_OK)\r
     {\r
-        LOGE("Failed to get the environment using GetEnv()");\r
+        NS_LOGE ("Failed to get the environment using GetEnv()");\r
         return JNI_ERR;\r
     }\r
 \r
@@ -1297,13 +1510,13 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
                               "org/iotivity/service/ns/common/Message");\r
     if (!localMessage)\r
     {\r
-        LOGE("Failed to get local Message class");\r
+        NS_LOGE ("Failed to get local Message class");\r
         return JNI_ERR;\r
     }\r
     g_cls_Message = (jclass) (env->NewGlobalRef(localMessage));\r
     if (!g_cls_Message)\r
     {\r
-        LOGE("Failed to set Global Message reference");\r
+        NS_LOGE ("Failed to set Global Message reference");\r
         return JNI_ERR;\r
     }\r
 \r
@@ -1311,13 +1524,13 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
                                "org/iotivity/service/ns/consumer/Provider");\r
     if (!localProvider)\r
     {\r
-        LOGE("Failed to get local Provider class");\r
+        NS_LOGE ("Failed to get local Provider class");\r
         return JNI_ERR;\r
     }\r
     g_cls_Provider = (jclass) (env->NewGlobalRef(localProvider));\r
     if (!g_cls_Provider)\r
     {\r
-        LOGE("Failed to set Global Provider reference");\r
+        NS_LOGE ("Failed to set Global Provider reference");\r
         return JNI_ERR;\r
     }\r
 \r
@@ -1325,13 +1538,13 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
                                "org/iotivity/service/ns/common/SyncInfo");\r
     if (!localSyncInfo)\r
     {\r
-        LOGE("Failed to get local SyncInfo class");\r
+        NS_LOGE ("Failed to get local SyncInfo class");\r
         return JNI_ERR;\r
     }\r
     g_cls_SyncInfo = (jclass) (env->NewGlobalRef(localSyncInfo));\r
     if (!g_cls_SyncInfo)\r
     {\r
-        LOGE("Failed to set Global NSSyncInfo reference");\r
+        NS_LOGE ("Failed to set Global NSSyncInfo reference");\r
         return JNI_ERR;\r
     }\r
 \r
@@ -1339,13 +1552,13 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
                                "org/iotivity/service/ns/common/SyncInfo$SyncType");\r
     if (!localSyncType)\r
     {\r
-        LOGE("Failed to get local SyncType enum");\r
+        NS_LOGE ("Failed to get local SyncType enum");\r
         return JNI_ERR;\r
     }\r
     g_cls_SyncType = (jclass) (env->NewGlobalRef(localSyncType));\r
     if (!g_cls_SyncType)\r
     {\r
-        LOGE("Failed to set Global SyncType reference");\r
+        NS_LOGE ("Failed to set Global SyncType reference");\r
         return JNI_ERR;\r
     }\r
 \r
@@ -1353,26 +1566,26 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
                                     "org/iotivity/service/ns/common/MediaContents");\r
     if (!localMediaContents)\r
     {\r
-        LOGE("Failed to get local MediaContents class");\r
+        NS_LOGE ("Failed to get local MediaContents class");\r
         return JNI_ERR;\r
     }\r
     g_cls_MediaContents = (jclass) (env->NewGlobalRef(localMediaContents));\r
     if (!g_cls_MediaContents)\r
     {\r
-        LOGE("Failed to set Global MediaContents reference");\r
+        NS_LOGE ("Failed to set Global MediaContents reference");\r
         return JNI_ERR;\r
     }\r
     jclass localTopicState = env->FindClass(\r
                                  "org/iotivity/service/ns/common/Topic$TopicState");\r
     if (!localTopicState)\r
     {\r
-        LOGE("Failed to get local TopicState enum");\r
+        NS_LOGE ("Failed to get local TopicState enum");\r
         return JNI_ERR;\r
     }\r
     g_cls_TopicState = (jclass) (env->NewGlobalRef(localTopicState));\r
     if (!g_cls_TopicState)\r
     {\r
-        LOGE("Failed to set Global TopicState reference");\r
+        NS_LOGE ("Failed to set Global TopicState reference");\r
         return JNI_ERR;\r
     }\r
 \r
@@ -1380,13 +1593,13 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
                             "org/iotivity/service/ns/common/Topic");\r
     if (!localTopic)\r
     {\r
-        LOGE("Failed to get local TopicState enum");\r
+        NS_LOGE ("Failed to get local TopicState enum");\r
         return JNI_ERR;\r
     }\r
     g_cls_Topic = (jclass) (env->NewGlobalRef(localTopic));\r
     if (!g_cls_Topic)\r
     {\r
-        LOGE("Failed to set Global Topic reference");\r
+        NS_LOGE ("Failed to set Global Topic reference");\r
         return JNI_ERR;\r
     }\r
 \r
@@ -1394,13 +1607,13 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
                                   "org/iotivity/service/ns/common/Message$MessageType");\r
     if (!localMessageType)\r
     {\r
-        LOGE("Failed to get local Message Type class");\r
+        NS_LOGE ("Failed to get local Message Type class");\r
         return JNI_ERR;\r
     }\r
     g_cls_Message_Type = (jclass) (env->NewGlobalRef(localMessageType));\r
     if (!g_cls_Message_Type)\r
     {\r
-        LOGE("Failed to set Global Message Type reference");\r
+        NS_LOGE ("Failed to set Global Message Type reference");\r
         return JNI_ERR;\r
     }\r
 \r
@@ -1408,13 +1621,13 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
                                     "org/iotivity/service/ns/consumer/Provider$ProviderState");\r
     if (!localProviderState)\r
     {\r
-        LOGE("Failed to get localProviderState  Type class");\r
+        NS_LOGE ("Failed to get localProviderState  Type class");\r
         return JNI_ERR;\r
     }\r
     g_cls_ProviderState = (jclass) (env->NewGlobalRef(localProviderState));\r
     if (!g_cls_ProviderState)\r
     {\r
-        LOGE("Failed to set Global ProviderState Type reference");\r
+        NS_LOGE ("Failed to set Global ProviderState Type reference");\r
         return JNI_ERR;\r
     }\r
 \r
@@ -1422,33 +1635,33 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
                                  "org/iotivity/service/ns/common/TopicsList");\r
     if (!localTopicsList)\r
     {\r
-        LOGE("Failed to get local Topic class");\r
+        NS_LOGE ("Failed to get local Topic class");\r
         return JNI_ERR;\r
     }\r
     g_cls_TopicsList = (jclass) (env->NewGlobalRef(localTopicsList));\r
     if (!g_cls_TopicsList)\r
     {\r
-        LOGE("Failed to set Global TopicsList reference");\r
+        NS_LOGE ("Failed to set Global TopicsList reference");\r
         return JNI_ERR;\r
     }\r
     //OcRepresentation\r
     jclass localOcRepresentation = env->FindClass("org/iotivity/base/OcRepresentation");\r
     if (!localOcRepresentation)\r
     {\r
-        LOGE("Failed to get local OcRepresentation class");\r
+        NS_LOGE ("Failed to get local OcRepresentation class");\r
         return JNI_ERR;\r
     }\r
     g_cls_OcRepresentation = (jclass) env->NewGlobalRef(localOcRepresentation);\r
     if (!g_cls_OcRepresentation)\r
     {\r
-        LOGE("Failed to set Global OcRepresentation reference");\r
+        NS_LOGE ("Failed to set Global OcRepresentation reference");\r
         return JNI_ERR;\r
     }\r
 \r
     g_mid_OcRepresentation_N_ctor_bool = env->GetMethodID(g_cls_OcRepresentation, "<init>", "(JZ)V");\r
     if (!g_mid_OcRepresentation_N_ctor_bool)\r
     {\r
-        LOGE("Failed to get Global OcRepresentation Constructor reference");\r
+        NS_LOGE ("Failed to get Global OcRepresentation Constructor reference");\r
         return JNI_ERR;\r
     }\r
 \r
@@ -1469,12 +1682,12 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
 \r
 JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *jvm, void *reserved)\r
 {\r
-    LOGI("ConsumerService_JNI_OnUnload");\r
-    JNIEnv *env;\r
+    NS_LOGI ("ConsumerService_JNI_OnUnload");\r
+    JNIEnv *env = NULL;\r
 \r
     if (jvm->GetEnv((void **)&env, JNI_CURRENT_VERSION) != JNI_OK)\r
     {\r
-        LOGE("Failed to get the environment using GetEnv()");\r
+        NS_LOGE ("Failed to get the environment using GetEnv()");\r
         return ;\r
     }\r
 \r
index 97ae3d8..cbcbce1 100755 (executable)
@@ -47,14 +47,23 @@ JNIEXPORT void JNICALL Java_org_iotivity_service_ns_consumer_ConsumerService_nat
 /*\r
  * Class:     org_iotivity_service_ns_consumer_ConsumerService\r
  * Method:    nativeEnableRemoteService\r
- * Signature: (Ljava/lang/String;)I\r
+ * Signature: (Ljava/lang/String;)V\r
  */\r
-JNIEXPORT jint JNICALL\r
+JNIEXPORT void JNICALL\r
 Java_org_iotivity_service_ns_consumer_ConsumerService_nativeEnableRemoteService\r
 (JNIEnv *, jobject, jstring);\r
 \r
 /*\r
  * Class:     org_iotivity_service_ns_consumer_ConsumerService\r
+ * Method:    nativeSubscribeMQService\r
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)V\r
+ */\r
+JNIEXPORT void JNICALL\r
+Java_org_iotivity_service_ns_consumer_ConsumerService_nativeSubscribeMQService\r
+(JNIEnv *, jobject, jstring, jstring);\r
+\r
+/*\r
+ * Class:     org_iotivity_service_ns_consumer_ConsumerService\r
  * Method:    nativeRescanProvider\r
  * Signature: ()V\r
  */\r
@@ -69,6 +78,15 @@ JNIEXPORT void JNICALL Java_org_iotivity_service_ns_consumer_ConsumerService_nat
 JNIEXPORT void JNICALL Java_org_iotivity_service_ns_consumer_Provider_nativeSubscribe\r
 (JNIEnv *, jobject);\r
 \r
+\r
+/*\r
+ * Class:     org_iotivity_service_ns_consumer_Provider\r
+ * Method:    nativeUnsubscribe\r
+ * Signature: ()V\r
+ */\r
+JNIEXPORT void JNICALL Java_org_iotivity_service_ns_consumer_Provider_nativeUnsubscribe\r
+(JNIEnv *, jobject);\r
+\r
 /*\r
  * Class:     org_iotivity_service_ns_consumer_Provider\r
  * Method:    nativeSendSyncInfo\r
@@ -80,7 +98,7 @@ JNIEXPORT void JNICALL Java_org_iotivity_service_ns_consumer_Provider_nativeSend
 /*\r
  * Class:     org_iotivity_service_ns_consumer_Provider\r
  * Method:    nativeSetListener\r
- * Signature: (Lorg/iotivity/service/ns/consumer/Provider/OnProviderStateListener;Lorg/iotivity/service/ns/consumer/Provider/OnMessageReceivedListner;Lorg/iotivity/service/ns/consumer/Provider/OnSyncInfoReceivedListner;)V\r
+ * Signature: (Lorg/iotivity/service/ns/consumer/Provider/OnProviderStateListener;Lorg/iotivity/service/ns/consumer/Provider/OnMessageReceivedListener;Lorg/iotivity/service/ns/consumer/Provider/OnSyncInfoReceivedListener;)V\r
  */\r
 JNIEXPORT void JNICALL Java_org_iotivity_service_ns_consumer_Provider_nativeSetListener\r
 (JNIEnv *, jobject, jobject, jobject, jobject);\r
@@ -96,9 +114,9 @@ JNIEXPORT jobject JNICALL Java_org_iotivity_service_ns_consumer_Provider_nativeG
 /*\r
  * Class:     org_iotivity_service_ns_consumer_Provider\r
  * Method:    nativeUpdateTopicList\r
- * Signature: (Lorg/iotivity/service/ns/common/TopicsList;)I\r
+ * Signature: (Lorg/iotivity/service/ns/common/TopicsList;)V\r
  */\r
-JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_consumer_Provider_nativeUpdateTopicList\r
+JNIEXPORT void JNICALL Java_org_iotivity_service_ns_consumer_Provider_nativeUpdateTopicList\r
 (JNIEnv *, jobject, jobject);\r
 \r
 /*\r
@@ -117,6 +135,14 @@ JNIEXPORT jobject JNICALL Java_org_iotivity_service_ns_consumer_Provider_nativeG
 JNIEXPORT jboolean JNICALL Java_org_iotivity_service_ns_consumer_Provider_nativeIsSubscribed\r
 (JNIEnv *, jobject);\r
 \r
+/*\r
+ * Class:     org_iotivity_service_ns_consumer_Provider\r
+ * Method:    nativeDispose\r
+ * Signature: ()V\r
+ */\r
+JNIEXPORT void JNICALL Java_org_iotivity_service_ns_consumer_Provider_nativeDispose\r
+(JNIEnv *env, jobject object);\r
+\r
 #ifdef __cplusplus\r
 }\r
 #endif\r
index 3e96fe5..2c4ee96 100755 (executable)
@@ -20,6 +20,7 @@
 
 #include "JniNotificationProvider.h"
 #include "NSProviderService.h"
+#include "NSException.h"
 #include "JniOcRepresentation.h"
 
 static JavaVM *g_jvm_provider = NULL;
@@ -51,7 +52,7 @@ static JNIEnv *GetJNIEnv(jint *ret)
         case JNI_EDETACHED:
             if (g_jvm_provider->AttachCurrentThread(&env, NULL) != JNI_OK)
             {
-                LOGE ("Failed to get the environment");
+                NS_LOGE ("Failed to get the environment");
                 return NULL;
             }
             else
@@ -59,16 +60,17 @@ static JNIEnv *GetJNIEnv(jint *ret)
                 return env;
             }
         case JNI_EVERSION:
-            LOGE ("JNI version is not supported");
+            NS_LOGE ("JNI version is not supported");
+            return NULL;
         default:
-            LOGE ("Failed to get the environment");
+            NS_LOGE ("Failed to get the environment");
             return NULL;
     }
 }
 
-OIC::Service::NSMessage *getNativeMessage(JNIEnv *env, jobject jMsg)
+OIC::Service::NSMessage getNativeMessage(JNIEnv *env, jobject jMsg)
 {
-    LOGD("JNIProviderService: getMessage - IN");
+    NS_LOGD ("JNIProviderService: getMessage - IN");
 
     jclass cls = env->GetObjectClass( jMsg);
 
@@ -76,7 +78,7 @@ OIC::Service::NSMessage *getNativeMessage(JNIEnv *env, jobject jMsg)
     jclass cls_messageType = (jclass) (env->NewLocalRef(g_cls_Message_Type));
     if (!cls_messageType)
     {
-        LOGE ("Failed to Get ObjectClass for Message Type");
+        ThrowNSException(JNI_INVALID_VALUE, "Failed to Get ObjectClass for Message Type");
         return nullptr;
     }
     jmethodID mid = env->GetMethodID(cls_messageType, "ordinal", "()I");
@@ -84,25 +86,25 @@ OIC::Service::NSMessage *getNativeMessage(JNIEnv *env, jobject jMsg)
                                          "Lorg/iotivity/service/ns/common/Message$MessageType;");
     if (fid_type == NULL)
     {
-        LOGE("Error: jfieldID for message type  is null");
+        ThrowNSException(JNI_INVALID_VALUE, "Error: jfieldID for message type  is null");
         return nullptr;
     }
     jobject jobj = env->GetObjectField( jMsg, fid_type);
     if (jobj == NULL)
     {
-        LOGE("Error: object of field  Message Type is null");
+        ThrowNSException(JNI_INVALID_VALUE, "Error: object of field  Message Type is null");
         return nullptr;
     }
     jint jtype = env->CallIntMethod(jobj, mid);
     OIC::Service::NSMessage::NSMessageType  type = (OIC::Service::NSMessage::NSMessageType) jtype;
 
-    LOGD("Message Type: %ld\n", (long )type);
+    NS_LOGD ("Message Type: %ld\n", (long )type);
 
     // Message Time
     jfieldID fid_tm = env->GetFieldID( cls, "mTime", "Ljava/lang/String;");
     if (fid_tm == NULL)
     {
-        LOGE("Error: jfieldID for message time is null");
+        ThrowNSException(JNI_INVALID_VALUE, "Error: jfieldID for message time is null");
         return nullptr;
     }
     jstring jtime = (jstring)env->GetObjectField( jMsg, fid_tm);
@@ -113,27 +115,27 @@ OIC::Service::NSMessage *getNativeMessage(JNIEnv *env, jobject jMsg)
     }
     else
     {
-        LOGD("Info: messageTitle is null");
+        NS_LOGD ("Info: messageTitle is null");
     }
-    LOGD("Message Time: %s\n", time);
+    NS_LOGD ("Message Time: %s\n", time);
 
     // Message TTL
     jfieldID fid_ttl = env->GetFieldID( cls, "mTTL", "J");
     if (fid_ttl == NULL)
     {
-        LOGE("Error: jfieldID for message ttl is null");
+        ThrowNSException(JNI_INVALID_VALUE, "Error: jfieldID for message ttl is null");
         return nullptr;
     }
 
     jlong jttl = (jlong) env->GetLongField( jMsg, fid_ttl);
     uint64_t  ttl = jttl;
-    LOGD("TTL: %d\n", ttl);
+    NS_LOGD ("TTL: %lld\n", ttl);
 
     // Message Title
     jfieldID fid_title = env->GetFieldID( cls, "mTitle", "Ljava/lang/String;");
     if (fid_title == NULL)
     {
-        LOGE("Error: jfieldID for message title is null");
+        ThrowNSException(JNI_INVALID_VALUE, "Error: jfieldID for message title is null");
         return nullptr;
     }
     jstring jmsgTitle = (jstring)env->GetObjectField( jMsg, fid_title);
@@ -144,15 +146,15 @@ OIC::Service::NSMessage *getNativeMessage(JNIEnv *env, jobject jMsg)
     }
     else
     {
-        LOGD("Info: messageTitle is null");
+        NS_LOGD ("Info: messageTitle is null");
     }
-    LOGD("Message Title: %s\n", messageTitle);
+    NS_LOGD ("Message Title: %s\n", messageTitle);
 
     // Message Content Text
     jfieldID fid_body = env->GetFieldID( cls, "mContentText", "Ljava/lang/String;");
     if (fid_body == NULL)
     {
-        LOGE("Error: jfieldID for message context Text is null");
+        ThrowNSException(JNI_INVALID_VALUE, "Error: jfieldID for message context Text is null");
         return nullptr;
     }
     jstring jmsgBody = (jstring)env->GetObjectField( jMsg, fid_body);
@@ -163,15 +165,15 @@ OIC::Service::NSMessage *getNativeMessage(JNIEnv *env, jobject jMsg)
     }
     else
     {
-        LOGD("Info: messageBody is null");
+        NS_LOGD ("Info: messageBody is null");
     }
-    LOGD("Message Body: %s\n", messageBody);
+    NS_LOGD ("Message Body: %s\n", messageBody);
 
     // Message Source
     jfieldID fid_source = env->GetFieldID( cls, "mSourceName", "Ljava/lang/String;");
     if (fid_source == NULL)
     {
-        LOGE("Error: jfieldID for message source is null");
+        ThrowNSException(JNI_INVALID_VALUE, "Error: jfieldID for message source is null");
         return nullptr;
     }
     jstring jmsgSource = (jstring)env->GetObjectField( jMsg, fid_source);
@@ -182,15 +184,15 @@ OIC::Service::NSMessage *getNativeMessage(JNIEnv *env, jobject jMsg)
     }
     else
     {
-        LOGD("Info: messageSource is null");
+        NS_LOGD ("Info: messageSource is null");
     }
-    LOGD("Message Source: %s\n", messageSource);
+    NS_LOGD ("Message Source: %s\n", messageSource);
 
     // Message Topic
     jfieldID fid_topic = env->GetFieldID( cls, "mTopic", "Ljava/lang/String;");
     if (fid_topic == NULL)
     {
-        LOGE("Error: jfieldID for topic  is null");
+        ThrowNSException(JNI_INVALID_VALUE, "Error: jfieldID for topic  is null");
         return nullptr;
     }
     jstring jtopic = (jstring)env->GetObjectField( jMsg, fid_topic);
@@ -201,36 +203,36 @@ OIC::Service::NSMessage *getNativeMessage(JNIEnv *env, jobject jMsg)
     }
     else
     {
-        LOGD("Info: topic is null");
+        NS_LOGD ("Info: topic is null");
     }
-    LOGD("Topic : %s\n", topic);
+    NS_LOGD ("Topic : %s\n", topic);
 
     // Message MediaContents
     jfieldID fid_media = env->GetFieldID( cls, "mMediaContents",
                                           "Lorg/iotivity/service/ns/common/MediaContents;");
     if (fid_media == NULL)
     {
-        LOGE("Error: jfieldID for MediaContents is null");
+        ThrowNSException(JNI_INVALID_VALUE, "Error: jfieldID for MediaContents is null");
         return nullptr;
     }
     jobject jmedia = env->GetObjectField( jMsg, fid_media);
     OIC::Service::NSMediaContents *media = nullptr;
     if (jmedia == NULL)
     {
-        LOGD("Info: jmedia object of MediaContents inside Message is null");
+        NS_LOGD ("Info: jmedia object of MediaContents inside Message is null");
     }
     else
     {
         jclass cls_MediaContents = (jclass) (env->NewLocalRef(g_cls_MediaContents));
         if (!cls_MediaContents)
         {
-            LOGE ("Failed to Get ObjectClass for class MediaContents");
+            ThrowNSException(JNI_INVALID_VALUE, "Failed to Get ObjectClass for class MediaContents");
             return nullptr;
         }
         jfieldID fid_icon = env->GetFieldID( cls_MediaContents, "mIconImage", "Ljava/lang/String;");
         if (fid_icon == NULL)
         {
-            LOGE("Error: jfieldID for iconImage is null");
+            ThrowNSException(JNI_INVALID_VALUE, "Error: jfieldID for iconImage is null");
             return nullptr;
         }
         jstring jiconImage = (jstring)env->GetObjectField( jmedia, fid_icon);
@@ -243,10 +245,10 @@ OIC::Service::NSMessage *getNativeMessage(JNIEnv *env, jobject jMsg)
         }
         else
         {
-            LOGD("Info: iconImage is null");
+            NS_LOGD ("Info: iconImage is null");
         }
         env->DeleteLocalRef(cls_MediaContents);
-        LOGD("iconImage: %s\n", iconImage);
+        NS_LOGD ("iconImage: %s\n", iconImage);
     }
 
     // Message ExtraInfo
@@ -254,60 +256,90 @@ OIC::Service::NSMessage *getNativeMessage(JNIEnv *env, jobject jMsg)
                              "Lorg/iotivity/base/OcRepresentation;");
     if (fid_extraInfo == NULL)
     {
-        LOGE("Error: jfieldID for mExtraInfo is null");
+        ThrowNSException(JNI_INVALID_VALUE, "Error: jfieldID for mExtraInfo is null");
         return nullptr;
     }
     jobject jExtraInfo = env->GetObjectField( jMsg, fid_extraInfo);
     OC::OCRepresentation *representation = nullptr;
     if (jExtraInfo == NULL)
     {
-        LOGE("Error: jExtraInfo object of Message is null");
+        NS_LOGE ("Error: jExtraInfo object of Message is null");
     }
     else
     {
         representation = GetHandle<OC::OCRepresentation>(env, jExtraInfo);
         if (env->ExceptionCheck())
         {
-            LOGE("Failed to get native handle from OcRepresentation");
+            NS_LOGE ("Failed to get native handle from OcRepresentation");
         }
         if (!representation)
         {
-            LOGE("Failed to get native object OcRepresentation");
+            NS_LOGE ("Failed to get native object OcRepresentation");
         }
     }
 
-    OIC::Service::NSMessage *nsMsg;
-    jfieldID nativeHandle = env->GetFieldID(cls, "mNativeHandle", "J");
-    if (!nativeHandle)
+    // Message Id
+    jfieldID fid_mid = env->GetFieldID( cls, "mMessageId", "J");
+    if (fid_mid == NULL)
+    {
+        ThrowNSException(JNI_INVALID_VALUE, "Error: jfieldID for message mMessageId is null");
+        return nullptr;
+    }
+
+    jlong jId = (jlong) env->GetLongField( jMsg, fid_mid);
+    uint64_t  jmId = jId;
+    NS_LOGD ("Message Id: %lld\n", jmId);
+
+    // Provider Id
+    jfieldID fid_pid = env->GetFieldID( cls, "mProviderId", "Ljava/lang/String;");
+    if (fid_pid == NULL)
     {
-        LOGE("Error: fieldID for mNativeHandle is null");
+        ThrowNSException(JNI_INVALID_VALUE, "Error: jfieldID for message mProviderId is null");
         return nullptr;
     }
-    jlong jMessage = env->GetLongField(jMsg, nativeHandle);
-    if (jMessage)
+    jstring jProId = (jstring)env->GetObjectField( jMsg, fid_pid);
+    const char *jpId = "";
+    if (jProId)
     {
-        LOGD ("calling sendMessage on mNativeHandle");
-        nsMsg = (OIC::Service::NSMessage *) (jMessage);
+        jpId = env->GetStringUTFChars( jProId, NULL);
     }
     else
     {
-        nsMsg = OIC::Service::NSProviderService::getInstance()->createMessage();
+        NS_LOGD ("Info: messageSource is null");
     }
+    NS_LOGD ("Provider Id : %s\n", jpId);
+
+
+    NSMessage *mesg = new NSMessage;
+    mesg->messageId = jmId;
+    mesg->providerId[0] = '\0';
+    strncat(mesg->providerId, jpId, NS_UTILS_UUID_STRING_SIZE - 1);
+
+    mesg->dateTime = nullptr;
+    mesg->title = nullptr;
+    mesg->contentText = nullptr;
+    mesg->sourceName = nullptr;
+    mesg->mediaContents = nullptr;
+    mesg->topic = nullptr;
+    mesg->extraInfo = nullptr;
+
+    OIC::Service::NSMessage nsMsg(mesg);
+    NS_LOGD ("Created NSMessage");
 
-    nsMsg->setType(type);
-    nsMsg->setTime(std::string(time));
-    nsMsg->setTTL(ttl);
-    nsMsg->setTitle(std::string(messageTitle));
-    nsMsg->setContentText(std::string(messageBody));
-    nsMsg->setSourceName(std::string(messageSource));
-    if(media != nullptr)
+    nsMsg.setType(type);
+    nsMsg.setTime(std::string(time));
+    nsMsg.setTTL(ttl);
+    nsMsg.setTitle(std::string(messageTitle));
+    nsMsg.setContentText(std::string(messageBody));
+    nsMsg.setSourceName(std::string(messageSource));
+    if (media != nullptr)
     {
-        nsMsg->setMediaContents(media);
+        nsMsg.setMediaContents(media);
     }
-    nsMsg->setTopic(std::string(topic));
+    nsMsg.setTopic(std::string(topic));
     if (representation != nullptr)
     {
-        nsMsg->setExtraInfo(*representation);
+        nsMsg.setExtraInfo(*representation);
     }
 
     env->DeleteLocalRef(cls_messageType);
@@ -332,73 +364,79 @@ OIC::Service::NSMessage *getNativeMessage(JNIEnv *env, jobject jMsg)
     {
         env->ReleaseStringUTFChars(jtopic, topic);
     }
-
-    LOGD("JNIProviderService: getMessage - OUT");
+    delete mesg;
+    NS_LOGD ("JNIProviderService: getMessage - OUT");
     return nsMsg;
 
 }
 
 jobject getJavaMessageType(JNIEnv *env, OIC::Service::NSMessage::NSMessageType type)
 {
-    LOGD ("JNIProviderService: getJavaMessageType - IN");
+    NS_LOGD ("JNIProviderService: getJavaMessageType - IN");
+    jobject messageType = NULL;
     switch (type)
     {
         case OIC::Service::NSMessage::NSMessageType::NS_MESSAGE_ALERT:
             {
                 static jfieldID fieldID = env->GetStaticFieldID(g_cls_Message_Type,
                                           "ALERT", "Lorg/iotivity/service/ns/common/Message$MessageType;");
-                return env->GetStaticObjectField(g_cls_Message_Type, fieldID);
+                messageType = env->GetStaticObjectField(g_cls_Message_Type, fieldID);
+                break;
             }
         case OIC::Service::NSMessage::NSMessageType::NS_MESSAGE_NOTICE:
             {
                 static jfieldID fieldID = env->GetStaticFieldID(g_cls_Message_Type,
                                           "NOTICE", "Lorg/iotivity/service/ns/common/Message$MessageType;");
-                return env->GetStaticObjectField(g_cls_Message_Type, fieldID);
+                messageType = env->GetStaticObjectField(g_cls_Message_Type, fieldID);
+                break;
             }
         case OIC::Service::NSMessage::NSMessageType::NS_MESSAGE_EVENT:
             {
                 static jfieldID fieldID = env->GetStaticFieldID(g_cls_Message_Type,
                                           "EVENT", "Lorg/iotivity/service/ns/common/Message$MessageType;");
-                return env->GetStaticObjectField(g_cls_Message_Type, fieldID);
+                messageType = env->GetStaticObjectField(g_cls_Message_Type, fieldID);
+                break;
             }
         case OIC::Service::NSMessage::NSMessageType::NS_MESSAGE_INFO:
             {
                 static jfieldID fieldID = env->GetStaticFieldID(g_cls_Message_Type,
                                           "INFO", "Lorg/iotivity/service/ns/common/Message$MessageType;");
-                return env->GetStaticObjectField(g_cls_Message_Type, fieldID);
+                messageType = env->GetStaticObjectField(g_cls_Message_Type, fieldID);
+                break;
             }
         default:
-            return NULL;
+            {
+                messageType = NULL;
+                break;
+            }
     }
-    LOGD ("JNIProviderService: getJavaMessageType - OUT");
-    return NULL;
+    NS_LOGD ("JNIProviderService: getJavaMessageType - OUT");
+    return messageType;
 }
 
-jobject getJavaMessage(JNIEnv *env, OIC::Service::NSMessage *message)
+jobject getJavaMessage(JNIEnv *env, OIC::Service::NSMessage message)
 {
-    LOGD ("JNIProviderService: getJavaMessage - IN");
-
-    LOGD ("id : %llu\n", message->getMessageId());
-    LOGD ("title : %s\n", message->getTitle().c_str());
-    LOGD ("content : %s\n", message->getContentText().c_str());
-    LOGD ("source : %s\n", message->getSourceName().c_str());
+    NS_LOGD ("JNIProviderService: getJavaMessage - IN");
 
-    jlong jMessageId = (jlong) message->getMessageId();
-    jstring jProviderId = env->NewStringUTF(message->getProviderId().c_str());
-    jstring jTitle = env->NewStringUTF(message->getTitle().c_str());
-    jstring jContentText = env->NewStringUTF(message->getContentText().c_str());
-    jstring jSourceName = env->NewStringUTF(message->getSourceName().c_str());
-    jstring jTopic = env->NewStringUTF(message->getTopic().c_str());
+    NS_LOGD ("id : %llu\n", message.getMessageId());
+    NS_LOGD ("title : %s\n", message.getTitle().c_str());
+    NS_LOGD ("content : %s\n", message.getContentText().c_str());
+    NS_LOGD ("source : %s\n", message.getSourceName().c_str());
 
-    jstring jTime = env->NewStringUTF(message->getTime().c_str());
-    jlong jTTL = (jlong) message->getTTL();
+    jlong jMessageId = (jlong) message.getMessageId();
+    jstring jProviderId = env->NewStringUTF(message.getProviderId().c_str());
+    jstring jTitle = env->NewStringUTF(message.getTitle().c_str());
+    jstring jContentText = env->NewStringUTF(message.getContentText().c_str());
+    jstring jSourceName = env->NewStringUTF(message.getSourceName().c_str());
+    jstring jTopic = env->NewStringUTF(message.getTopic().c_str());
 
-    jlong pMessage = (long) message;
+    jstring jTime = env->NewStringUTF(message.getTime().c_str());
+    jlong jTTL = (jlong) message.getTTL();
 
     jclass cls_message = (jclass) (env->NewLocalRef(g_cls_Message));
     if (!cls_message)
     {
-        LOGE ("Failed to Get ObjectClass for Message");
+        NS_LOGE ("Failed to Get ObjectClass for Message");
         return NULL ;
     }
     jmethodID mid_message = env->GetMethodID(
@@ -406,28 +444,21 @@ jobject getJavaMessage(JNIEnv *env, OIC::Service::NSMessage *message)
                                 "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
     if (!mid_message)
     {
-        LOGE ("Failed to Get MethodID for Message<init>");
+        NS_LOGE ("Failed to Get MethodID for Message<init>");
         return NULL;
     }
     jobject obj_message = env->NewObject(cls_message, mid_message,
                                          jTitle, jContentText, jSourceName);
     if (!obj_message)
     {
-        LOGE ("Failed to Get Java Object for Message");
+        NS_LOGE ("Failed to Get Java Object for Message");
         return NULL;
     }
-    jfieldID fid_nativeHandle = env->GetFieldID(cls_message, "mNativeHandle", "J");
-    if (!fid_nativeHandle)
-    {
-        LOGE("Failed to get nativeHandle for Message");
-        return NULL;
-    }
-    env->SetLongField(obj_message, fid_nativeHandle, pMessage);
 
     jfieldID fid_messageId = env->GetFieldID(cls_message, "mMessageId", "J");
     if (!fid_messageId)
     {
-        LOGE("Failed to get field MessageID for Message");
+        NS_LOGE ("Failed to get field MessageID for Message");
         return NULL;
     }
     env->SetLongField(obj_message, fid_messageId, jMessageId);
@@ -435,7 +466,7 @@ jobject getJavaMessage(JNIEnv *env, OIC::Service::NSMessage *message)
     jfieldID fid_providerId = env->GetFieldID(cls_message, "mProviderId", "Ljava/lang/String;");
     if (!fid_providerId)
     {
-        LOGE("Failed to get field ProviderID for Message");
+        NS_LOGE ("Failed to get field ProviderID for Message");
         return NULL;
     }
     env->SetObjectField(obj_message, fid_providerId, jProviderId);
@@ -443,7 +474,7 @@ jobject getJavaMessage(JNIEnv *env, OIC::Service::NSMessage *message)
     jfieldID fid_time = env->GetFieldID(cls_message, "mTime", "Ljava/lang/String;");
     if (!fid_time)
     {
-        LOGE("Failed to get field Time for Message");
+        NS_LOGE ("Failed to get field Time for Message");
         return NULL;
     }
     env->SetObjectField(obj_message, fid_time, jTime);
@@ -451,7 +482,7 @@ jobject getJavaMessage(JNIEnv *env, OIC::Service::NSMessage *message)
     jfieldID fid_ttl = env->GetFieldID(cls_message, "mTTL", "J");
     if (!fid_ttl)
     {
-        LOGE("Failed to get field TTL for Message");
+        NS_LOGE ("Failed to get field TTL for Message");
         return NULL;
     }
     env->SetLongField(obj_message, fid_ttl, jTTL);
@@ -459,26 +490,26 @@ jobject getJavaMessage(JNIEnv *env, OIC::Service::NSMessage *message)
     jfieldID fid_topic = env->GetFieldID(cls_message, "mTopic", "Ljava/lang/String;");
     if (!fid_topic)
     {
-        LOGE("Failed to get mTopic for Message");
+        NS_LOGE ("Failed to get mTopic for Message");
         return NULL;
     }
     env->SetObjectField(obj_message, fid_topic, jTopic);
 
-    OIC::Service::NSMediaContents *mediaCont = message->getMediaContents();
+    OIC::Service::NSMediaContents *mediaCont = message.getMediaContents();
     if (mediaCont != nullptr)
     {
         jstring jIconImage = env->NewStringUTF(mediaCont->getIconImage().c_str());
         jclass cls_mediaContents = (jclass) (env->NewLocalRef(g_cls_MediaContents));
         if (!cls_mediaContents)
         {
-            LOGE ("Failed to Get ObjectClass for MediaContents");
+            NS_LOGE ("Failed to Get ObjectClass for MediaContents");
             return NULL;
         }
         jmethodID mid_mediaContents = env->GetMethodID(
                                           cls_mediaContents, "<init>", "(Ljava/lang/String;)V");
         if (!mid_mediaContents)
         {
-            LOGE ("Failed to Get MethodID for MediaContents<init>");
+            NS_LOGE ("Failed to Get MethodID for MediaContents<init>");
             return NULL;
         }
         jobject obj_mediaContents = env->NewObject(cls_mediaContents, mid_mediaContents,
@@ -488,67 +519,68 @@ jobject getJavaMessage(JNIEnv *env, OIC::Service::NSMessage *message)
                                      "Lorg/iotivity/service/ns/common/MediaContents;");
         if (!fid_mediaContents)
         {
-            LOGE("Failed to get field mediaContents for Message");
+            NS_LOGE ("Failed to get field mediaContents for Message");
             return NULL;
         }
         env->SetObjectField(obj_message, fid_mediaContents, obj_mediaContents);
 
     }
 
-    jobject jType = getJavaMessageType(env, message->getType());
+    jobject jType = getJavaMessageType(env, message.getType());
     if (jType)
     {
         jfieldID fid_type = env->GetFieldID(cls_message, "mType",
                                             "Lorg/iotivity/service/ns/common/Message$MessageType;");
         if (!fid_type)
         {
-            LOGE("Failed to get field Type for Message");
+            NS_LOGE ("Failed to get field Type for Message");
             return NULL;
         }
         env->SetObjectField(obj_message, fid_type, jType);
     }
 
-    LOGD("Reading OCRepresentation Object from Native");
-    OC::OCRepresentation *ocRepresentation = new OC::OCRepresentation(message->getExtraInfo());
+    NS_LOGD ("Reading OCRepresentation Object from Native");
+    OC::OCRepresentation *ocRepresentation = new OC::OCRepresentation(message.getExtraInfo());
     jlong handle = reinterpret_cast<jlong>(ocRepresentation);
     jobject jRepresentation = env->NewObject(g_cls_OcRepresentation, g_mid_OcRepresentation_N_ctor_bool,
                               handle, true);
     if (!jRepresentation)
     {
-        LOGE("Failed to create OcRepresentation");
+        NS_LOGE ("Failed to create OcRepresentation");
         delete ocRepresentation;
     }
     else
     {
-        LOGD("Created OCRepresentation Object from Native");
+        NS_LOGD ("Created OCRepresentation Object from Native");
     }
     jfieldID fid_extraInfo = env->GetFieldID(cls_message, "mExtraInfo",
                              "Lorg/iotivity/base/OcRepresentation;");
     if (!fid_extraInfo)
     {
-        LOGE("Failed to get mExtraInfo for Message");
+        NS_LOGE ("Failed to get mExtraInfo for Message");
         delete ocRepresentation;
         return NULL;
     }
-    LOGD ("setting extraInfo field");
+    NS_LOGD ("setting extraInfo field");
     env->SetObjectField(obj_message, fid_extraInfo, jRepresentation);
 
     env->DeleteLocalRef(cls_message);
-    LOGD ("JNIProviderService: getJavaMessage - OUT");
+    NS_LOGD ("JNIProviderService: getJavaMessage - OUT");
     return obj_message;
 }
 
 jobject getJavaTopicState(JNIEnv *env, OIC::Service::NSTopic::NSTopicState nsState)
 {
-    LOGD("JNIProviderService: getJavaTopicState - IN");
+    NS_LOGD ("JNIProviderService: getJavaTopicState - IN");
 
     // TopicState
     jclass cls_topicState = (jclass) (env->NewLocalRef(g_cls_TopicState));
     if (!cls_topicState)
     {
-        LOGE ("Failed to Get ObjectClass for TopicState Type");
+        NS_LOGE ("Failed to Get ObjectClass for TopicState Type");
         return NULL;
     }
+    jobject topicState = NULL;
 
     switch (nsState)
     {
@@ -556,128 +588,148 @@ jobject getJavaTopicState(JNIEnv *env, OIC::Service::NSTopic::NSTopicState nsSta
             {
                 static jfieldID fieldID = env->GetStaticFieldID(cls_topicState,
                                           "UNSUBSCRIBED", "Lorg/iotivity/service/ns/common/Topic$TopicState;");
-                return env->GetStaticObjectField(cls_topicState, fieldID);
+                topicState = env->GetStaticObjectField(cls_topicState, fieldID);
+                break;
             }
         case OIC::Service::NSTopic::NSTopicState::SUBSCRIBED:
             {
                 static jfieldID fieldID = env->GetStaticFieldID(cls_topicState,
                                           "SUBSCRIBED", "Lorg/iotivity/service/ns/common/Topic$TopicState;");
-                return env->GetStaticObjectField(cls_topicState, fieldID);
+                topicState = env->GetStaticObjectField(cls_topicState, fieldID);
+                break;
             }
         default:
-            return NULL;
-
+            {
+                topicState = NULL;
+                break;
+            }
     }
 
-    LOGD("JNIProviderService: getJavaTopicState - OUT");
-    return NULL;
+    NS_LOGD ("JNIProviderService: getJavaTopicState - OUT");
+    return topicState;
 }
 
-jobject getJavaTopicsList(JNIEnv *env, OIC::Service::NSTopicsList *topicList)
+jobject getJavaTopicsList(JNIEnv *env, std::shared_ptr<OIC::Service::NSTopicsList> topicList)
 {
-    LOGD("JNIProviderService: getJavaTopicsList - IN");
+    NS_LOGD ("JNIProviderService: getJavaTopicsList - IN");
     jclass cls_topicList = (jclass) (env->NewLocalRef(g_cls_TopicsList));
     if (!cls_topicList)
     {
-        LOGE ("Failed to Get ObjectClass for TopicsList");
+        NS_LOGE ("Failed to Get ObjectClass for TopicsList");
         return NULL;
     }
     jmethodID mid_topicList = env->GetMethodID(cls_topicList, "<init>", "()V");
     if (!mid_topicList)
     {
-        LOGE ("Failed to Get MethodID for TopicsList<init>");
+        NS_LOGE ("Failed to Get MethodID for TopicsList<init>");
         return NULL;
     }
     jobject obj_topicList = env->NewObject(cls_topicList, mid_topicList);
     if (!obj_topicList)
     {
-        LOGE ("Failed to Get object for TopicsList");
+        NS_LOGE ("Failed to Get object for TopicsList");
         return NULL;
     }
     jmethodID mid_addTopic = env->GetMethodID(cls_topicList, "addTopic",
                              "(Ljava/lang/String;Lorg/iotivity/service/ns/common/Topic$TopicState;)V");
     if (!mid_addTopic)
     {
-        LOGE ("Failed to Get MethodID for addTopic");
+        NS_LOGE ("Failed to Get MethodID for addTopic");
         return NULL;
     }
     for (auto it : topicList->getTopicsList())
     {
-        jobject jState = getJavaTopicState(env, it->getState());
-        std::string topicName = it->getTopicName();
+        jobject jState = getJavaTopicState(env, it.getState());
+        std::string topicName = it.getTopicName();
         jstring jTopicName = env->NewStringUTF(topicName.c_str());
         env->CallVoidMethod(obj_topicList, mid_addTopic, jTopicName, jState);
     }
     env->DeleteLocalRef(cls_topicList);
-    LOGD("JNIProviderService: getJavaTopicsList - OUT");
+    NS_LOGD ("JNIProviderService: getJavaTopicsList - OUT");
     return obj_topicList;
 }
 
 jobject getJavaSyncType(JNIEnv *env, OIC::Service::NSSyncInfo::NSSyncType nsType)
 {
-    LOGD ("JNIProviderService: getJavaSyncType - IN");
+    NS_LOGD ("JNIProviderService: getJavaSyncType - IN");
 
     // SyncType
     jclass cls_SyncType = (jclass) (env->NewLocalRef(g_cls_SyncType));
     if (!cls_SyncType)
     {
-        LOGE ("Failed to Get ObjectClass for SyncType");
+        NS_LOGE ("Failed to Get ObjectClass for SyncType");
         return NULL;
     }
+    jobject syncType = NULL;
     switch (nsType)
     {
         case OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_UNREAD:
             {
                 static jfieldID fieldID = env->GetStaticFieldID(cls_SyncType,
                                           "UNREAD", "Lorg/iotivity/service/ns/common/SyncInfo$SyncType;");
-                return env->GetStaticObjectField(cls_SyncType, fieldID);
+                syncType = env->GetStaticObjectField(cls_SyncType, fieldID);
+                break;
             }
         case OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_READ :
             {
                 static jfieldID fieldID = env->GetStaticFieldID(cls_SyncType,
                                           "READ", "Lorg/iotivity/service/ns/common/SyncInfo$SyncType;");
-                return env->GetStaticObjectField(cls_SyncType, fieldID);
+                syncType = env->GetStaticObjectField(cls_SyncType, fieldID);
+                break;
             }
         case OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_DELETED :
             {
                 static jfieldID fieldID = env->GetStaticFieldID(cls_SyncType,
                                           "DELETED", "Lorg/iotivity/service/ns/common/SyncInfo$SyncType;");
-                return env->GetStaticObjectField(cls_SyncType, fieldID);
+                syncType = env->GetStaticObjectField(cls_SyncType, fieldID);
+                break;
             }
         default:
-            return NULL;
+            {
+                syncType = NULL;
+                break;
+            }
     }
 
-    LOGD ("JNIProviderService: getJavaSyncType - OUT");
-    return NULL;
+    NS_LOGD ("JNIProviderService: getJavaSyncType - OUT");
+    return syncType;
 }
 
 
-void onSubscribeListenerCb(OIC::Service::NSConsumer *consumer)
+void onSubscribeListenerCb(std::shared_ptr<OIC::Service::NSConsumer> consumer)
 {
-    LOGD("JNIProviderService_onSubscribeListenerCb - IN");
+    NS_LOGD ("JNIProviderService_onSubscribeListenerCb - IN");
 
-    jint envRet;
+    jint envRet = 0;;
     JNIEnv *env = GetJNIEnv(&envRet);
-    if (NULL == env) return ;
+    if (NULL == env)
+    {
+        return ;
+    }
 
     jobject jSubscriptionListener = (jobject) env->NewLocalRef(g_obj_subscriptionListener);
     if (!jSubscriptionListener)
     {
-        LOGE ("Failed to Get jSubscriptionListener");
-        if (JNI_EDETACHED == envRet) g_jvm_provider->DetachCurrentThread();
+        NS_LOGE ("Failed to Get jSubscriptionListener");
+        if (JNI_EDETACHED == envRet)
+        {
+            g_jvm_provider->DetachCurrentThread();
+        }
         return ;
     }
 
-    LOGD("consumer ID : %s\n", consumer->getConsumerId().c_str());
+    NS_LOGD ("consumer ID : %s\n", consumer->getConsumerId().c_str());
 
     jstring jConsumerId = env->NewStringUTF( consumer->getConsumerId().c_str());
 
     jclass cls_consumer = (jclass) (env->NewLocalRef(g_cls_Consumer));
     if (!cls_consumer)
     {
-        LOGE ("Failed to Get ObjectClass for Consumer");
-        if (JNI_EDETACHED == envRet) g_jvm_provider->DetachCurrentThread();
+        NS_LOGE ("Failed to Get ObjectClass for Consumer");
+        if (JNI_EDETACHED == envRet)
+        {
+            g_jvm_provider->DetachCurrentThread();
+        }
         return ;
     }
 
@@ -687,8 +739,11 @@ void onSubscribeListenerCb(OIC::Service::NSConsumer *consumer)
                                  "(Ljava/lang/String;)V");
     if (!mid_consumer)
     {
-        LOGE ("Failed to Get MethodID for Consumer<init>");
-        if (JNI_EDETACHED == envRet) g_jvm_provider->DetachCurrentThread();
+        NS_LOGE ("Failed to Get MethodID for Consumer<init>");
+        if (JNI_EDETACHED == envRet)
+        {
+            g_jvm_provider->DetachCurrentThread();
+        }
         return ;
     }
     jobject obj_consumer = env->NewObject( cls_consumer, mid_consumer, jConsumerId);
@@ -696,8 +751,11 @@ void onSubscribeListenerCb(OIC::Service::NSConsumer *consumer)
     jclass cls = env->GetObjectClass( jSubscriptionListener);
     if (!cls)
     {
-        LOGE("Failed to Get ObjectClass of jSubscriptionListener");
-        if (JNI_EDETACHED == envRet) g_jvm_provider->DetachCurrentThread();
+        NS_LOGE ("Failed to Get ObjectClass of jSubscriptionListener");
+        if (JNI_EDETACHED == envRet)
+        {
+            g_jvm_provider->DetachCurrentThread();
+        }
         return;
     }
     jmethodID mid = env->GetMethodID(
@@ -706,52 +764,70 @@ void onSubscribeListenerCb(OIC::Service::NSConsumer *consumer)
                         "(Lorg/iotivity/service/ns/provider/Consumer;)V");
     if (!mid)
     {
-        LOGE("Failed to Get MethodID of onConsumerSubscribed");
-        if (JNI_EDETACHED == envRet) g_jvm_provider->DetachCurrentThread();
+        NS_LOGE ("Failed to Get MethodID of onConsumerSubscribed");
+        if (JNI_EDETACHED == envRet)
+        {
+            g_jvm_provider->DetachCurrentThread();
+        }
         return;
     }
 
     env->CallVoidMethod( jSubscriptionListener, mid, obj_consumer);
     env->DeleteLocalRef(jSubscriptionListener);
     env->DeleteLocalRef(cls_consumer);
-    if (JNI_EDETACHED == envRet) g_jvm_provider->DetachCurrentThread();
-    LOGD("JNIProviderService_onSubscribeListenerCb - OUT");
+    if (JNI_EDETACHED == envRet)
+    {
+        g_jvm_provider->DetachCurrentThread();
+    }
+    NS_LOGD ("JNIProviderService_onSubscribeListenerCb - OUT");
     return;
 }
 
-void onSyncInfoListenerCb(OIC::Service::NSSyncInfo *sync)
+void onSyncInfoListenerCb(OIC::Service::NSSyncInfo sync)
 {
-    LOGD("JNIProviderService_onSyncInfoListenerCb - IN");
+    NS_LOGD ("JNIProviderService_onSyncInfoListenerCb - IN");
 
-    jint envRet;
+    jint envRet = 0;;
     JNIEnv *env = GetJNIEnv(&envRet);
-    if (NULL == env) return ;
+    if (NULL == env)
+    {
+        return ;
+    }
 
     jobject jSyncListener = (jobject) env->NewLocalRef(g_obj_syncListener);
     if (!jSyncListener)
     {
-        LOGE ("Failed to Get jSyncListener");
-        if (JNI_EDETACHED == envRet) g_jvm_provider->DetachCurrentThread();
+        NS_LOGE ("Failed to Get jSyncListener");
+        if (JNI_EDETACHED == envRet)
+        {
+            g_jvm_provider->DetachCurrentThread();
+        }
         return ;
     }
 
-    LOGD("Sync ID : %ld\n", (long) sync->getMessageId());
-    LOGD("Sync STATE : %d\n", (int) sync->getState());
+    NS_LOGD ("Sync ID : %ld\n", (long) sync.getMessageId());
+    NS_LOGD ("Sync STATE : %d\n", (int) sync.getState());
 
-    jlong jMessageId = (long)  sync->getMessageId();
-    jstring jProviderId = env->NewStringUTF(sync->getProviderId().c_str());
-    jobject syncType = getJavaSyncType(env, sync->getState());
+    jlong jMessageId = (long)  sync.getMessageId();
+    jstring jProviderId = env->NewStringUTF(sync.getProviderId().c_str());
+    jobject syncType = getJavaSyncType(env, sync.getState());
     if (!syncType)
     {
-        LOGE ("Failed to Get syncType for SyncInfo");
-        if (JNI_EDETACHED == envRet) g_jvm_provider->DetachCurrentThread();
+        NS_LOGE ("Failed to Get syncType for SyncInfo");
+        if (JNI_EDETACHED == envRet)
+        {
+            g_jvm_provider->DetachCurrentThread();
+        }
         return ;
     }
     jclass cls_SyncInfo = (jclass) (env->NewLocalRef(g_cls_SyncInfo));
     if (!cls_SyncInfo)
     {
-        LOGE ("Failed to Get ObjectClass for SyncInfo");
-        if (JNI_EDETACHED == envRet) g_jvm_provider->DetachCurrentThread();
+        NS_LOGE ("Failed to Get ObjectClass for SyncInfo");
+        if (JNI_EDETACHED == envRet)
+        {
+            g_jvm_provider->DetachCurrentThread();
+        }
         return ;
     }
     jmethodID mid_syncInfo = env->GetMethodID(
@@ -760,8 +836,11 @@ void onSyncInfoListenerCb(OIC::Service::NSSyncInfo *sync)
                                  "(JLjava/lang/String;Lorg/iotivity/service/ns/common/SyncInfo$SyncType;)V");
     if (!mid_syncInfo)
     {
-        LOGE ("Failed to Get MethodID for SyncInfo");
-        if (JNI_EDETACHED == envRet) g_jvm_provider->DetachCurrentThread();
+        NS_LOGE ("Failed to Get MethodID for SyncInfo");
+        if (JNI_EDETACHED == envRet)
+        {
+            g_jvm_provider->DetachCurrentThread();
+        }
         return ;
     }
 
@@ -769,17 +848,23 @@ void onSyncInfoListenerCb(OIC::Service::NSSyncInfo *sync)
                                            jMessageId, jProviderId, syncType);
     if (!obj_syncInfo)
     {
-        LOGE ("Failed to Get Object for SyncInfo");
-        if (JNI_EDETACHED == envRet) g_jvm_provider->DetachCurrentThread();
+        NS_LOGE ("Failed to Get Object for SyncInfo");
+        if (JNI_EDETACHED == envRet)
+        {
+            g_jvm_provider->DetachCurrentThread();
+        }
         return ;
     }
 
     jclass cls = env->GetObjectClass( jSyncListener);
     if (!cls)
     {
-        LOGE("Failed to Get ObjectClass");
-        if (JNI_EDETACHED == envRet) g_jvm_provider->DetachCurrentThread();
-        return;
+        NS_LOGE ("Failed to Get ObjectClass");
+        if (JNI_EDETACHED == envRet)
+        {
+            g_jvm_provider->DetachCurrentThread();
+        }
+        return ;
     }
     jmethodID mid = env->GetMethodID(
                         cls,
@@ -787,31 +872,35 @@ void onSyncInfoListenerCb(OIC::Service::NSSyncInfo *sync)
                         "(Lorg/iotivity/service/ns/common/SyncInfo;)V");
     if (!mid)
     {
-        LOGE("Failed to Get MethodID");
-        if (JNI_EDETACHED == envRet) g_jvm_provider->DetachCurrentThread();
-        return;
+        NS_LOGE ("Failed to Get MethodID");
+        if (JNI_EDETACHED == envRet)
+        {
+            g_jvm_provider->DetachCurrentThread();
+        }
+        return ;
     }
     env->CallVoidMethod( jSyncListener, mid, obj_syncInfo);
 
     env->DeleteLocalRef(jSyncListener);
     env->DeleteLocalRef(cls_SyncInfo);
-    if (JNI_EDETACHED == envRet) g_jvm_provider->DetachCurrentThread();
-
-    LOGD("JNIProviderService: OnSyncInfoListenerCb - OUT");
+    if (JNI_EDETACHED == envRet)
+    {
+        g_jvm_provider->DetachCurrentThread();
+    }
+    NS_LOGD ("JNIProviderService: OnSyncInfoListenerCb - OUT");
     return;
 
 }
 
-JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeStart
+JNIEXPORT void JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeStart
 (JNIEnv *env, jobject jObj, jobject jSubscriptionListener, jobject jSyncListener,
  jboolean jPolicy, jstring jUserInfo, jboolean jResourceSecurity)
 {
-    LOGD("JNIProviderService: nativeStart - IN");
+    NS_LOGD ("JNIProviderService: nativeStart - IN");
     if (!jSubscriptionListener || !jSyncListener)
     {
-        LOGE("Fail to set listeners");
-        ThrowNSException(NS_ERROR, "Listener cannot be null");
-        return (jint) OIC::Service::NSResult::ERROR;
+        ThrowNSException(JNI_INVALID_VALUE, "Listener cannot be null");
+        return;
     }
 
     if (g_obj_subscriptionListener != NULL)
@@ -843,24 +932,24 @@ JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nat
     OIC::Service::NSResult result = OIC::Service::NSProviderService::getInstance()->start(cfg);
     if (result != OIC::Service::NSResult::OK)
     {
-        LOGE("Fail to start NSProviderService");
-
+        ThrowNSException((int) result, "Fail to start NSProviderService");
+        return;
     }
 
-    LOGD("JNIProviderService: nativeStart - OUT");
-    return (jint) result;
+    NS_LOGD ("JNIProviderService: nativeStart - OUT");
+    return;
 }
 
-JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeStop
+JNIEXPORT void JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeStop
 (JNIEnv *env, jobject jObj)
 {
-    LOGD("JNIProviderService: nativeStop - IN");
+    NS_LOGD ("JNIProviderService: nativeStop - IN");
 
     OIC::Service::NSResult result = OIC::Service::NSProviderService::getInstance()->stop();
     if (result !=  OIC::Service::NSResult::OK)
     {
-        LOGD("Fail to stop NSProvider service");
-        return (jint) result;
+        ThrowNSException((int) result, "Fail to stop NSProviderService");
+        return;
     }
 
     env->DeleteGlobalRef( g_obj_subscriptionListener);
@@ -868,76 +957,72 @@ JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nat
     g_obj_subscriptionListener = NULL;
     g_obj_syncListener = NULL;
 
-    LOGD("JNIProviderService: nativeStop - OUT");
-    return (jint) result;
+    NS_LOGD ("JNIProviderService: nativeStop - OUT");
+    return;
 }
 
-JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeSendMessage
+JNIEXPORT void JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeSendMessage
 (JNIEnv *env, jobject jObj, jobject jMsg)
 {
-    LOGD("JNIProviderService: nativeSendMessage - IN");
+    NS_LOGD ("JNIProviderService: nativeSendMessage - IN");
     if (!jMsg)
     {
-        LOGD("Fail to send notification - Message is null");
-        ThrowNSException(NS_ERROR, "Message cannot be null");
-        return (jint) OIC::Service::NSResult::ERROR;
-    }
-    OIC::Service::NSMessage *nsMsg = getNativeMessage(env, jMsg);
-    if (nsMsg == nullptr)
-    {
-        ThrowNSException(NS_ERROR, "Message didn't have a field ID ");
-        return (jint) OIC::Service::NSResult::ERROR;
+        ThrowNSException(JNI_INVALID_VALUE, "Message cannot be null");
+        return;
     }
+    OIC::Service::NSMessage nsMsg = getNativeMessage(env, jMsg);
 
     OIC::Service::NSResult result = OIC::Service::NSProviderService::getInstance()->sendMessage(nsMsg);
     if (result !=  OIC::Service::NSResult::OK)
     {
-        LOGD("Fail to send NSProvider Message");
+        ThrowNSException((int) result, "Fail to send NSProvider Message");
+        return;
     }
-    LOGD("JNIProviderService: nativeSendMessage - OUT");
-    return (jint) result;
+    NS_LOGD ("JNIProviderService: nativeSendMessage - OUT");
+    return;
 }
 
 JNIEXPORT void JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeSendSyncInfo
 (JNIEnv *env, jobject jObj, jlong messageId , jint syncState)
 {
-    LOGD("JNIProviderService: nativeSendSyncInfo - IN");
-    OIC::Service::NSProviderService::getInstance()->sendSyncInfo( messageId,
-            (OIC::Service::NSSyncInfo::NSSyncType) syncState);
-    LOGD("JNIProviderService: nativeSendSyncInfo - OUT");
+    NS_LOGD ("JNIProviderService: nativeSendSyncInfo - IN");
+    OIC::Service::NSResult result = OIC::Service::NSProviderService::getInstance()->sendSyncInfo(
+                                        messageId,
+                                        (OIC::Service::NSSyncInfo::NSSyncType) syncState);
+    if (result !=  OIC::Service::NSResult::OK)
+    {
+        ThrowNSException((int) result, "Fail to send NSProvider SendSyncInfo");
+        return;
+    }
+    NS_LOGD ("JNIProviderService: nativeSendSyncInfo - OUT");
     return;
 }
 
 JNIEXPORT jobject JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeCreateMessage
 (JNIEnv *env, jobject jObj)
 {
-    LOGD("JNIProviderService: nativeCreateMessage - IN");
-    OIC::Service::NSMessage *message =
+    NS_LOGD ("JNIProviderService: nativeCreateMessage - IN");
+    OIC::Service::NSMessage message =
         OIC::Service::NSProviderService::getInstance()->createMessage();
-    if (message == nullptr)
-    {
-        ThrowNSException(NS_ERROR, "Couldn't get Native Message");
-        return NULL;
-    }
     jobject jMsg =  getJavaMessage(env, message);
     if (!jMsg)
     {
-        ThrowNSException(NS_ERROR, "Couldn't create Java Message");
+        ThrowNSException(JNI_INVALID_VALUE, "Couldn't create Java Message");
         return NULL;
     }
-    LOGD("JNIProviderService: nativeCreateMessage - OUT");
+    NS_LOGD ("JNIProviderService: nativeCreateMessage - OUT");
     return jMsg;
 }
 
-JNIEXPORT jint JNICALL
+JNIEXPORT void JNICALL
 Java_org_iotivity_service_ns_provider_ProviderService_nativeEnableRemoteService
 (JNIEnv *env, jobject jObj, jstring jstr)
 {
-    LOGD("JNIProviderService: nativeEnableRemoteService - IN");
+    NS_LOGD ("JNIProviderService: nativeEnableRemoteService - IN");
     if (!jstr)
     {
-        ThrowNSException(NS_ERROR, "Server Address Can't be NULL");
-        return (jint) OIC::Service::NSResult::ERROR;
+        ThrowNSException(JNI_INVALID_VALUE, "Server Address Can't be NULL");
+        return;
     }
 
     const char *address = env->GetStringUTFChars( jstr, NULL);
@@ -947,22 +1032,23 @@ Java_org_iotivity_service_ns_provider_ProviderService_nativeEnableRemoteService
             servAddress);
     if (result !=  OIC::Service::NSResult::OK)
     {
-        LOGE("Fail to Enable Remote Service");
+        ThrowNSException((int) result, "Fail to  Enable Remote Service");
+        return;
     }
     env->ReleaseStringUTFChars(jstr, address);
-    LOGD("JNIProviderService: nativeEnableRemoteService - OUT");
-    return (jint) result;
+    NS_LOGD ("JNIProviderService: nativeEnableRemoteService - OUT");
+    return;
 }
 
-JNIEXPORT jint JNICALL
+JNIEXPORT void JNICALL
 Java_org_iotivity_service_ns_provider_ProviderService_nativeDisableRemoteService
 (JNIEnv *env, jobject jObj, jstring jstr)
 {
-    LOGD("JNIProviderService: nativeDisableRemoteService - IN");
+    NS_LOGD ("JNIProviderService: nativeDisableRemoteService - IN");
     if (!jstr)
     {
-        ThrowNSException(NS_ERROR, "Server Address Can't be NULL");
-        return (jint) OIC::Service::NSResult::ERROR;
+        ThrowNSException(JNI_INVALID_VALUE, "Server Address Can't be NULL");
+        return;
     }
 
     const char *address = env->GetStringUTFChars( jstr, NULL);
@@ -972,21 +1058,57 @@ Java_org_iotivity_service_ns_provider_ProviderService_nativeDisableRemoteService
             servAddress);
     if (result !=  OIC::Service::NSResult::OK)
     {
-        LOGE("Fail to Disable Remote Service");
+        ThrowNSException((int) result, "Fail to  Disable Remote Service");
+        return;
     }
     env->ReleaseStringUTFChars(jstr, address);
-    LOGD("JNIProviderService: nativeDisableRemoteService - OUT");
-    return (jint) result;
+    NS_LOGD ("JNIProviderService: nativeDisableRemoteService - OUT");
+    return;
+}
+
+JNIEXPORT void JNICALL
+Java_org_iotivity_service_ns_provider_ProviderService_nativeSubscribeMQService
+(JNIEnv *env, jobject jObj, jstring jserverAddress, jstring jTopicName)
+{
+    NS_LOGD ("JNIProviderService: nativeSubscribeMQService - IN");
+    if (!jserverAddress)
+    {
+        ThrowNSException(JNI_INVALID_VALUE, "Server Address Can't be NULL");
+        return;
+    }
+    if (!jTopicName)
+    {
+        ThrowNSException(JNI_INVALID_VALUE, "TopicName Can't be NULL");
+        return;
+    }
+
+    const char *address = env->GetStringUTFChars( jserverAddress, NULL);
+    std::string servAddress(address);
+    const char *topic = env->GetStringUTFChars( jTopicName, NULL);
+    std::string topicName(topic);
+
+    OIC::Service::NSResult result  =
+        OIC::Service::NSProviderService::getInstance()->subscribeMQService(
+            servAddress, topicName);
+    if (result !=  OIC::Service::NSResult::OK)
+    {
+        ThrowNSException((int) result, "Fail to  Subscribe to MQ Service");
+        return;
+    }
+    env->ReleaseStringUTFChars(jserverAddress, address);
+    env->ReleaseStringUTFChars(jTopicName, topic);
+    NS_LOGD ("JNIProviderService: nativeSubscribeMQService - OUT");
+    return;
 }
 
-JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeRegisterTopic
+JNIEXPORT void JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeRegisterTopic
 (JNIEnv *env, jobject jObj, jstring jTopicName)
 {
-    LOGD("JNIProviderService: nativeRegisterTopic - IN");
+    NS_LOGD ("JNIProviderService: nativeRegisterTopic - IN");
     if (!jTopicName)
     {
-        ThrowNSException(NS_ERROR, "Topic Name Can't be NULL");
-        return (jint) OIC::Service::NSResult::ERROR;
+        ThrowNSException(JNI_INVALID_VALUE, "Topic Name Can't be NULL");
+        return;
     }
     const char *name = env->GetStringUTFChars( jTopicName, NULL);
     std::string topicName(name);
@@ -994,20 +1116,21 @@ JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nat
                                          topicName);
     if (result !=  OIC::Service::NSResult::OK)
     {
-        LOGE("Fail to Register Topic");
+        ThrowNSException((int) result, "Fail to  Register Topic");
+        return;
     }
     env->ReleaseStringUTFChars(jTopicName, name);
-    LOGD("JNIProviderService: nativeRegisterTopic - OUT");
-    return (jint) result;
+    NS_LOGD ("JNIProviderService: nativeRegisterTopic - OUT");
+    return;
 }
-JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeUnregisterTopic
+JNIEXPORT void JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeUnregisterTopic
 (JNIEnv *env, jobject jObj, jstring jTopicName)
 {
-    LOGD("JNIProviderService: nativeUnregisterTopic - IN");
+    NS_LOGD ("JNIProviderService: nativeUnregisterTopic - IN");
     if (!jTopicName)
     {
-        ThrowNSException(NS_ERROR, "Topic Name Can't be NULL");
-        return (jint) OIC::Service::NSResult::ERROR;
+        ThrowNSException(JNI_INVALID_VALUE, "Topic Name Can't be NULL");
+        return;
     }
     const char *name = env->GetStringUTFChars( jTopicName, NULL);
     std::string topicName(name);
@@ -1015,158 +1138,207 @@ JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nat
                                          topicName);
     if (result !=  OIC::Service::NSResult::OK)
     {
-        LOGE("Fail to Unregister Topic");
+        ThrowNSException((int) result, "Fail to  Unregister Topic");
+        return;
     }
     env->ReleaseStringUTFChars(jTopicName, name);
-    LOGD("JNIProviderService: nativeUnregisterTopic - OUT");
-    return (jint) result;
+    NS_LOGD ("JNIProviderService: nativeUnregisterTopic - OUT");
+    return;
 }
 
 JNIEXPORT jobject JNICALL
 Java_org_iotivity_service_ns_provider_ProviderService_nativeGetRegisteredTopicList
 (JNIEnv *env, jobject jObj)
 {
-    LOGD("JNIProviderService: nativeGetRegisteredTopicList - IN");
+    NS_LOGD ("JNIProviderService: nativeGetRegisteredTopicList - IN");
 
-    OIC::Service::NSTopicsList *topicList  =
+    std::shared_ptr<OIC::Service::NSTopicsList> topicList  =
         OIC::Service::NSProviderService::getInstance()->getRegisteredTopicList();
     if (topicList == nullptr)
     {
-        ThrowNSException(NS_ERROR, "Topic List doesn't exist");
+        ThrowNSException(JNI_INVALID_VALUE, "Topic List doesn't exist");
         return NULL;
     }
 
     jobject obj_topicList = getJavaTopicsList(env, topicList);
 
-    LOGD("JNIProviderService: nativeGetRegisteredTopicList - OUT");
+    NS_LOGD ("JNIProviderService: nativeGetRegisteredTopicList - OUT");
     return obj_topicList;
 }
 
-JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_Consumer_nativeAcceptSubscription
+JNIEXPORT void JNICALL Java_org_iotivity_service_ns_provider_Consumer_nativeAcceptSubscription
 (JNIEnv *env,  jobject jObj, jstring jConsumerId, jboolean jAccepted)
 {
-    LOGD("JNIProviderService: nativeAcceptSubscription - IN");
+    NS_LOGD ("JNIProviderService: nativeAcceptSubscription - IN");
     if (!jConsumerId)
     {
-        ThrowNSException(NS_ERROR, "ConsumerId Can't be NULL");
-        return (jint) OIC::Service::NSResult::ERROR;
+        ThrowNSException(JNI_INVALID_VALUE, "ConsumerId Can't be NULL");
+        return;
     }
     const char *id = env->GetStringUTFChars( jConsumerId, NULL);
     std::string consumerId(id);
-    LOGD("Consumer ID: %s\n", consumerId.c_str());
+    NS_LOGD ("Consumer ID: %s\n", consumerId.c_str());
 
-    OIC::Service::NSConsumer *consumer =
+    std::shared_ptr<OIC::Service::NSConsumer> consumer =
         OIC::Service::NSProviderService::getInstance()->getConsumer(consumerId);
     if (consumer)
-        return (jint) consumer->acceptSubscription((bool)jAccepted);
-
-    LOGE("Couldn't find consumer");
-    LOGD("JNIProviderService: nativeAcceptSubscription - OUT");
-    return (jint) OIC::Service::NSResult::ERROR;
+    {
+        OIC::Service::NSResult result = OIC::Service::NSResult::ERROR;
+        try
+        {
+            result = consumer->acceptSubscription((bool)jAccepted);
+        }
+        catch (OIC::Service::NSException ex)
+        {
+            ThrowNSException(NATIVE_EXCEPTION, ex.what());
+            return;
+        }
+        if (result !=  OIC::Service::NSResult::OK)
+        {
+            ThrowNSException((int) result, "Fail to  acceptSubscription");
+            return;
+        }
+    }
+    else
+    {
+        NS_LOGE ("Couldn't find consumer");
+        ThrowNSException(JNI_NO_NATIVE_POINTER, "Fail to find native consumer");
+    }
+    return;
 }
-JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_Consumer_nativeSetConsumerTopic
+JNIEXPORT void JNICALL Java_org_iotivity_service_ns_provider_Consumer_nativeSetConsumerTopic
 (JNIEnv *env, jobject jObj, jstring jConsumerId, jstring jTopicName)
 {
-    LOGD("JNIProviderService: nativeSetConsumerTopic - IN");
+    NS_LOGD ("JNIProviderService: nativeSetConsumerTopic - IN");
     if (!jConsumerId || !jTopicName)
     {
-        ThrowNSException(NS_ERROR, "Topic Name or ConsumerId Can't be NULL");
-        return (jint) OIC::Service::NSResult::ERROR;
+        ThrowNSException(JNI_INVALID_VALUE, "Topic Name or ConsumerId Can't be NULL");
+        return;
     }
     const char *name = env->GetStringUTFChars( jTopicName, NULL);
     const char *id = env->GetStringUTFChars( jConsumerId, NULL);
     std::string topicName(name);
     std::string consumerId(id);
-    OIC::Service::NSConsumer *nsConsumer =
+    std::shared_ptr<OIC::Service::NSConsumer> nsConsumer =
         OIC::Service::NSProviderService::getInstance()->getConsumer(consumerId);
     if (!nsConsumer)
     {
-        ThrowNSException(NS_ERROR, "Consumer does exists");
-        return (jint) OIC::Service::NSResult::ERROR;
+        ThrowNSException(JNI_NO_NATIVE_POINTER, "Consumer does exists");
+        return;
+    }
+    OIC::Service::NSResult result = OIC::Service::NSResult::ERROR;
+    try
+    {
+        result  = nsConsumer->setTopic(topicName);
+    }
+    catch (OIC::Service::NSException ex)
+    {
+        ThrowNSException(NATIVE_EXCEPTION, ex.what());
+        return;
     }
-    OIC::Service::NSResult result  = nsConsumer->setTopic(topicName);
 
     if (result !=  OIC::Service::NSResult::OK)
     {
-        LOGD("Fail to Select Topic");
+        ThrowNSException((int) result, "Fail to  Select Topic");
+        return;
     }
     env->ReleaseStringUTFChars(jTopicName, name);
     env->ReleaseStringUTFChars(jConsumerId, id);
-    LOGD("JNIProviderService: nativeSetConsumerTopic - OUT");
-    return (jint) result;
+    NS_LOGD ("JNIProviderService: nativeSetConsumerTopic - OUT");
+    return;
 }
-JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_Consumer_nativeUnsetConsumerTopic
+JNIEXPORT void JNICALL Java_org_iotivity_service_ns_provider_Consumer_nativeUnsetConsumerTopic
 (JNIEnv *env, jobject jObj, jstring jConsumerId, jstring jTopicName)
 {
-    LOGD("JNIProviderService: nativeUnsetConsumerTopic - IN");
+    NS_LOGD ("JNIProviderService: nativeUnsetConsumerTopic - IN");
     if (!jConsumerId || !jTopicName)
     {
-        ThrowNSException(NS_ERROR, "Topic Name or ConsumerId Can't be NULL");
-        return (jint) OIC::Service::NSResult::ERROR;
+        ThrowNSException(JNI_INVALID_VALUE, "Topic Name or ConsumerId Can't be NULL");
+        return;
     }
     const char *name = env->GetStringUTFChars( jTopicName, NULL);
     const char *id = env->GetStringUTFChars( jConsumerId, NULL);
     std::string topicName(name);
     std::string consumerId(id);
-    OIC::Service::NSConsumer *nsConsumer =
+    std::shared_ptr<OIC::Service::NSConsumer> nsConsumer =
         OIC::Service::NSProviderService::getInstance()->getConsumer(consumerId);
     if (!nsConsumer)
     {
-        ThrowNSException(NS_ERROR, "Consumer does exists");
-        return (jint) OIC::Service::NSResult::ERROR;
+        ThrowNSException(JNI_NO_NATIVE_POINTER, "Consumer does exists");
+        return;
+    }
+    OIC::Service::NSResult result = OIC::Service::NSResult::ERROR;
+    try
+    {
+        result  = nsConsumer->unsetTopic(topicName);
+    }
+    catch (OIC::Service::NSException ex)
+    {
+        ThrowNSException(NATIVE_EXCEPTION, ex.what());
+        return;
     }
-    OIC::Service::NSResult result  = nsConsumer->unsetTopic(topicName);
 
     if (result !=  OIC::Service::NSResult::OK)
     {
-        LOGE("Fail to Unselect Topic");
+        ThrowNSException((int) result, "Fail to  Unselect Topic");
+        return;
     }
     env->ReleaseStringUTFChars(jTopicName, name);
     env->ReleaseStringUTFChars(jConsumerId, id);
-    LOGD("JNIProviderService: nativeUnsetConsumerTopic - OUT");
-    return (jint) result;
+    NS_LOGD ("JNIProviderService: nativeUnsetConsumerTopic - OUT");
+    return;
 }
 
 JNIEXPORT jobject JNICALL Java_org_iotivity_service_ns_provider_Consumer_nativeGetConsumerTopicList
 (JNIEnv *env, jobject jObj, jstring jConsumerId)
 {
-    LOGD("JNIProviderService: nativeGetConsumerTopicList - IN");
+    NS_LOGD ("JNIProviderService: nativeGetConsumerTopicList - IN");
     if (!jConsumerId)
     {
-        ThrowNSException(NS_ERROR, "Topic Name or ConsumerId Can't be NULL");
+        ThrowNSException(JNI_INVALID_VALUE, "Topic Name or ConsumerId Can't be NULL");
         return NULL;
     }
     const char *id = env->GetStringUTFChars( jConsumerId, NULL);
     std::string consumerId(id);
-    OIC::Service::NSConsumer *nsConsumer =
+    std::shared_ptr<OIC::Service::NSConsumer> nsConsumer =
         OIC::Service::NSProviderService::getInstance()->getConsumer(consumerId);
     if (!nsConsumer)
     {
-        ThrowNSException(NS_ERROR, "Consumer does exists");
+        ThrowNSException(JNI_NO_NATIVE_POINTER, "Consumer does exists");
         return NULL;
     }
     env->ReleaseStringUTFChars(jConsumerId, id);
-    OIC::Service::NSTopicsList *topicList  = nsConsumer->getConsumerTopicList();
+    std::shared_ptr<OIC::Service::NSTopicsList> topicList = nullptr;
+    try
+    {
+        topicList  = nsConsumer->getConsumerTopicList();
+    }
+    catch (OIC::Service::NSException ex)
+    {
+        ThrowNSException(NATIVE_EXCEPTION, ex.what());
+        return NULL;
+    }
     if (topicList == nullptr)
     {
-        ThrowNSException(NS_ERROR, "Topic List doesn't exist");
+        ThrowNSException(JNI_NO_NATIVE_POINTER, "Topic List doesn't exist");
         return NULL;
     }
     jobject obj_topicList = getJavaTopicsList(env, topicList);
-    LOGD("JNIProviderService: nativeGetConsumerTopicList - OUT");
+
+    NS_LOGD ("JNIProviderService: nativeGetConsumerTopicList - OUT");
     return obj_topicList;
 }
 
 // JNI OnLoad
 JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
 {
-    LOGD("ProviderService_JNI_OnLoad");
+    NS_LOGD ("ProviderService_JNI_OnLoad");
     g_jvm_provider = jvm;
 
-    JNIEnv *env;
+    JNIEnv *env = NULL;
     if (jvm->GetEnv((void **)&env, JNI_CURRENT_VERSION) != JNI_OK)
     {
-        LOGE("Failed to get the environment using GetEnv()");
+        NS_LOGE ("Failed to get the environment using GetEnv()");
         return JNI_ERR;
     }
 
@@ -1174,13 +1346,13 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
                               "org/iotivity/service/ns/common/Message");
     if (!localMessage)
     {
-        LOGE("Failed to get local Message class");
+        NS_LOGE ("Failed to get local Message class");
         return JNI_ERR;
     }
     g_cls_Message = (jclass) (env->NewGlobalRef(localMessage));
     if (!g_cls_Message)
     {
-        LOGE("Failed to set Global Message reference");
+        NS_LOGE ("Failed to set Global Message reference");
         return JNI_ERR;
     }
 
@@ -1188,13 +1360,13 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
                                   "org/iotivity/service/ns/common/Message$MessageType");
     if (!localMessageType)
     {
-        LOGE("Failed to get local Message Type class");
+        NS_LOGE ("Failed to get local Message Type class");
         return JNI_ERR;
     }
     g_cls_Message_Type = (jclass) (env->NewGlobalRef(localMessageType));
     if (!g_cls_Message_Type)
     {
-        LOGE("Failed to set Global Message Type reference");
+        NS_LOGE ("Failed to set Global Message Type reference");
         return JNI_ERR;
     }
 
@@ -1202,13 +1374,13 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
                                "org/iotivity/service/ns/provider/Consumer");
     if (!localConsumer)
     {
-        LOGE("Failed to get local Provider class");
+        NS_LOGE ("Failed to get local Provider class");
         return JNI_ERR;
     }
     g_cls_Consumer = (jclass) (env->NewGlobalRef(localConsumer));
     if (!g_cls_Consumer)
     {
-        LOGE("Failed to set Global Provider reference");
+        NS_LOGE ("Failed to set Global Provider reference");
         return JNI_ERR;
     }
 
@@ -1216,13 +1388,13 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
                                "org/iotivity/service/ns/common/SyncInfo");
     if (!localSyncInfo)
     {
-        LOGE("Failed to get local SyncInfo class");
+        NS_LOGE ("Failed to get local SyncInfo class");
         return JNI_ERR;
     }
     g_cls_SyncInfo = (jclass) (env->NewGlobalRef(localSyncInfo));
     if (!g_cls_SyncInfo)
     {
-        LOGE("Failed to set Global SyncInfo reference");
+        NS_LOGE ("Failed to set Global SyncInfo reference");
         return JNI_ERR;
     }
 
@@ -1230,13 +1402,13 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
                                "org/iotivity/service/ns/common/SyncInfo$SyncType");
     if (!localSyncType)
     {
-        LOGE("Failed to get local SyncType enum");
+        NS_LOGE ("Failed to get local SyncType enum");
         return JNI_ERR;
     }
     g_cls_SyncType = (jclass) (env->NewGlobalRef(localSyncType));
     if (!g_cls_SyncType)
     {
-        LOGE("Failed to set Global SyncType reference");
+        NS_LOGE ("Failed to set Global SyncType reference");
         return JNI_ERR;
     }
 
@@ -1244,13 +1416,13 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
                                     "org/iotivity/service/ns/common/MediaContents");
     if (!localMediaContents)
     {
-        LOGE("Failed to get local MediaContents class");
+        NS_LOGE ("Failed to get local MediaContents class");
         return JNI_ERR;
     }
     g_cls_MediaContents = (jclass) (env->NewGlobalRef(localMediaContents));
     if (!g_cls_MediaContents)
     {
-        LOGE("Failed to set Global MediaContents reference");
+        NS_LOGE ("Failed to set Global MediaContents reference");
         return JNI_ERR;
     }
 
@@ -1258,13 +1430,13 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
                             "org/iotivity/service/ns/common/Topic");
     if (!localTopic)
     {
-        LOGE("Failed to get local Topic class");
+        NS_LOGE ("Failed to get local Topic class");
         return JNI_ERR;
     }
     g_cls_Topic = (jclass) (env->NewGlobalRef(localTopic));
     if (!g_cls_Topic)
     {
-        LOGE("Failed to set Global Topic reference");
+        NS_LOGE ("Failed to set Global Topic reference");
         return JNI_ERR;
     }
 
@@ -1272,13 +1444,13 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
                                  "org/iotivity/service/ns/common/TopicsList");
     if (!localTopicsList)
     {
-        LOGE("Failed to get local Topic class");
+        NS_LOGE ("Failed to get local Topic class");
         return JNI_ERR;
     }
     g_cls_TopicsList = (jclass) (env->NewGlobalRef(localTopicsList));
     if (!g_cls_TopicsList)
     {
-        LOGE("Failed to set Global TopicsList reference");
+        NS_LOGE ("Failed to set Global TopicsList reference");
         return JNI_ERR;
     }
 
@@ -1286,13 +1458,13 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
                                  "org/iotivity/service/ns/common/Topic$TopicState");
     if (!localTopicState)
     {
-        LOGE("Failed to get local TopicState enum");
+        NS_LOGE ("Failed to get local TopicState enum");
         return JNI_ERR;
     }
     g_cls_TopicState = (jclass) (env->NewGlobalRef(localTopicState));
     if (!g_cls_TopicState)
     {
-        LOGE("Failed to set Global TopicState reference");
+        NS_LOGE ("Failed to set Global TopicState reference");
         return JNI_ERR;
     }
 
@@ -1300,20 +1472,20 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
     jclass localOcRepresentation = env->FindClass("org/iotivity/base/OcRepresentation");
     if (!localOcRepresentation)
     {
-        LOGE("Failed to get local OcRepresentation class");
+        NS_LOGE ("Failed to get local OcRepresentation class");
         return JNI_ERR;
     }
     g_cls_OcRepresentation = (jclass) env->NewGlobalRef(localOcRepresentation);
     if (!g_cls_OcRepresentation)
     {
-        LOGE("Failed to set Global OcRepresentation reference");
+        NS_LOGE ("Failed to set Global OcRepresentation reference");
         return JNI_ERR;
     }
 
     g_mid_OcRepresentation_N_ctor_bool = env->GetMethodID(g_cls_OcRepresentation, "<init>", "(JZ)V");
     if (!g_mid_OcRepresentation_N_ctor_bool)
     {
-        LOGE("Failed to get Global OcRepresentation Constructor reference");
+        NS_LOGE ("Failed to get Global OcRepresentation Constructor reference");
         return JNI_ERR;
     }
 
@@ -1333,12 +1505,12 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
 
 JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *jvm, void *reserved)
 {
-    LOGD("ProviderService_JNI_OnUnload");
-    JNIEnv *env;
+    NS_LOGD ("ProviderService_JNI_OnUnload");
+    JNIEnv *env = NULL;
 
     if (jvm->GetEnv((void **)&env, JNI_CURRENT_VERSION) != JNI_OK)
     {
-        LOGE("Failed to get the environment using GetEnv()");
+        NS_LOGE ("Failed to get the environment using GetEnv()");
         return ;
     }
 
old mode 100644 (file)
new mode 100755 (executable)
index d3a1a50..f17d110
@@ -30,25 +30,25 @@ extern "C" {
 /*
  * Class:     org_iotivity_service_ns_provider_ProviderService
  * Method:    nativeStart
- * Signature: (Lorg/iotivity/service/ns/provider/ProviderService/OnConsumerSubscribedListener;Lorg/iotivity/service/ns/provider/ProviderService/OnMessageSynchronizedListener;ZLjava/lang/String;Z)I
+ * Signature: (Lorg/iotivity/service/ns/provider/ProviderService/OnConsumerSubscribedListener;Lorg/iotivity/service/ns/provider/ProviderService/OnMessageSynchronizedListener;ZLjava/lang/String;Z)V
  */
-JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeStart
+JNIEXPORT void JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeStart
 (JNIEnv *, jobject, jobject, jobject, jboolean, jstring, jboolean);
 
 /*
  * Class:     org_iotivity_service_ns_provider_ProviderService
  * Method:    nativeStop
- * Signature: ()I
+ * Signature: ()V
  */
-JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeStop
+JNIEXPORT void JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeStop
 (JNIEnv *, jobject);
 
 /*
  * Class:     org_iotivity_service_ns_provider_ProviderService
  * Method:    nativeSendMessage
- * Signature: (Lorg/iotivity/service/ns/common/Message;)I
+ * Signature: (Lorg/iotivity/service/ns/common/Message;)V
  */
-JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeSendMessage
+JNIEXPORT void JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeSendMessage
 (JNIEnv *, jobject, jobject);
 
 /*
@@ -70,35 +70,44 @@ JNIEXPORT jobject JNICALL Java_org_iotivity_service_ns_provider_ProviderService_
 /*
  * Class:     org_iotivity_service_ns_provider_ProviderService
  * Method:    nativeEnableRemoteService
- * Signature: (Ljava/lang/String;)I
+ * Signature: (Ljava/lang/String;)V
  */
-JNIEXPORT jint JNICALL
+JNIEXPORT void JNICALL
 Java_org_iotivity_service_ns_provider_ProviderService_nativeEnableRemoteService
 (JNIEnv *, jobject, jstring);
 
 /*
  * Class:     org_iotivity_service_ns_provider_ProviderService
  * Method:    nativeDisableRemoteService
- * Signature: (Ljava/lang/String;)I
+ * Signature: (Ljava/lang/String;)V
  */
-JNIEXPORT jint JNICALL
+JNIEXPORT void JNICALL
 Java_org_iotivity_service_ns_provider_ProviderService_nativeDisableRemoteService
 (JNIEnv *, jobject, jstring);
 
 /*
  * Class:     org_iotivity_service_ns_provider_ProviderService
+ * Method:    nativeSubscribeMQService
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_service_ns_provider_ProviderService_nativeSubscribeMQService
+(JNIEnv *, jobject, jstring, jstring);
+
+/*
+ * Class:     org_iotivity_service_ns_provider_ProviderService
  * Method:    nativeRegisterTopic
- * Signature: (Ljava/lang/String;)I
+ * Signature: (Ljava/lang/String;)V
  */
-JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeRegisterTopic
+JNIEXPORT void JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeRegisterTopic
 (JNIEnv *, jobject, jstring);
 
 /*
  * Class:     org_iotivity_service_ns_provider_ProviderService
  * Method:    nativeUnregisterTopic
- * Signature: (Ljava/lang/String;)I
+ * Signature: (Ljava/lang/String;)V
  */
-JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeUnregisterTopic
+JNIEXPORT void JNICALL Java_org_iotivity_service_ns_provider_ProviderService_nativeUnregisterTopic
 (JNIEnv *, jobject, jstring);
 
 /*
@@ -113,25 +122,25 @@ Java_org_iotivity_service_ns_provider_ProviderService_nativeGetRegisteredTopicLi
 /*
  * Class:     org_iotivity_service_ns_provider_Consumer
  * Method:    nativeAcceptSubscription
- * Signature: (Ljava/lang/String;Z)I
+ * Signature: (Ljava/lang/String;Z)V
  */
-JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_Consumer_nativeAcceptSubscription
+JNIEXPORT void JNICALL Java_org_iotivity_service_ns_provider_Consumer_nativeAcceptSubscription
 (JNIEnv *, jobject, jstring, jboolean);
 
 /*
  * Class:     org_iotivity_service_ns_provider_Consumer
  * Method:    nativeSetConsumerTopic
- * Signature: (Ljava/lang/String;Ljava/lang/String;)I
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)V
  */
-JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_Consumer_nativeSetConsumerTopic
+JNIEXPORT void JNICALL Java_org_iotivity_service_ns_provider_Consumer_nativeSetConsumerTopic
 (JNIEnv *, jobject, jstring, jstring);
 
 /*
  * Class:     org_iotivity_service_ns_provider_Consumer
  * Method:    nativeUnsetConsumerTopic
- * Signature: (Ljava/lang/String;Ljava/lang/String;)I
+ * Signature: (Ljava/lang/String;Ljava/lang/String;)V
  */
-JNIEXPORT jint JNICALL Java_org_iotivity_service_ns_provider_Consumer_nativeUnsetConsumerTopic
+JNIEXPORT void JNICALL Java_org_iotivity_service_ns_provider_Consumer_nativeUnsetConsumerTopic
 (JNIEnv *, jobject, jstring, jstring);
 
 /*
diff --git a/service/notification/cpp-wrapper/common/NSException.h b/service/notification/cpp-wrapper/common/NSException.h
new file mode 100755 (executable)
index 0000000..01fec7b
--- /dev/null
@@ -0,0 +1,67 @@
+/******************************************************************
+ *
+ * Copyright 2017 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   NSException.h
+ *
+ * @brief   This file provides exception handling for Notification Service.
+ */
+
+#ifndef _NS_EXCEPTION_H_
+#define _NS_EXCEPTION_H_
+
+#include <exception>
+
+namespace OIC
+{
+    namespace Service
+    {
+        /**
+         * @class   NSException
+         * @brief   This is the base exception of all type of exception thrown from Notification service module.
+         */
+        class NSException : public std::exception
+        {
+            public:
+                /**
+                      * Constructor of NSException.
+                      *
+                      * @param message - String describing the error messsage.
+                      */
+                NSException(const std::string &message) : m_message(message) {}
+
+                /**
+                      * API to get error message describing exception reason.
+                      *
+                      * @return Null terminated string.
+                      */
+                virtual const char *what() const noexcept                
+                {
+                    return m_message.c_str();
+                }
+
+                virtual ~NSException() throw() {}
+
+            private:
+                std::string m_message;
+        };
+    }
+}
+#endif /* _NS_EXCEPTION_H_ */
index 915547b..3386253 100755 (executable)
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
 #include "NSTopicsList.h"
+#include "NSException.h"
 #include "oic_malloc.h"
 
 namespace OIC
 {
     namespace Service
     {
-        NSTopicsList::NSTopicsList(::NSTopicLL *topics)
+        NSTopicsList::NSTopicsList(::NSTopicLL *topics, bool modify)
         {
             ::NSTopicLL *topicsNode = nullptr;
             topicsNode = topics;
+            m_modifiable = modify;
 
             while (topicsNode != nullptr)
             {
-                addTopic(topicsNode->topicName, (NSTopic::NSTopicState)topicsNode->state);
+                m_topicsList.push_back(new NSTopic(
+                    topicsNode->topicName, (NSTopic::NSTopicState)topicsNode->state));
                 topicsNode = topicsNode->next;
             }
 
@@ -41,47 +44,79 @@ namespace OIC
         {
             for (auto it : topicsList.getTopicsList())
             {
-                addTopic(it->getTopicName(), it->getState());
+                m_topicsList.push_back(new NSTopic(it.getTopicName(), it.getState()));
             }
+            m_modifiable = false;
         }
 
         NSTopicsList &NSTopicsList::operator=(const NSTopicsList &topicsList)
         {
             for (auto it : topicsList.getTopicsList())
             {
-                this->addTopic(it->getTopicName(), it->getState());
+                this->m_topicsList.push_back(new NSTopic(it.getTopicName(), it.getState()));
             }
             return *this;
+            m_modifiable = false;
         }
 
         NSTopicsList::~NSTopicsList()
         {
-            for (auto it : getTopicsList())
+            for (auto it : m_topicsList)
             {
                 delete it;
             }
-            getTopicsList().clear();
+            m_topicsList.clear();
         }
 
         void NSTopicsList::addTopic(const std::string &topicName, NSTopic::NSTopicState state)
         {
-            m_topicsList.push_back(new NSTopic(topicName, state));
+            if(m_modifiable)
+            {
+                m_topicsList.push_back(new NSTopic(topicName, state));
+            }
+            else
+            {
+                throw NSException("Invalid Operation. Method not supported as the object state is invalid");
+            }
         }
 
         void NSTopicsList::removeTopic(const std::string &topicName)
         {
-            for (auto it : getTopicsList())
+            if(m_modifiable)
             {
-                if (it->getTopicName().compare(topicName) == 0)
+                for (auto it : m_topicsList)
                 {
-                    m_topicsList.remove(it);
+                    if (it->getTopicName().compare(topicName) == 0)
+                    {
+                        m_topicsList.remove(it);
+                        break;
+                    }
                 }
             }
+            else
+            {
+                throw NSException("Invalid Operation. Method not supported as the object state is invalid");
+            }
         }
 
-        std::list<NSTopic *> NSTopicsList::getTopicsList() const
+        std::list<NSTopic> NSTopicsList::getTopicsList() const
+        {
+            std::list<NSTopic> topicList;
+            for (auto it : m_topicsList)
+            {
+                NSTopic topic(it->getTopicName(), it->getState());
+                topicList.push_back(topic);
+            }
+            return topicList;
+        }
+       
+        //Below method restricts the application from illegally modifying Topics when
+        //Provider is in Invalid state. By calling the API, the service prevents and protects
+        //the integrity of TopicsList updation when the associated object is Invalid
+        //The default value of the variable is 'false' in the provider side. Also, the state is irreversible.
+        void NSTopicsList::unsetModifiability()
         {
-            return m_topicsList;
+            m_modifiable = false;
         }
     }
 }
index f868bd2..288882c 100755 (executable)
@@ -46,14 +46,14 @@ namespace OIC
                 /**
                      * Constructor of NSTopicsList.
                      */
-                NSTopicsList() = default;
+                NSTopicsList() : m_modifiable(true) { }
 
                 /**
                      * Constructor of NSTopicsList.
                      *
                      * @param topics - pointer to NSTopicLL struct to initialize.
                      */
-                NSTopicsList(::NSTopicLL *topics);
+                NSTopicsList(::NSTopicLL *topics, bool modify);
 
                 /**
                      * Copy Constructor of NSTopicsList.
@@ -95,10 +95,20 @@ namespace OIC
                      *
                      * @return topic as NSTopics Linked list.
                      */
-                std::list<NSTopic *> getTopicsList() const;
+                std::list<NSTopic> getTopicsList() const;
+
+                /**
+                     * This method is for preventing for add/remove Topic from Topicslist.
+                     * Below method restricts the application from illegally modifying Topics when 
+                     * Provider is in Invalid state. By calling the API, the service prevents and protects
+                     * the integrity of TopicsList updation when the associated object is Invalid.
+                     *
+                     */
+                void unsetModifiability();
 
             private:
                 std::list<NSTopic *> m_topicsList;
+                bool m_modifiable;
 
         };
     }
index 115ae46..f72933e 100755 (executable)
@@ -77,6 +77,18 @@ if not env.get('RELEASE') and target_os not in ['ios']:
 if env.get('WITH_CLOUD') == True:
        notification_env.AppendUnique(CPPDEFINES = ['WITH_CLOUD'])
 
+with_mq = env.get('WITH_MQ')
+if 'SUB' in with_mq:
+    notification_env.AppendUnique(CPPDEFINES = ['MQ_SUBSCRIBER', 'WITH_MQ'])
+    print "MQ SUB support"
+
+if 'PUB' in with_mq:
+    notification_env.AppendUnique(CPPDEFINES = ['MQ_PUBLISHER', 'WITH_MQ'])
+    print "MQ PUB support"
+
+if 'BROKER' in with_mq:
+    notification_env.AppendUnique(CPPDEFINES = ['MQ_BROKER', 'WITH_MQ'])
+    print "MQ Broker support"
 ######################################################################
 # Source files and Targets for Consumer
 ######################################################################
diff --git a/service/notification/cpp-wrapper/consumer/inc/NSAcceptedProviders.h b/service/notification/cpp-wrapper/consumer/inc/NSAcceptedProviders.h
new file mode 100755 (executable)
index 0000000..7711afd
--- /dev/null
@@ -0,0 +1,119 @@
+//******************************************************************
+//
+// Copyright 2017 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 C++ APIs for Notification Service for Accepted Providers.
+ */
+
+#ifndef _NS_ACCEPTED_PROVIDERS_H_
+#define _NS_ACCEPTED_PROVIDERS_H_
+
+#include <map>
+#include <mutex>
+#include <algorithm>
+#include "NSProvider.h"
+
+
+namespace OIC
+{
+    namespace Service
+    {
+        /**
+              * @class   NSAcceptedProviders
+              * @brief   This class provides a set of C++APIs for managing accepted Providers.
+              */
+        class NSAcceptedProviders
+        {
+            public :
+                /**
+                      * Constructor of NSAcceptedProviders.
+                      *
+                      */
+                NSAcceptedProviders()
+                {
+                    removeProviders();
+                }
+
+                /**
+                      * Destructor of NSAcceptedProviders.
+                      */
+                ~NSAcceptedProviders()
+                {
+                    removeProviders();
+                }
+
+                /**
+                     *  request to get NSProvider pointer
+                     * @param id -id as string
+                     *
+                     * @return shared pointer to NSProvider
+                     */
+                std::shared_ptr<NSProvider> getProvider(const std::string &id);
+
+                /**
+                      *  request to add NSProvider pointer
+                      * @param shared pointer to NSProvider
+                      *
+                      */
+                void addProvider(std::shared_ptr<NSProvider> provider);
+
+                /**
+                      *  request to remove NSProvider
+                      * @param id -id as string
+                      *
+                      */
+                void removeProvider(const std::string &id);
+
+                /**
+                      *  request to check if NSProvider is accepted
+                      * @param id -id as string
+                      *
+                      * @return true if accepted else false
+                      */
+                bool isAccepted(const std::string &id);
+
+                /**
+                      *  get size of providers accepted.
+                      * @return m_providers size
+                      */
+                int size();
+
+                /**
+                      *  request to remove all NSProviders
+                      */
+                void removeProviders();
+
+                /**
+                      *  get the map of providers accepted.
+                      * @return m_providers  -map of accepted providers
+                      */
+                std::map<std::string, std::shared_ptr<NSProvider> > getProviders();
+
+            private :
+                std::map<std::string, std::shared_ptr<NSProvider> > m_providers;
+                std::mutex m_mutex;
+        };
+    }
+}
+
+#endif //_NS_ACCEPTED_PROVIDERS_H_
index f60dd57..0c020f0 100755 (executable)
@@ -28,7 +28,6 @@
 #ifndef _NS_CONSUMER_SERVICE_H_\r
 #define _NS_CONSUMER_SERVICE_H_\r
 \r
-#include <list>\r
 #include <algorithm>\r
 #include "NSProvider.h"\r
 #include "NSUtils.h"\r
@@ -38,19 +37,19 @@ namespace OIC
 {\r
     namespace Service\r
     {\r
+        class NSAcceptedProviders;\r
         /**\r
          * @class   NSConsumerService\r
          * @brief   This class provides a set of C++APIs for Notification Consumer.\r
          */\r
         class NSConsumerService\r
         {\r
-\r
             public :\r
                 /**\r
                      * Consumer uses this callback function to receive the discovered providers\r
                      * @param[in] provider        Provider who has the notification resource\r
                      */\r
-                typedef void (*ProviderDiscoveredCallback)(NSProvider *);\r
+                typedef void (*ProviderDiscoveredCallback)(std::shared_ptr<NSProvider> );\r
 \r
                 /**\r
                       * API for getting the Instance of NSConsumerService class\r
@@ -62,13 +61,15 @@ namespace OIC
                 /**\r
                       * Initialize notification service for consumer\r
                       * @param providerDiscovered Callback function pointers to ProviderDiscoveredCallback,\r
+                      * @return ::NS_OK or result code of NSResult\r
                       */\r
-                void start(ProviderDiscoveredCallback providerDiscovered);\r
+                NSResult start(ProviderDiscoveredCallback providerDiscovered);\r
 \r
                 /**\r
                       * Terminate notification service for consumer\r
+                      * @return ::NS_OK or result code of NSResult\r
                       */\r
-                void stop();\r
+                NSResult stop();\r
 \r
                 /**\r
                      * Request to discover to remote address as parameter.\r
@@ -78,9 +79,18 @@ namespace OIC
                 NSResult enableRemoteService(const std::string &serverAddress);\r
 \r
                 /**\r
+                      * Request to subscribe to remote MQ address as parameter.\r
+                      * @param[in] server address combined with IP address and port number and MQ broker uri using delimiter :\r
+                      * @param[in] topicName the interest Topic name for subscription.\r
+                      * @return ::NS_OK or result code of NSResult\r
+                      */\r
+                NSResult subscribeMQService(const std::string &serverAddress, const std::string &topicName);\r
+\r
+                /**\r
                       * Request discovery manually\r
+                      * @return ::NS_OK or result code of NSResult\r
                       */\r
-                void rescanProvider();\r
+                NSResult rescanProvider();\r
 \r
                 /**\r
                       *  get the callback for ProviderDiscovered\r
@@ -89,22 +99,22 @@ namespace OIC
                 ProviderDiscoveredCallback getProviderDiscoveredCb();\r
 \r
                 /**\r
-                      *  request to get NSProvider pointer\r
-                      * @param id -id as string\r
-                      *\r
-                      * @return pointer to NSProvider\r
-                      */\r
-                NSProvider *getProvider(const std::string &id);\r
+                     *  request to get NSProvider pointer\r
+                     * @param id -id as string\r
+                     *\r
+                     * @return shared pointer to NSProvider\r
+                     */\r
+                std::shared_ptr<NSProvider> getProvider(const std::string &id);\r
 \r
                 /**\r
-                      *  get list of providers acceted.\r
-                      * @return m_acceptedProviders -list of accepted providers\r
+                      *  get handle of providers accepted.\r
+                      * @return m_acceptedProviders -accepted providers\r
                       */\r
-                std::list<NSProvider *> &getAcceptedProviders();\r
+                NSAcceptedProviders *getAcceptedProviders();\r
 \r
             private :\r
                 ProviderDiscoveredCallback m_providerDiscoveredCb;\r
-                std::list<NSProvider *> m_acceptedProviders;\r
+                NSAcceptedProviders *m_acceptedProviders;\r
 \r
             private :\r
                 NSConsumerService();\r
@@ -114,6 +124,10 @@ namespace OIC
                 NSConsumerService(const NSConsumerService &&) = delete;\r
                 NSConsumerService &operator=(const NSConsumerService && ) = delete;\r
 \r
+                static void onProviderStateReceived(::NSProvider *provider, ::NSProviderState state);\r
+                static void onNSMessageReceived(::NSMessage *message);\r
+                static void onNSSyncInfoReceived(::NSSyncInfo *syncInfo);\r
+\r
         };\r
     }\r
 }\r
index bdbd678..e6aa871 100755 (executable)
-//******************************************************************\r
-//\r
-// Copyright 2016 Samsung Electronics All Rights Reserved.\r
-//\r
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
-//\r
-// Licensed under the Apache License, Version 2.0 (the "License");\r
-// you may not use this file except in compliance with the License.\r
-// You may obtain a copy of the License at\r
-//\r
-//      http://www.apache.org/licenses/LICENSE-2.0\r
-//\r
-// Unless required by applicable law or agreed to in writing, software\r
-// distributed under the License is distributed on an "AS IS" BASIS,\r
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-// See the License for the specific language governing permissions and\r
-// limitations under the License.\r
-//\r
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
-\r
-/**\r
- * @file\r
- *\r
- * This file contains Notification service Provider representation.\r
- */\r
-\r
-#ifndef _NS_PROVIDER_H_\r
-#define _NS_PROVIDER_H_\r
-\r
-\r
-#include <string>\r
-#include "NSSyncInfo.h"\r
-#include "NSMessage.h"\r
-#include "NSUtils.h"\r
-#include "NSTopicsList.h"\r
-\r
-namespace OIC\r
-{\r
-    namespace Service\r
-    {\r
-        /**\r
-         * @class   NSProvider\r
-         * @brief   This class provides a set of Notification service Provider representation APIs.\r
-         */\r
-        class NSProvider\r
-        {\r
-            public:\r
-\r
-                /**\r
-                     * Invoked when the provider state is changed\r
-                     * @param[in] providerState  NSProviderState of the notification resource\r
-                     */\r
-                typedef void (* ProviderStateCallback)(NSProviderState);\r
-\r
-                /**\r
-                     * Consumer use this callback function to receive notification message from provider\r
-                     * synchronization\r
-                     * @param[in] message     Notification message\r
-                     */\r
-                typedef void (*MessageReceivedCallback)(NSMessage *);\r
-\r
-                /**\r
-                     * Provider and consumer use this callback function to receive the status of the message\r
-                     * synchronization\r
-                     * @param[in] sync        Synchronization information of the notification message\r
-                     */\r
-                typedef void (*SyncInfoReceivedCallback)(NSSyncInfo *);\r
-\r
-                /**\r
-                      * Constructor of NSProvider.\r
-                      */\r
-                NSProvider(): m_topicList(new NSTopicsList()), m_state(NSProviderState::DENY),\r
-                    m_subscribedState(NSProviderSubscribedState::DENY),\r
-                    m_stateCb(NULL), m_messageCb(NULL), m_syncInfoCb(NULL)\r
-                {\r
-                }\r
-\r
-                /**\r
-                      * Constructor of NSProvider.\r
-                      *\r
-                      * @param providerId - providerId of the Notification.\r
-                      */\r
-                NSProvider(const std::string &providerId) : m_providerId(providerId),\r
-                    m_topicList(new NSTopicsList()), m_state(NSProviderState::DENY),\r
-                    m_subscribedState(NSProviderSubscribedState::DENY),\r
-                    m_stateCb(NULL), m_messageCb(NULL), m_syncInfoCb(NULL)\r
-                {\r
-                }\r
-\r
-                /**\r
-                      * Constructor of NSProvider.\r
-                      *\r
-                      * @param providerId - providerId of the Notification.\r
-                      * @param topicList - NSTopicsList of interested Topics.\r
-                      */\r
-                NSProvider(const std::string &providerId, NSTopicsList *topicList) : m_providerId(\r
-                        providerId), m_topicList(topicList), m_state(NSProviderState::DENY),\r
-                    m_subscribedState(NSProviderSubscribedState::DENY),\r
-                    m_stateCb(NULL), m_messageCb(NULL), m_syncInfoCb(NULL)\r
-                {\r
-                }\r
-\r
-                /**\r
-                      * Constructor of NSProvider.\r
-                      *\r
-                      * @param provider - of type NSProvider.\r
-                      */\r
-                NSProvider(::NSProvider *provider);\r
-\r
-                /**\r
-                     * Copy Constructor of NSProvider.\r
-                     *\r
-                     * @param provider - NSProvider to initialize.\r
-                     */\r
-                NSProvider(const NSProvider &provider);\r
-\r
-                /**\r
-                     * Copy assignment operator of NSProvider.\r
-                     *\r
-                     * @param provider -  NSProvider to initialize.\r
-                     * @return NSProvider object reference\r
-                     */\r
-                NSProvider &operator=(const NSProvider &provider);\r
-\r
-                /**\r
-                      * Destructor of NSProvider.\r
-                      */\r
-                ~NSProvider();\r
-\r
-                /**\r
-                      * This method is for getting ProviderId from the Notification service provider.\r
-                      *\r
-                      * @return ProviderId as string.\r
-                      */\r
-                std::string getProviderId() const;\r
-\r
-                /**\r
-                      * This method is for getting NSTopic List from the Notification service provider.\r
-                      *\r
-                      * @return NSTopicsList  as pointer.\r
-                      */\r
-                NSTopicsList *getTopicList() const;\r
-\r
-                /**\r
-                     * Update Topic list that is wanted to be subscribed from provider\r
-                     *\r
-                     * @param topicList - NSTopicsList of interested Topics.\r
-                     * @return NSResult\r
-                     */\r
-                NSResult updateTopicList(NSTopicsList *topicList);\r
-\r
-                /**\r
-                      * This method is for getting ProviderState from the Notification service provider.\r
-                      *\r
-                      * @return ProviderState as NSProviderState.\r
-                      */\r
-                NSProviderState getProviderState() const;\r
-\r
-                /**\r
-                      * This method is for getting SubscribedState from the Notification service provider.\r
-                      *\r
-                      * @return subscribedState as NSProviderSubscribedState.\r
-                      */\r
-                NSProviderSubscribedState getProviderSubscribedState() const;\r
-\r
-                /**\r
-                      * This method is for requesting subscription of Notification service.\r
-                      *\r
-                      */\r
-                void subscribe();\r
-\r
-                /**\r
-                      * This method is for requesting subscription status from Provider of Notification service.\r
-                      *\r
-                      */\r
-                bool isSubscribed();\r
-\r
-                /**\r
-                      * This method is for Sending SyncInfo of Notification service.\r
-                      *\r
-                      * @param messageId - id of type message.\r
-                      * @param type - NSSyncType of Notification service.\r
-                      */\r
-                void sendSyncInfo(uint64_t messageId, NSSyncInfo::NSSyncType type);\r
-\r
-                /**\r
-                      * This method is for registering for listeners of Notification .\r
-                      *\r
-                      * @param stateHandle - ProviderStateCallback callback.\r
-                      * @param messageHandle - MessageReceivedCallback callback.\r
-                      * @param syncHandle - SyncInfoReceivedCallback callback\r
-                      */\r
-                void setListener(ProviderStateCallback stateHandle,\r
-                                 MessageReceivedCallback messageHandle,\r
-                                 SyncInfoReceivedCallback syncHandle);\r
-\r
-                /**\r
-                      * This method is for getting the registered cb of Provider State received.\r
-                      *\r
-                      * @return stateCb - ProviderStateCallback .\r
-                      */\r
-                ProviderStateCallback getProviderStateReceivedCb() const;\r
-\r
-                /**\r
-                      * This method is for getting the registered cb of Notification message received.\r
-                      *\r
-                      * @return messageCb - MessageReceivedCallback .\r
-                      */\r
-                MessageReceivedCallback getMessageReceivedCb() const;\r
-\r
-                /**\r
-                      * This method is for getting the registered cb of Notification SyncInfo received.\r
-                      *\r
-                      * @return syncInfoCb - SyncInfoReceivedCallback .\r
-                      */\r
-                SyncInfoReceivedCallback getSyncInfoReceivedCb() const;\r
-\r
-                /**\r
-                      * This method is for setting NSTopic List for the Notification service provider.\r
-                      *\r
-                      * @param topicsList  as NSTopicsList pointer.\r
-                      */\r
-                void setTopicList(NSTopicsList *topicsList);\r
-\r
-                /**\r
-                     * This method is for setting ProviderState for the Notification service provider.\r
-                     *\r
-                     * @param providerState as NSProviderState.\r
-                     */\r
-                void setProviderState(const NSProviderState &providerState);\r
-\r
-                /**\r
-                     * This method is for setting subscribedState for the Notification service provider.\r
-                     *\r
-                     * @param subscribedState as NSProviderSubscribedState.\r
-                     */\r
-                void setProviderSubscribedState(const NSProviderSubscribedState &subscribedState);\r
-\r
-            private:\r
-                ::NSProvider *getNSProvider();\r
-\r
-            private:\r
-                std::string m_providerId;\r
-                NSTopicsList *m_topicList;\r
-                NSProviderState m_state;\r
-                NSProviderSubscribedState m_subscribedState;\r
-\r
-                ProviderStateCallback m_stateCb;\r
-                MessageReceivedCallback m_messageCb;\r
-                SyncInfoReceivedCallback m_syncInfoCb;\r
-        };\r
-    }\r
-}\r
-#endif /* _NS_PROVIDER_H_ */\r
+//******************************************************************
+//
+// Copyright 2016 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 Notification service Provider representation.
+ */
+
+#ifndef _NS_PROVIDER_H_
+#define _NS_PROVIDER_H_
+
+
+#include <string>
+#include "NSSyncInfo.h"
+#include "NSMessage.h"
+#include "NSUtils.h"
+#include "NSTopicsList.h"
+#include "NSException.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        /**
+         * @class   NSProvider
+         * @brief   This class provides a set of Notification service Provider representation APIs.
+         */
+        class NSProvider
+        {
+            public:
+
+                /**
+                     * Invoked when the provider state is changed
+                     * @param[in] providerState  NSProviderState of the notification resource
+                     */
+                typedef void (* ProviderStateCallback)(NSProviderState);
+
+                /**
+                     * Consumer use this callback function to receive notification message from provider
+                     * synchronization
+                     * @param[in] message     Notification message
+                     */
+                typedef void (*MessageReceivedCallback)(NSMessage);
+
+                /**
+                     * Provider and consumer use this callback function to receive the status of the message
+                     * synchronization
+                     * @param[in] sync        Synchronization information of the notification message
+                     */
+                typedef void (*SyncInfoReceivedCallback)(NSSyncInfo);
+
+                /**
+                      * Constructor of NSProvider.
+                      */
+                NSProvider(): m_topicList(std::make_shared<NSTopicsList>()), m_state(NSProviderState::DENY),
+                    m_subscribedState(NSProviderSubscribedState::DENY),
+                    m_stateCb(NULL), m_messageCb(NULL), m_syncInfoCb(NULL)
+                {
+                }
+
+                /**
+                      * Constructor of NSProvider.
+                      *
+                      * @param providerId - providerId of the Notification.
+                      */
+                NSProvider(const std::string &providerId) : m_providerId(providerId),
+                    m_topicList(std::make_shared<NSTopicsList>()), m_state(NSProviderState::DENY),
+                    m_subscribedState(NSProviderSubscribedState::DENY),
+                    m_stateCb(NULL), m_messageCb(NULL), m_syncInfoCb(NULL)
+                {
+                }
+
+                /**
+                      * Constructor of NSProvider.
+                      *
+                      * @param providerId - providerId of the Notification.
+                      * @param topicList - NSTopicsList of interested Topics.
+                      */
+                NSProvider(const std::string &providerId, std::shared_ptr<NSTopicsList> topicList) : m_providerId(
+                        providerId), m_topicList(topicList), m_state(NSProviderState::DENY),
+                    m_subscribedState(NSProviderSubscribedState::DENY),
+                    m_stateCb(NULL), m_messageCb(NULL), m_syncInfoCb(NULL)
+                {
+                }
+
+                /**
+                      * Constructor of NSProvider.
+                      *
+                      * @param provider - of type NSProvider.
+                      */
+                NSProvider(::NSProvider *provider);
+
+                /**
+                     * Copy Constructor of NSProvider.
+                     *
+                     * @param provider - NSProvider to initialize.
+                     */
+                NSProvider(const NSProvider &provider);
+
+                /**
+                     * Copy assignment operator of NSProvider.
+                     *
+                     * @param provider -  NSProvider to initialize.
+                     * @return NSProvider object reference
+                     */
+                NSProvider &operator=(const NSProvider &provider);
+
+                /**
+                      * Destructor of NSProvider.
+                      */
+                ~NSProvider() = default;
+
+                /**
+                      * This method is for getting ProviderId from the Notification service provider.
+                      *
+                      * @return ProviderId as string.
+                      */
+                std::string getProviderId() const;
+
+                /**
+                      * This method is for getting NSTopic List from the Notification service provider.
+                      *
+                      * @return NSTopicsList  as pointer.
+                      */
+                std::shared_ptr<NSTopicsList> getTopicList() const  throw (NSException);
+
+                /**
+                     * Update Topic list that is wanted to be subscribed from provider
+                     *
+                     * @param topicList - NSTopicsList of interested Topics.
+                     * @return NSResult
+                     */
+                NSResult updateTopicList(std::shared_ptr<NSTopicsList> topicList)  throw (NSException);
+
+                /**
+                      * This method is for getting ProviderState from the Notification service provider.
+                      *
+                      * @return ProviderState as NSProviderState.
+                      */
+                NSProviderState getProviderState() const;
+
+                /**
+                      * This method is for getting SubscribedState from the Notification service provider.
+                      *
+                      * @return subscribedState as NSProviderSubscribedState.
+                      */
+                NSProviderSubscribedState getProviderSubscribedState() const  throw (NSException);
+
+                /**
+                      * This method is for requesting subscription of Notification service.
+                      * This API should be called with a valid Provider object obtained from Discovery callback.
+                      * The API should not be called when the Provider is in STOPPED state.
+                      *
+                      * Discovery APIs to discover Providers are as below.
+                      * Start/rescanProvider for D2D,
+                      * enableRemoteService for D2S,
+                      *
+                      * @return ::NS_OK or result code of NSResult
+                      */
+                NSResult subscribe()  throw (NSException);
+
+                /**
+                      * Request to unsubscribe in order not to receive notification message from provider
+                      *
+                      * This API should be called with a valid Provider object obtained from Discovery callback.
+                      * The API should not be called when the Provider is in STOPPED state.
+                      *
+                      * @return ::NS_OK or result code of NSResult
+                     */
+                NSResult unsubscribe()  throw (NSException);
+
+                /**
+                      * This method is for requesting subscription status from Provider of Notification service.
+                      *
+                      */
+                bool isSubscribed()  throw (NSException);
+
+                /**
+                      * This method is for Sending SyncInfo of Notification service.
+                      *
+                      * @param messageId - id of type message.
+                      * @param type - NSSyncType of Notification service.
+                      * @return ::NS_OK or result code of NSResult
+                      */
+                NSResult sendSyncInfo(uint64_t messageId, NSSyncInfo::NSSyncType type)  throw (NSException);
+
+                /**
+                      * This method is for registering for listeners of Notification .
+                      *
+                      * @param stateHandle - ProviderStateCallback callback.
+                      * @param messageHandle - MessageReceivedCallback callback.
+                      * @param syncHandle - SyncInfoReceivedCallback callback
+                      */
+                void setListener(ProviderStateCallback stateHandle,
+                                 MessageReceivedCallback messageHandle,
+                                 SyncInfoReceivedCallback syncHandle);
+
+                /**
+                      * This method is for getting the registered cb of Provider State received.
+                      *
+                      * @return stateCb - ProviderStateCallback .
+                      */
+                ProviderStateCallback getProviderStateReceivedCb() const;
+
+                /**
+                      * This method is for getting the registered cb of Notification message received.
+                      *
+                      * @return messageCb - MessageReceivedCallback .
+                      */
+                MessageReceivedCallback getMessageReceivedCb() const;
+
+                /**
+                      * This method is for getting the registered cb of Notification SyncInfo received.
+                      *
+                      * @return syncInfoCb - SyncInfoReceivedCallback .
+                      */
+                SyncInfoReceivedCallback getSyncInfoReceivedCb() const;
+
+                /**
+                      * This method is for setting NSTopic List for the Notification service provider.
+                      *
+                      * @param topicsList  as NSTopicsList pointer.
+                      */
+                void setTopicList(std::shared_ptr<NSTopicsList> topicsList);
+
+                /**
+                     * This method is for setting ProviderState for the Notification service provider.
+                     *
+                     * @param providerState as NSProviderState.
+                     */
+                void setProviderState(const NSProviderState &providerState);
+
+                /**
+                     * This method is for setting subscribedState for the Notification service provider.
+                     *
+                     * @param subscribedState as NSProviderSubscribedState.
+                     */
+                void setProviderSubscribedState(const NSProviderSubscribedState &subscribedState);
+
+            private:
+                ::NSProvider *getNSProvider();
+                bool isValid() const;
+
+            private:
+                std::string m_providerId;
+                std::shared_ptr<NSTopicsList> m_topicList;
+                NSProviderState m_state;
+                NSProviderSubscribedState m_subscribedState;
+
+                ProviderStateCallback m_stateCb;
+                MessageReceivedCallback m_messageCb;
+                SyncInfoReceivedCallback m_syncInfoCb;
+        };
+    }
+}
+#endif /* _NS_PROVIDER_H_ */
diff --git a/service/notification/cpp-wrapper/consumer/src/NSAcceptedProviders.cpp b/service/notification/cpp-wrapper/consumer/src/NSAcceptedProviders.cpp
new file mode 100755 (executable)
index 0000000..ac2408c
--- /dev/null
@@ -0,0 +1,96 @@
+//******************************************************************
+//
+// Copyright 2017 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 "NSAcceptedProviders.h"
+#include <cstring>
+#include "NSCommon.h"
+#include "NSConstants.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        std::shared_ptr<NSProvider> NSAcceptedProviders::getProvider(const std::string &id)
+        {
+            std::lock_guard<std::mutex> lock(m_mutex);
+            NS_LOG_V(DEBUG, "AcceptedProviders::getProvider size  : %d", (int) m_providers.size());
+            auto it = m_providers.find(id);
+            if (it != m_providers.end() )
+            {
+                NS_LOG(DEBUG, "getProvider : Found Provider with given ID");
+                return it->second;
+            }
+            NS_LOG(DEBUG, "getProvider : Not Found Provider with given ID");
+            return NULL;
+        }
+        void NSAcceptedProviders::addProvider(std::shared_ptr<NSProvider> provider)
+        {
+            std::lock_guard<std::mutex> lock(m_mutex);
+            NS_LOG_V(INFO_PRIVATE, "AcceptedProviders::addProvider  Id : %s", provider->getProviderId().c_str());
+            m_providers[provider->getProviderId()] = provider;
+            return;
+        }
+
+        void NSAcceptedProviders::removeProvider(const std::string &id)
+        {
+            std::lock_guard<std::mutex> lock(m_mutex);
+            NS_LOG_V(INFO_PRIVATE, "AcceptedProviders::removeProvider  Id : %s", id.c_str());
+            m_providers.erase(id);
+            return;
+        }
+
+        bool NSAcceptedProviders::isAccepted(const std::string &id)
+        {
+            std::lock_guard<std::mutex> lock(m_mutex);
+            NS_LOG_V(INFO_PRIVATE, "AcceptedProviders::isAccepted  Id : %s", id.c_str());
+            if ( m_providers.find(id) == m_providers.end() )
+            {
+                NS_LOG(DEBUG, "isAccepted : Not Found Provider with given ID");
+                return false;
+            }
+            else
+            {
+                NS_LOG(DEBUG, "isAccepted : Found Provider with given ID");
+                return true;
+            }
+        }
+
+        int NSAcceptedProviders::size()
+        {
+            std::lock_guard<std::mutex> lock(m_mutex);
+            NS_LOG_V(DEBUG, "AcceptedProviders::size  : %d", (int) m_providers.size());
+            return m_providers.size();
+        }
+
+        void NSAcceptedProviders::removeProviders()
+        {
+            std::lock_guard<std::mutex> lock(m_mutex);
+            NS_LOG(DEBUG, "AcceptedProviders::removeProviders ");
+            m_providers.clear();
+            return;
+        }
+
+        std::map<std::string, std::shared_ptr<NSProvider> > NSAcceptedProviders::getProviders()
+        {
+            std::lock_guard<std::mutex> lock(m_mutex);
+            return m_providers;
+        }
+    }
+}
index 67b7fb6..d242919 100755 (executable)
-//******************************************************************\r
-//\r
-// Copyright 2016 Samsung Electronics All Rights Reserved.\r
-//\r
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
-//\r
-// Licensed under the Apache License, Version 2.0 (the "License");\r
-// you may not use this file except in compliance with the License.\r
-// You may obtain a copy of the License at\r
-//\r
-//      http://www.apache.org/licenses/LICENSE-2.0\r
-//\r
-// Unless required by applicable law or agreed to in writing, software\r
-// distributed under the License is distributed on an "AS IS" BASIS,\r
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-// See the License for the specific language governing permissions and\r
-// limitations under the License.\r
-//\r
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
-\r
-#include "NSConsumerService.h"\r
-#include <cstring>\r
-#include "NSConsumerInterface.h"\r
-#include "NSMessage.h"\r
-#include "NSCommon.h"\r
-#include "NSConstants.h"\r
-#include "oic_string.h"\r
-#include "oic_malloc.h"\r
-\r
-namespace OIC\r
-{\r
-    namespace Service\r
-    {\r
-        void onProviderStateReceived(::NSProvider *provider, ::NSProviderState state)\r
-        {\r
-            NS_LOG(DEBUG, "onNSProviderStateChanged - IN");\r
-            NS_LOG_V(DEBUG, "provider Id : %s", provider->providerId);\r
-            NS_LOG_V(DEBUG, "state : %d", (int)state);\r
-\r
-            std::string provId;\r
-            provId.assign(provider->providerId, NS_UTILS_UUID_STRING_SIZE - 1);\r
-            NSProvider *oldProvider = NSConsumerService::getInstance()->getProvider(provId);\r
-\r
-            if (oldProvider == nullptr)\r
-            {\r
-                NSProvider *nsProvider = new NSProvider(provider);\r
-                NS_LOG(DEBUG, "Provider with same Id do not exist. updating Data for New Provider");\r
-                auto discoveredCallback = NSConsumerService::getInstance()->getProviderDiscoveredCb();\r
-                nsProvider->setProviderState((NSProviderState)state);\r
-                auto topicLL = NSConsumerGetTopicList(provider->providerId);\r
-                nsProvider->setTopicList(new NSTopicsList(topicLL));\r
-                if (state == NS_DISCOVERED)\r
-                {\r
-                    nsProvider->setProviderSubscribedState(NSProviderSubscribedState::DISCOVERED);\r
-                    if (discoveredCallback != NULL)\r
-                    {\r
-                        NS_LOG(DEBUG, "initiating the Discovered callback : NS_DISCOVERED, policy false");\r
-                        discoveredCallback(nsProvider);\r
-                    }\r
-                }\r
-                else if (state == NS_ALLOW)\r
-                {\r
-                    nsProvider->setProviderSubscribedState(NSProviderSubscribedState::SUBSCRIBED);\r
-                    if (discoveredCallback != NULL)\r
-                    {\r
-                        NS_LOG(DEBUG, "initiating the Discovered callback : NS_ALLOW, policy true");\r
-                        discoveredCallback(nsProvider);\r
-                    }\r
-                }\r
-                NSConsumerService::getInstance()->getAcceptedProviders().push_back(nsProvider);\r
-            }\r
-            else\r
-            {\r
-                NS_LOG(DEBUG, "Provider with same Id exists. updating the old Provider data");\r
-                auto changeCallback = oldProvider->getProviderStateReceivedCb();\r
-                auto prevState = oldProvider->getProviderState();\r
-                oldProvider->setProviderState((NSProviderState)state);\r
-                if (state == NS_ALLOW)\r
-                {\r
-                    oldProvider->setProviderSubscribedState(NSProviderSubscribedState::SUBSCRIBED);\r
-                    if (changeCallback != NULL)\r
-                    {\r
-                        NS_LOG(DEBUG, "initiating the callback for Response : NS_ALLOW");\r
-                        changeCallback((NSProviderState)state);\r
-                    }\r
-                    else\r
-                    {\r
-                        oldProvider->setProviderSubscribedState(NSProviderSubscribedState::SUBSCRIBED);\r
-                        auto discoveredCallback = NSConsumerService::getInstance()->getProviderDiscoveredCb();\r
-                        discoveredCallback(oldProvider);\r
-                        auto changeCallback = oldProvider->getProviderStateReceivedCb();\r
-                        changeCallback(prevState);\r
-                    }\r
-                }\r
-                else if (state == NS_DENY)\r
-                {\r
-                    oldProvider->setProviderSubscribedState(NSProviderSubscribedState::DENY);\r
-                    NSConsumerService::getInstance()->getAcceptedProviders().remove(oldProvider);\r
-                    if (changeCallback != NULL)\r
-                    {\r
-                        NS_LOG(DEBUG, "initiating the callback for Response : NS_DENY");\r
-                        changeCallback((NSProviderState)state);\r
-                    }\r
-                    delete oldProvider;\r
-                }\r
-                else if (state == NS_TOPIC)\r
-                {\r
-                    auto topicLL = NSConsumerGetTopicList(provider->providerId);\r
-                    oldProvider->setTopicList(new NSTopicsList(topicLL));\r
-                    if (changeCallback != NULL)\r
-                    {\r
-                        NS_LOG(DEBUG, "initiating the callback for Response : NS_TOPIC");\r
-                        changeCallback((NSProviderState)state);\r
-                    }\r
-                    if (topicLL)\r
-                    {\r
-                        NSTopicLL *iter = topicLL;\r
-                        NSTopicLL *following = NULL;\r
-\r
-                        while (iter)\r
-                        {\r
-                            following = iter->next;\r
-                            if (iter)\r
-                            {\r
-                                NSOICFree(iter->topicName);\r
-                                iter->next = NULL;\r
-                                NSOICFree(iter);\r
-                            }\r
-                            iter = following;\r
-                        }\r
-                    }\r
-                }\r
-                else if (state == NS_STOPPED)\r
-                {\r
-                    oldProvider->setProviderSubscribedState(NSProviderSubscribedState::DENY);\r
-                    NSConsumerService::getInstance()->getAcceptedProviders().remove(oldProvider);\r
-                    NS_LOG(DEBUG, "initiating the State callback : NS_STOPPED");\r
-                    if (changeCallback != NULL)\r
-                    {\r
-                        NS_LOG(DEBUG, "initiating the callback for Response : NS_STOPPED");\r
-                        changeCallback((NSProviderState)state);\r
-                    }\r
-                }\r
-            }\r
-            NS_LOG(DEBUG, "onNSProviderStateChanged - OUT");\r
-        }\r
-\r
-        void onNSMessageReceived(::NSMessage *message)\r
-        {\r
-            NS_LOG(DEBUG, "onNSMessageReceived - IN");\r
-            NS_LOG_V(DEBUG, "message->providerId : %s", message->providerId);\r
-\r
-            NSMessage *nsMessage = new NSMessage(message);\r
-\r
-            NS_LOG_V(DEBUG, "getAcceptedProviders Size : %d", (int)\r
-                     NSConsumerService::getInstance()->getAcceptedProviders().size());\r
-            for (auto it : NSConsumerService::getInstance()->getAcceptedProviders())\r
-            {\r
-                if (it->getProviderId() == nsMessage->getProviderId())\r
-                {\r
-                    NS_LOG(DEBUG, "Found Provider with given ID");\r
-                    auto callback = it->getMessageReceivedCb();\r
-                    if (callback != NULL)\r
-                    {\r
-                        NS_LOG(DEBUG, "initiating the callback for messageReceived");\r
-                        callback(nsMessage);\r
-                    }\r
-                    break;\r
-                }\r
-            }\r
-            delete nsMessage;\r
-            NS_LOG(DEBUG, "onNSMessageReceived - OUT");\r
-        }\r
-\r
-        void onNSSyncInfoReceived(::NSSyncInfo *syncInfo)\r
-        {\r
-            NS_LOG(DEBUG, "onNSSyncInfoReceived - IN");\r
-            NSSyncInfo *nsSyncInfo = new NSSyncInfo(syncInfo);\r
-            for (auto it : NSConsumerService::getInstance()->getAcceptedProviders())\r
-            {\r
-                if (it->getProviderId() == nsSyncInfo->getProviderId())\r
-                {\r
-                    NS_LOG(DEBUG, "Found Provider with given ID");\r
-                    auto callback = it->getSyncInfoReceivedCb();\r
-                    if (callback != NULL)\r
-                    {\r
-                        NS_LOG(DEBUG, "initiating the callback for SyncInfoReceived");\r
-                        callback(nsSyncInfo);\r
-                    }\r
-                    break;\r
-                }\r
-            }\r
-            delete nsSyncInfo;\r
-            NS_LOG(DEBUG, "onNSSyncInfoReceived - OUT");\r
-        }\r
-\r
-        NSConsumerService::NSConsumerService()\r
-        {\r
-            m_providerDiscoveredCb = NULL;\r
-        }\r
-\r
-        NSConsumerService::~NSConsumerService()\r
-        {\r
-            for (auto it : getAcceptedProviders())\r
-            {\r
-                delete it;\r
-            }\r
-            getAcceptedProviders().clear();\r
-        }\r
-\r
-        NSConsumerService *NSConsumerService::getInstance()\r
-        {\r
-            static  NSConsumerService s_instance;\r
-            return &s_instance;\r
-        }\r
-\r
-        void NSConsumerService::start(NSConsumerService::ProviderDiscoveredCallback providerDiscovered)\r
-        {\r
-            NS_LOG(DEBUG, "start - IN");\r
-            m_providerDiscoveredCb = providerDiscovered;\r
-            NSConsumerConfig nsConfig;\r
-            nsConfig.changedCb = onProviderStateReceived;\r
-            nsConfig.messageCb = onNSMessageReceived;\r
-            nsConfig.syncInfoCb = onNSSyncInfoReceived;\r
-\r
-            NSStartConsumer(nsConfig);\r
-            NS_LOG(DEBUG, "start - OUT");\r
-            return;\r
-        }\r
-\r
-        void NSConsumerService::stop()\r
-        {\r
-            NS_LOG(DEBUG, "stop - IN");\r
-            NSStopConsumer();\r
-            for (auto it : getAcceptedProviders())\r
-            {\r
-                delete it;\r
-            }\r
-            getAcceptedProviders().clear();\r
-            NS_LOG(DEBUG, "stop - OUT");\r
-            return;\r
-        }\r
-\r
-        NSResult NSConsumerService::enableRemoteService(const std::string &serverAddress)\r
-        {\r
-            NS_LOG(DEBUG, "enableRemoteService - IN");\r
-            NS_LOG_V(DEBUG, "Server Address : %s", serverAddress.c_str());\r
-            NSResult result = NSResult::ERROR;\r
-#ifdef WITH_CLOUD\r
-            result = (NSResult) NSConsumerEnableRemoteService(OICStrdup(serverAddress.c_str()));\r
-#else\r
-            NS_LOG(ERROR, "Remote Services feature is not enabled in the Build");\r
-            (void) serverAddress;\r
-#endif\r
-            NS_LOG(DEBUG, "enableRemoteService - OUT");\r
-            return result;\r
-        }\r
-\r
-        void NSConsumerService::rescanProvider()\r
-        {\r
-            NS_LOG(DEBUG, "rescanProvider - IN");\r
-            NSRescanProvider();\r
-            NS_LOG(DEBUG, "rescanProvider - OUT");\r
-            return;\r
-        }\r
-\r
-        NSConsumerService::ProviderDiscoveredCallback NSConsumerService::getProviderDiscoveredCb()\r
-        {\r
-            return m_providerDiscoveredCb;\r
-        }\r
-\r
-        NSProvider *NSConsumerService::getProvider(const std::string &id)\r
-        {\r
-            for (auto it : getAcceptedProviders())\r
-            {\r
-                if (it->getProviderId() == id)\r
-                {\r
-                    NS_LOG(DEBUG, "getProvider : Found Provider with given ID");\r
-                    return it;\r
-                }\r
-            }\r
-            NS_LOG(DEBUG, "getProvider : Not Found Provider with given ID");\r
-            return NULL;\r
-        }\r
-\r
-        std::list<NSProvider *> &NSConsumerService::getAcceptedProviders()\r
-        {\r
-            return m_acceptedProviders;\r
-        }\r
-    }\r
-}\r
+//******************************************************************
+//
+// Copyright 2016 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 "NSConsumerService.h"
+#include <cstring>
+#include "NSConsumerInterface.h"
+#include "NSAcceptedProviders.h"
+#include "NSMessage.h"
+#include "NSCommon.h"
+#include "NSConstants.h"
+#include "oic_string.h"
+#include "oic_malloc.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        void NSConsumerService::onProviderStateReceived(::NSProvider *provider, ::NSProviderState state)
+        {
+            NS_LOG(DEBUG, "onNSProviderStateChanged - IN");
+            NS_LOG_V(INFO_PRIVATE, "provider Id : %s", provider->providerId);
+            NS_LOG_V(DEBUG, "state : %d", (int)state);
+
+            std::string provId;
+            provId.assign(provider->providerId, NS_UTILS_UUID_STRING_SIZE - 1);
+            std::shared_ptr<NSProvider> oldProvider =
+                NSConsumerService::getInstance()->getProvider(provId);
+
+            if (oldProvider == nullptr)
+            {
+                //Callback received for First time from new Provider as there is no reference to
+                //previous Provider with same ID in internal map.
+                //States received during discovery of Provider : NS_DISCOVERED and NS_ALLOW
+                std::shared_ptr<NSProvider> nsProvider = std::make_shared<NSProvider>(provider);
+                NS_LOG(DEBUG, "Provider with same Id do not exist. updating Data for New Provider");
+                auto discoveredCallback = NSConsumerService::getInstance()->getProviderDiscoveredCb();
+                nsProvider->setProviderState((NSProviderState)state);
+                auto topicLL = NSConsumerGetTopicList(provider->providerId);
+                nsProvider->setTopicList(std::make_shared<NSTopicsList>(topicLL, false));
+                NSConsumerService::getInstance()->getAcceptedProviders()->addProvider(nsProvider);
+                if (state == NS_DISCOVERED)
+                {
+                    nsProvider->setProviderSubscribedState(NSProviderSubscribedState::DISCOVERED);
+                    if (discoveredCallback != NULL)
+                    {
+                        NS_LOG(DEBUG,
+                               "initiating the Discovered callback : NS_DISCOVERED, policy false, Accepter: Consumer");
+                        discoveredCallback(nsProvider);
+                    }
+                }
+                else if (state == NS_ALLOW)
+                {
+                    nsProvider->setProviderSubscribedState(NSProviderSubscribedState::SUBSCRIBED);
+                    if (discoveredCallback != NULL)
+                    {
+                        NS_LOG(DEBUG, "initiating the Discovered callback : NS_ALLOW, policy true, Accepter: Provider");
+                        discoveredCallback(nsProvider);
+                    }
+                }
+            }
+            else
+            {
+                //Callback received from already discovered and existing Provider in internal map.
+                //States received Post discovery of Provider.
+                NS_LOG(DEBUG, "Provider with same Id exists. updating the old Provider data");
+                auto changeCallback = oldProvider->getProviderStateReceivedCb();
+                auto prevState = oldProvider->getProviderState();
+                oldProvider->setProviderState((NSProviderState)state);
+                if (state == NS_ALLOW)
+                {
+                    oldProvider->setProviderSubscribedState(NSProviderSubscribedState::SUBSCRIBED);
+                    if (changeCallback != NULL)
+                    {
+                        NS_LOG(DEBUG, "initiating the callback for Response : NS_ALLOW");
+                        changeCallback((NSProviderState)state);
+                    }
+                    else
+                    {
+                        oldProvider->setProviderSubscribedState(NSProviderSubscribedState::SUBSCRIBED);
+                        auto discoveredCallback = NSConsumerService::getInstance()->getProviderDiscoveredCb();
+                        if (discoveredCallback != NULL)
+                        {
+                            discoveredCallback(oldProvider);
+                        }
+                        auto changeCallback = oldProvider->getProviderStateReceivedCb();
+                        if (changeCallback != NULL)
+                        {
+                            changeCallback(prevState);
+                        }
+                    }
+                }
+                else if (state == NS_DENY)
+                {
+                    oldProvider->setProviderSubscribedState(NSProviderSubscribedState::DENY);
+                    NSConsumerService::getInstance()->getAcceptedProviders()->removeProvider(
+                        oldProvider->getProviderId());
+                    if (changeCallback != NULL)
+                    {
+                        NS_LOG(DEBUG, "initiating the callback for Response : NS_DENY");
+                        changeCallback((NSProviderState)state);
+                    }
+                }
+                else if (state == NS_TOPIC)
+                {
+                    auto topicLL = NSConsumerGetTopicList(provider->providerId);
+                    oldProvider->setTopicList(std::make_shared<NSTopicsList>(topicLL, false));
+                    if (changeCallback != NULL)
+                    {
+                        NS_LOG(DEBUG, "initiating the callback for Response : NS_TOPIC");
+                        changeCallback((NSProviderState)state);
+                    }
+                    if (topicLL)
+                    {
+                        NSTopicLL *iter = topicLL;
+                        NSTopicLL *following = NULL;
+
+                        while (iter)
+                        {
+                            following = iter->next;
+                            if (iter)
+                            {
+                                NSOICFree(iter->topicName);
+                                iter->next = NULL;
+                                NSOICFree(iter);
+                            }
+                            iter = following;
+                        }
+                    }
+                }
+                else if (state == NS_STOPPED)
+                {
+                    oldProvider->setProviderSubscribedState(NSProviderSubscribedState::DENY);
+                    oldProvider->getTopicList()->unsetModifiability();
+                    NSConsumerService::getInstance()->getAcceptedProviders()->removeProvider(
+                        oldProvider->getProviderId());
+                    NS_LOG(DEBUG, "initiating the State callback : NS_STOPPED");
+                    if (changeCallback != NULL)
+                    {
+                        NS_LOG(DEBUG, "initiating the callback for Response : NS_STOPPED");
+                        changeCallback((NSProviderState)state);
+                    }
+                }
+            }
+            NS_LOG(DEBUG, "onNSProviderStateChanged - OUT");
+        }
+
+        void NSConsumerService::onNSMessageReceived(::NSMessage *message)
+        {
+            NS_LOG(DEBUG, "onNSMessageReceived - IN");
+            NS_LOG_V(INFO_PRIVATE, "message->providerId : %s", message->providerId);
+
+            NSMessage nsMessage(message);
+
+            if (NSConsumerService::getInstance()->getAcceptedProviders()->isAccepted(
+                    nsMessage.getProviderId()))
+            {
+                auto provider = NSConsumerService::getInstance()->getProvider(
+                                    nsMessage.getProviderId());
+                if (provider != nullptr)
+                {
+                    NS_LOG(DEBUG, "Found Provider with given ID");
+                    auto callback = provider->getMessageReceivedCb();
+                    if (callback != NULL)
+                    {
+                        NS_LOG(DEBUG, "initiating the callback for messageReceived");
+                        callback(nsMessage);
+                    }
+                }
+            }
+            NS_LOG(DEBUG, "onNSMessageReceived - OUT");
+        }
+
+        void NSConsumerService::onNSSyncInfoReceived(::NSSyncInfo *syncInfo)
+        {
+            NS_LOG(DEBUG, "onNSSyncInfoReceived - IN");
+            NS_LOG_V(INFO_PRIVATE, "syncInfo->providerId : %s", syncInfo->providerId);
+
+            NSSyncInfo nsSyncInfo(syncInfo);
+
+            if (NSConsumerService::getInstance()->getAcceptedProviders()->isAccepted(
+                    nsSyncInfo.getProviderId()))
+            {
+                auto provider = NSConsumerService::getInstance()->getProvider(
+                                    nsSyncInfo.getProviderId());
+                if (provider != nullptr)
+                {
+                    NS_LOG(DEBUG, "Found Provider with given ID");
+                    auto callback = provider->getSyncInfoReceivedCb();
+                    if (callback != NULL)
+                    {
+                        NS_LOG(DEBUG, "initiating the callback for SyncInfoReceived");
+                        callback(nsSyncInfo);
+                    }
+                }
+            }
+            NS_LOG(DEBUG, "onNSSyncInfoReceived - OUT");
+        }
+
+        NSConsumerService::NSConsumerService()
+        {
+            m_providerDiscoveredCb = NULL;
+            m_acceptedProviders = new NSAcceptedProviders();
+        }
+
+        NSConsumerService::~NSConsumerService()
+        {
+            m_acceptedProviders->removeProviders();
+            delete m_acceptedProviders;
+        }
+
+        NSConsumerService *NSConsumerService::getInstance()
+        {
+            static  NSConsumerService s_instance;
+            return &s_instance;
+        }
+
+        NSResult NSConsumerService::start(NSConsumerService::ProviderDiscoveredCallback providerDiscovered)
+        {
+            NS_LOG(DEBUG, "start - IN");
+            m_acceptedProviders->removeProviders();
+
+            m_providerDiscoveredCb = providerDiscovered;
+            NSConsumerConfig nsConfig;
+            nsConfig.changedCb = onProviderStateReceived;
+            nsConfig.messageCb = onNSMessageReceived;
+            nsConfig.syncInfoCb = onNSSyncInfoReceived;
+
+            NSResult result = (NSResult) NSStartConsumer(nsConfig);
+            NS_LOG(DEBUG, "start - OUT");
+            return result;
+        }
+
+        NSResult NSConsumerService::stop()
+        {
+            NS_LOG(DEBUG, "stop - IN");
+            m_providerDiscoveredCb = NULL;
+            m_acceptedProviders->removeProviders();
+
+            NSResult result = (NSResult) NSStopConsumer();
+            NS_LOG(DEBUG, "stop - OUT");
+            return result;
+        }
+
+        NSResult NSConsumerService::enableRemoteService(const std::string &serverAddress)
+        {
+            NS_LOG(DEBUG, "enableRemoteService - IN");
+            NS_LOG_V(INFO_PRIVATE, "Server Address : %s", serverAddress.c_str());
+            NSResult result = NSResult::ERROR;
+#ifdef WITH_CLOUD
+            result = (NSResult) NSConsumerEnableRemoteService(OICStrdup(serverAddress.c_str()));
+#else
+            NS_LOG(ERROR, "Remote Services feature is not enabled in the Build");
+            (void) serverAddress;
+#endif
+            NS_LOG(DEBUG, "enableRemoteService - OUT");
+            return result;
+        }
+
+        NSResult NSConsumerService::subscribeMQService(const std::string &serverAddress,
+                const std::string &topicName)
+        {
+            NS_LOG(DEBUG, "subscribeMQService - IN");
+            NS_LOG_V(INFO_PRIVATE, "Server Address : %s", serverAddress.c_str());
+            NSResult result = NSResult::ERROR;
+#ifdef WITH_MQ
+            result = (NSResult) NSConsumerSubscribeMQService(
+                         serverAddress.c_str(), topicName.c_str());
+#else
+            NS_LOG(ERROR, "MQ Services feature is not enabled in the Build");
+            (void) serverAddress;
+            (void) topicName;
+#endif
+            NS_LOG(DEBUG, "subscribeMQService - OUT");
+            return result;
+        }
+
+        NSResult NSConsumerService::rescanProvider()
+        {
+            NS_LOG(DEBUG, "rescanProvider - IN");
+            NSResult result = (NSResult) NSRescanProvider();
+            NS_LOG(DEBUG, "rescanProvider - OUT");
+            return result;
+        }
+
+        NSConsumerService::ProviderDiscoveredCallback NSConsumerService::getProviderDiscoveredCb()
+        {
+            return m_providerDiscoveredCb;
+        }
+
+        std::shared_ptr<NSProvider> NSConsumerService::getProvider(const std::string &id)
+        {
+            return m_acceptedProviders->getProvider(id);
+        }
+
+        NSAcceptedProviders *NSConsumerService::getAcceptedProviders()
+        {
+            return m_acceptedProviders;
+        }
+    }
+}
index 0c5588a..9272cf3 100755 (executable)
@@ -20,7 +20,9 @@
 \r
 #include "NSProvider.h"\r
 #include <cstring>\r
+#include "NSConsumerService.h"\r
 #include "NSConsumerInterface.h"\r
+#include "NSAcceptedProviders.h"\r
 #include "NSConstants.h"\r
 #include "NSCommon.h"\r
 #include "oic_string.h"\r
@@ -45,7 +47,7 @@ namespace OIC
             m_state = NSProviderState::DENY;\r
             m_subscribedState = NSProviderSubscribedState::DENY;\r
 \r
-            m_topicList = new NSTopicsList();\r
+            m_topicList = std::make_shared<NSTopicsList>();\r
 \r
             if (provider != nullptr)\r
             {\r
@@ -56,15 +58,16 @@ namespace OIC
         NSProvider::NSProvider(const NSProvider &provider)\r
         {\r
             m_providerId = provider.getProviderId();\r
-            m_topicList = new NSTopicsList();\r
+            m_topicList = std::make_shared<NSTopicsList>();\r
             auto topicsList = provider.getTopicList();\r
             if (topicsList != nullptr)\r
             {\r
                 for (auto it : topicsList->getTopicsList())\r
                 {\r
-                    getTopicList()->addTopic(it->getTopicName(), it->getState());\r
+                    m_topicList->addTopic(it.getTopicName(), it.getState());\r
                 }\r
             }\r
+            m_topicList->unsetModifiability();\r
             setListener(provider.getProviderStateReceivedCb(), provider.getMessageReceivedCb(),\r
                         provider.getSyncInfoReceivedCb());\r
             setProviderState(provider.getProviderState());\r
@@ -74,15 +77,16 @@ namespace OIC
         NSProvider &NSProvider::operator=(const NSProvider &provider)\r
         {\r
             this->m_providerId = provider.getProviderId();\r
-            this->m_topicList = new NSTopicsList();\r
+            this->m_topicList = std::make_shared<NSTopicsList>();\r
             auto topicsList = provider.getTopicList();\r
             if (topicsList != nullptr)\r
             {\r
                 for (auto it : topicsList->getTopicsList())\r
                 {\r
-                    this->getTopicList()->addTopic(it->getTopicName(), it->getState());\r
+                    this->m_topicList->addTopic(it.getTopicName(), it.getState());\r
                 }\r
             }\r
+            m_topicList->unsetModifiability();\r
             this->setListener(provider.getProviderStateReceivedCb(), provider.getMessageReceivedCb(),\r
                               provider.getSyncInfoReceivedCb());\r
             this->setProviderState(provider.getProviderState());\r
@@ -90,28 +94,34 @@ namespace OIC
             return *this;\r
         }\r
 \r
-        NSProvider::~NSProvider()\r
-        {\r
-            if (m_topicList != nullptr)\r
-            {\r
-                delete m_topicList;\r
-            }\r
-        }\r
-\r
         std::string NSProvider::getProviderId() const\r
         {\r
             return m_providerId;\r
         }\r
 \r
-        NSTopicsList *NSProvider::getTopicList() const\r
+        std::shared_ptr<NSTopicsList> NSProvider::getTopicList() const  throw (NSException)\r
         {\r
             NS_LOG(DEBUG, "getTopicList - IN");\r
-            return m_topicList;\r
+            if (!isValid())\r
+            {\r
+                throw NSException("Invalid Operation on provider. Provider is already Stopped.");\r
+            }\r
+            std::shared_ptr<NSTopicsList> topicList = std::make_shared<NSTopicsList>();\r
+            for (auto it : m_topicList->getTopicsList())\r
+            {\r
+                topicList->addTopic(it.getTopicName(), it.getState());\r
+            }\r
+            topicList->unsetModifiability();\r
+            return topicList;\r
         }\r
 \r
-        NSResult NSProvider::updateTopicList(NSTopicsList *topicList)\r
+        NSResult NSProvider::updateTopicList(std::shared_ptr<NSTopicsList> topicList)  throw (NSException)\r
         {\r
             NS_LOG(DEBUG, "updateTopicList - IN");\r
+            if (!isValid())\r
+            {\r
+                throw NSException("Invalid Operation on provider. Provider is already Stopped.");\r
+            }\r
             if (topicList == nullptr)\r
             {\r
                 return NSResult::ERROR;\r
@@ -127,8 +137,8 @@ namespace OIC
                     return NSResult::ERROR;\r
                 }\r
                 topic->topicName = NULL;\r
-                topic->topicName = OICStrdup(it->getTopicName().c_str());\r
-                topic->state = (::NSTopicState)it->getState();\r
+                topic->topicName = OICStrdup(it.getTopicName().c_str());\r
+                topic->state = (::NSTopicState)it.getState();\r
                 topic->next = NULL;\r
                 if (topicLL == NULL)\r
                 {\r
@@ -157,7 +167,7 @@ namespace OIC
                     iter = iter->next;\r
                 }\r
             }\r
-            NS_LOG_V(DEBUG, "calling Lower layer UpdateTopicList for Provider Id : %s",\r
+            NS_LOG_V(INFO_PRIVATE, "calling Lower layer UpdateTopicList for Provider Id : %s",\r
                      getProviderId().c_str());\r
             NSResult result = (NSResult) NSConsumerUpdateTopicList(getProviderId().c_str(), topicLL);\r
 \r
@@ -185,25 +195,54 @@ namespace OIC
         NSProviderState NSProvider::getProviderState() const\r
         {\r
             NS_LOG_V(DEBUG, "getProviderState  state : %d", (int)m_state);\r
+            if (!isValid())\r
+            {\r
+                return NSProviderState::STOPPED;\r
+            }\r
             return m_state;\r
         }\r
 \r
-        NSProviderSubscribedState NSProvider::getProviderSubscribedState() const\r
+        NSProviderSubscribedState NSProvider::getProviderSubscribedState() const  throw (NSException)\r
         {\r
             NS_LOG_V(DEBUG, "getProviderSubscribedState  state : %d", (int)m_subscribedState);\r
+            if (!isValid())\r
+            {\r
+                throw NSException("Invalid Operation on provider. Provider is already Stopped.");\r
+            }\r
             return m_subscribedState;\r
         }\r
 \r
-        void NSProvider::subscribe()\r
+        NSResult NSProvider::subscribe()  throw (NSException)\r
         {\r
             NS_LOG(DEBUG, "Subscribe - IN");\r
-            NSSubscribe(getProviderId().c_str());\r
+            if (!isValid())\r
+            {\r
+                throw NSException("Invalid Operation on provider. Provider is already Stopped.");\r
+            }\r
+            NSResult result = (NSResult) NSSubscribe(getProviderId().c_str());\r
             NS_LOG(DEBUG, "Subscribe - OUT");\r
+            return result;\r
         }\r
 \r
-        bool NSProvider::isSubscribed()\r
+        NSResult NSProvider::unsubscribe()  throw (NSException)\r
+        {\r
+            NS_LOG(DEBUG, "unsubscribe - IN");\r
+            if (!isValid())\r
+            {\r
+                throw NSException("Invalid Operation on provider. Provider is already Stopped.");\r
+            }\r
+            NSResult result = (NSResult) NSUnsubscribe(getProviderId().c_str());\r
+            NS_LOG(DEBUG, "unsubscribe - OUT");\r
+            return result;\r
+        }\r
+\r
+        bool NSProvider::isSubscribed()  throw (NSException)\r
         {\r
             NS_LOG(DEBUG, "isSubscribed - IN");\r
+            if (!isValid())\r
+            {\r
+                throw NSException("Invalid Operation on provider. Provider is already Stopped.");\r
+            }\r
             NS_LOG_V(DEBUG, "Subscribed state : %d", (int)getProviderSubscribedState());\r
             if (getProviderSubscribedState() == NSProviderSubscribedState::SUBSCRIBED)\r
             {\r
@@ -212,12 +251,17 @@ namespace OIC
             return false;\r
         }\r
 \r
-        void NSProvider::sendSyncInfo(uint64_t messageId, NSSyncInfo::NSSyncType type)\r
+        NSResult NSProvider::sendSyncInfo(uint64_t messageId, NSSyncInfo::NSSyncType type)  throw (NSException)\r
         {\r
             NS_LOG(DEBUG, "SendSyncInfo - IN");\r
-            NSConsumerSendSyncInfo(m_providerId.c_str(), messageId, (::NSSyncType)type);\r
+            if (!isValid())\r
+            {\r
+                throw NSException("Invalid Operation on provider. Provider is already Stopped.");\r
+            }\r
+            NSResult result = (NSResult) NSConsumerSendSyncInfo(getProviderId().c_str(), messageId,\r
+                              (::NSSyncType)type);\r
             NS_LOG(DEBUG, "SendSyncInfo - OUT");\r
-            return;\r
+            return result;\r
         }\r
 \r
         void NSProvider::setListener(NSProvider::ProviderStateCallback stateHandle,\r
@@ -246,12 +290,8 @@ namespace OIC
             return m_syncInfoCb;\r
         }\r
 \r
-        void NSProvider::setTopicList(NSTopicsList *topicsList)\r
+        void NSProvider::setTopicList(std::shared_ptr<NSTopicsList> topicsList)\r
         {\r
-            if (m_topicList != nullptr)\r
-            {\r
-                delete m_topicList;\r
-            }\r
             m_topicList = topicsList;\r
         }\r
 \r
@@ -264,5 +304,15 @@ namespace OIC
         {\r
             m_subscribedState = subscribedState;\r
         }\r
+\r
+        bool NSProvider::isValid() const\r
+        {\r
+            if (!NSConsumerService::getInstance()->getAcceptedProviders()->isAccepted(getProviderId()))\r
+            {\r
+                NS_LOG(DEBUG, "Invalid Operation with stale reference of Provider. Provider ID doesnot exist");\r
+                return false;\r
+            }\r
+            return true;\r
+        }\r
     }\r
 }\r
index bff7f1c..21d6d8e 100755 (executable)
@@ -45,7 +45,8 @@ notification_sample_env.PrependUnique(LIBS = [
        'oc_logger',
        'oc',
        'connectivity_abstraction',
-       'libcoap'
+       'libcoap',
+        'resource_directory'
        ])
 
 notification_sample_env.AppendUnique(CXXFLAGS = ['-std=c++0x','-frtti'])
@@ -69,10 +70,23 @@ if not env.get('RELEASE'):
 if env.get('WITH_CLOUD') == True:
        notification_sample_env.AppendUnique(CPPDEFINES = ['WITH_CLOUD'])
 
+with_mq = env.get('WITH_MQ')
+if 'SUB' in with_mq:
+    notification_sample_env.AppendUnique(CPPDEFINES = ['MQ_SUBSCRIBER', 'WITH_MQ'])
+    print "MQ SUB support"
+
+if 'PUB' in with_mq:
+    notification_sample_env.AppendUnique(CPPDEFINES = ['MQ_PUBLISHER', 'WITH_MQ'])
+    print "MQ PUB support"
+
+if 'BROKER' in with_mq:
+    notification_sample_env.AppendUnique(CPPDEFINES = ['MQ_BROKER', 'WITH_MQ'])
+    print "MQ Broker support"
+
 if env.get('WITH_TCP') == True:
        notification_sample_env.AppendUnique(CPPDEFINES = ['WITH_TCP'])
-       if env.get('SECURED') == '1':
-               notification_sample_env.AppendUnique(LIBS = ['mbedtls', 'mbedx509', 'mbedcrypto'])
+if env.get('SECURED') == '1':
+       notification_sample_env.AppendUnique(LIBS = ['mbedtls', 'mbedx509', 'mbedcrypto'])
 
 ####################################################################
 # Source files and Targets
index f7c027c..4398ab1 100755 (executable)
-/******************************************************************\r
- *\r
- * Copyright 2016 Samsung Electronics All Rights Reserved.\r
- *\r
- *\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *      http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- *\r
- ******************************************************************/\r
-\r
-#include <iostream>\r
-#include <limits>\r
-\r
-#include <unistd.h>\r
-#include "NSConsumerService.h"\r
-#include "NSMessage.h"\r
-#include "NSProvider.h"\r
-#include "NSTopicsList.h"\r
-#include "ocstack.h"\r
-\r
-#define TAG "NotiConsumerWrapperExample"\r
-using namespace std;\r
-using namespace OIC::Service;\r
-\r
-bool isExit = false;\r
-std::string REMOTE_SERVER_ADDRESS;\r
-std::string mainProvider;\r
-uint64_t mainMessageId = 0;\r
-\r
-FILE *server_fopen(const char *path, const char *mode)\r
-{\r
-    (void)path;\r
-    return fopen("oic_ns_provider_db.dat", mode);\r
-}\r
-\r
-void onNotificationPostedCb(OIC::Service::NSMessage *notification)\r
-{\r
-    std::cout << "------------------------------------" << std::endl;\r
-    std::cout << "Message Received " << std::endl;\r
-    std::cout << "------------------------------------" << std::endl;\r
-    std::cout << "id : " << notification->getMessageId() << std::endl;\r
-    std::cout << "title : " << notification->getTitle() << std::endl;\r
-    std::cout << "content : " <<  notification->getContentText() << std::endl;\r
-    std::cout << "source : " <<  notification->getSourceName() << std::endl;\r
-    std::cout << "topic : " <<  notification->getTopic() << std::endl;\r
-    std::cout << "type : " <<  (int) notification->getType() << std::endl;\r
-    std::cout << "TTL : " <<  notification->getTTL() << std::endl;\r
-    std::cout << "time : " <<  notification->getTime() << std::endl;\r
-    if (notification->getMediaContents() != nullptr)\r
-    {\r
-        std::cout << "MediaContents IconImage : " <<  notification->getMediaContents()->getIconImage()\r
-                  << std::endl;\r
-    }\r
-    std::cout << "ExtraInfo " << std::endl;\r
-    OC::OCRepresentation rep = notification->getExtraInfo();\r
-    for (auto it : rep.getResourceTypes())\r
-    {\r
-        std::cout << "resourceType : " << it << std::endl;\r
-    }\r
-    for (auto it : rep.getResourceInterfaces())\r
-    {\r
-        std::cout << "Interface : " << it << std::endl;\r
-    }\r
-    for (auto it : rep.getValues())\r
-    {\r
-        std::cout << "Key : " << it.first << std::endl;\r
-    }\r
-    mainMessageId = notification->getMessageId();\r
-}\r
-\r
-void onNotificationSyncCb(OIC::Service::NSSyncInfo *sync)\r
-{\r
-    std::cout << "------------------------------------" << std::endl;\r
-    std::cout << "SyncInfo Received " << std::endl;\r
-    std::cout << "------------------------------------" << std::endl;\r
-    std::cout << "Sync ID : " <<  sync->getMessageId() << std::endl;\r
-    std::cout << "Provider ID : " <<  sync->getProviderId() << std::endl;\r
-    std::cout << "Sync STATE : " << (int) sync->getState() << std::endl;\r
-}\r
-\r
-void onProviderStateChangedCb(OIC::Service::NSProviderState state)\r
-{\r
-    std::cout << "onProviderStateChangedCb" << std::endl;\r
-    if (state == OIC::Service::NSProviderState::ALLOW)\r
-    {\r
-        std::cout << "Provider Subscription Accepted" << std::endl;\r
-    }\r
-    else if (state == OIC::Service::NSProviderState::DENY)\r
-    {\r
-        std::cout << "Provider Subscription Denied" << std::endl;\r
-        std::cout << "------------------------------------" << std::endl;\r
-    }\r
-    else if (state == OIC::Service::NSProviderState::TOPIC)\r
-    {\r
-        OIC::Service::NSProvider *provider = NSConsumerService::getInstance()->getProvider(mainProvider);\r
-        if (provider != nullptr)\r
-        {\r
-            auto topicList = provider->getTopicList();\r
-            if (topicList != nullptr)\r
-            {\r
-                for (auto it : topicList->getTopicsList())\r
-                {\r
-                    std::cout << "Topic Name: " << it->getTopicName() << std::endl;\r
-                    std::cout << "Topic state: " << (int) it->getState() << std::endl;\r
-                }\r
-            }\r
-        }\r
-    }\r
-    else if (state == OIC::Service::NSProviderState::STOPPED)\r
-    {\r
-        std::cout << "Provider Stopped" << std::endl;\r
-        std::cout << "------------------------------------" << std::endl;\r
-    }\r
-}\r
-\r
-void onDiscoverNotificationCb(OIC::Service::NSProvider *provider)\r
-{\r
-    std::cout << "Notification Resource Discovered" << std::endl;\r
-    std::cout << "SetListeners for callbacks" << std::endl;\r
-    std::cout << "ProviderID : " << provider->getProviderId() << std::endl;\r
-    provider->setListener(onProviderStateChangedCb, onNotificationPostedCb, onNotificationSyncCb);\r
-    if (!provider->isSubscribed())\r
-    {\r
-        std::cout << "startSubscribing" << std::endl;\r
-        provider->subscribe();\r
-    }\r
-    if (mainProvider.empty())\r
-    {\r
-        mainProvider = provider->getProviderId();\r
-    }\r
-}\r
-\r
-void *OCProcessThread(void *ptr)\r
-{\r
-    (void) ptr;\r
-\r
-    while (!isExit)\r
-    {\r
-        usleep(2000);\r
-        if (OCProcess() != OC_STACK_OK)\r
-        {\r
-            OCStop();\r
-            break;\r
-        }\r
-    }\r
-\r
-    return NULL;\r
-}\r
-\r
-int main(void)\r
-{\r
-    pthread_t OCThread = 0;\r
-\r
-    std::cout << "start Iotivity" << std::endl;\r
-\r
-    // open oic_db\r
-    static OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink};\r
-    OCRegisterPersistentStorageHandler(&ps);\r
-\r
-    if (OCInit1(OC_CLIENT_SERVER, OC_DEFAULT_FLAGS, OC_DEFAULT_FLAGS) != OC_STACK_OK)\r
-    {\r
-        std::cout << "OCInit fail" << std::endl;\r
-        return 0;\r
-    }\r
-\r
-    pthread_create(&OCThread, NULL, OCProcessThread, NULL);\r
-\r
-    std::cout << "Start notification consumer service" << std::endl;\r
-    while (!isExit)\r
-    {\r
-        int num = 0;\r
-\r
-        std::cout << "1. Start Consumer" << std::endl;\r
-        std::cout << "2. Stop Consumer" << std::endl;\r
-        std::cout << "3. SendSyncInfo" << std::endl;\r
-        std::cout << "4. GetTopicList" << std::endl;\r
-        std::cout << "5. UpdateTopicList" << std::endl;\r
-#ifdef WITH_CLOUD\r
-        std::cout << "6. Enable  NS Consumer RemoteService" << std::endl;\r
-#endif\r
-        std::cout << "7. Exit" << std::endl;\r
-\r
-        std::cout << "Input: " << std::endl;\r
-        std::cin >> num;\r
-        switch (num)\r
-        {\r
-            case 1:\r
-                {\r
-                    std::cout << "Start the Notification Consumer" << std::endl;\r
-                    NSConsumerService::getInstance()->start(onDiscoverNotificationCb);\r
-                    break;\r
-                }\r
-            case 2:\r
-                {\r
-                    std::cout << "Stop the Notification Consumer" << std::endl;\r
-                    NSConsumerService::getInstance()->stop();\r
-                    break;\r
-                }\r
-            case 3:\r
-                {\r
-                    std::cout <<  "SendSyncInfo" << std::endl;\r
-                    if (!mainMessageId)\r
-                    {\r
-                        std::cout <<  "Message ID is empty" << std::endl;\r
-                        break;\r
-                    }\r
-                    std::cout << "1. Send Read Sync" << std::endl;\r
-                    std::cout << "2. Send Delete Sync" << std::endl;\r
-                    int syn = 0;\r
-                    while (!(std::cin >> syn))\r
-                    {\r
-                        std::cout << "Bad value!" << std::endl;;\r
-                        std::cin.clear();\r
-                        std::cin.ignore(numeric_limits<streamsize>::max(), '\n');\r
-                    }\r
-                    switch (syn)\r
-                    {\r
-                        case 1:\r
-                            {\r
-                                std::cout << "Sending Read Sync" << std::endl;\r
-                                auto provider = NSConsumerService::getInstance()->getProvider(\r
-                                                    mainProvider);\r
-                                if (provider != nullptr)\r
-                                {\r
-                                    provider->sendSyncInfo(mainMessageId,\r
-                                                           OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_READ);\r
-                                }\r
-                            }\r
-                            break;\r
-                        case 2:\r
-                            {\r
-                                std::cout << "Sending Delete Sync" << std::endl;\r
-                                auto provider = NSConsumerService::getInstance()->getProvider(\r
-                                                    mainProvider);\r
-                                if (provider != nullptr)\r
-                                {\r
-                                    provider->sendSyncInfo(mainMessageId,\r
-                                                           OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_DELETED);\r
-                                }\r
-                            }\r
-                            break;\r
-                        default:\r
-                            {\r
-                                cout << "Invalid Input!. sending default Read Sync";\r
-                                auto provider = NSConsumerService::getInstance()->getProvider(\r
-                                                    mainProvider);\r
-                                if (provider != nullptr)\r
-                                {\r
-                                    provider->sendSyncInfo(mainMessageId,\r
-                                                           OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_READ);\r
-                                }\r
-                                std::cin.clear();\r
-                                std::cin.ignore(numeric_limits<streamsize>::max(), '\n');\r
-                                break;\r
-                            }\r
-                    }\r
-                    break;\r
-                }\r
-            case 4:\r
-                {\r
-                    std::cout <<  "GetTopicList" << std::endl;\r
-                    OIC::Service::NSProvider *provider = NSConsumerService::getInstance()->getProvider(mainProvider);\r
-                    if (provider != nullptr)\r
-                    {\r
-                        auto topicList = provider->getTopicList();\r
-                        if (topicList != nullptr)\r
-                        {\r
-                            for (auto it : topicList->getTopicsList())\r
-                            {\r
-                                std::cout << "Topic Name: " << it->getTopicName() << std::endl;\r
-                                std::cout << "Topic state: " << (int) it->getState() << std::endl;\r
-                            }\r
-                        }\r
-                    }\r
-                }\r
-                break;\r
-            case 5:\r
-                {\r
-                    std::cout <<  "UpdateTopicList" << std::endl;\r
-                    OIC::Service::NSProvider *provider = NSConsumerService::getInstance()->getProvider(mainProvider);\r
-                    if (provider != nullptr)\r
-                    {\r
-                        NSTopicsList *topicList = new NSTopicsList();\r
-                        topicList->addTopic("OCF_TOPIC1", NSTopic::NSTopicState::SUBSCRIBED);\r
-                        topicList->addTopic("OCF_TOPIC2", NSTopic::NSTopicState::SUBSCRIBED);\r
-                        topicList->addTopic("OCF_TOPIC3", NSTopic::NSTopicState::UNSUBSCRIBED);\r
-\r
-                        provider->updateTopicList(topicList);\r
-                        delete topicList;\r
-                        delete provider;\r
-                    }\r
-                }\r
-                break;\r
-#ifdef WITH_CLOUD\r
-            case 6:\r
-                {\r
-                    std::cout << "Enable NS Consumer RemoteService" << std::endl;\r
-                    std::cout << "Input the Server Address :";\r
-                    std::cin >> REMOTE_SERVER_ADDRESS;\r
-                    NSConsumerService::getInstance()->enableRemoteService(REMOTE_SERVER_ADDRESS);\r
-                    break;\r
-                }\r
-#endif\r
-            case 7:\r
-                {\r
-                    std::cout << "Exit" << std::endl;\r
-                    NSConsumerService::getInstance()->stop();\r
-                    isExit = true;\r
-                    break;\r
-                }\r
-            default:\r
-                {\r
-                    std::cout << "Under Construction" << std::endl;\r
-                    std::cin.clear();\r
-                    std::cin.ignore(numeric_limits<streamsize>::max(), '\n');\r
-                    break;\r
-                }\r
-        }\r
-    }\r
-\r
-    return 0;\r
-}\r
+/******************************************************************
+ *
+ * Copyright 2016 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 <iostream>
+#include <limits>
+
+#include <unistd.h>
+#include "NSConsumerService.h"
+#include "NSMessage.h"
+#include "NSProvider.h"
+#include "NSTopicsList.h"
+#include "ocstack.h"
+
+#define TAG "NotiConsumerWrapperExample"
+using namespace std;
+using namespace OIC::Service;
+
+bool isExit = false;
+std::string REMOTE_SERVER_ADDRESS;
+std::string mainProvider;
+uint64_t mainMessageId = 0;
+
+#ifndef OC_SECURITY_DB_DAT_FILE_NAME
+#define OC_SECURITY_DB_DAT_FILE_NAME "oic_svr_db.dat"
+#endif
+
+FILE *server_fopen(const char *path, const char *mode)
+{
+    if (0 == strcmp(path, OC_SECURITY_DB_DAT_FILE_NAME))
+    {
+        return fopen("oic_ns_provider_db.dat", mode);
+    }
+    else
+    {
+        return fopen(path, mode);
+    }
+}
+
+void onNotificationPostedCb(OIC::Service::NSMessage notification)
+{
+    std::cout << "------------------------------------" << std::endl;
+    std::cout << "Message Received " << std::endl;
+    std::cout << "------------------------------------" << std::endl;
+    std::cout << "id : " << notification.getMessageId() << std::endl;
+    std::cout << "title : " << notification.getTitle() << std::endl;
+    std::cout << "content : " <<  notification.getContentText() << std::endl;
+    std::cout << "source : " <<  notification.getSourceName() << std::endl;
+    std::cout << "topic : " <<  notification.getTopic() << std::endl;
+    std::cout << "type : " <<  (int) notification.getType() << std::endl;
+    std::cout << "TTL : " <<  notification.getTTL() << std::endl;
+    std::cout << "time : " <<  notification.getTime() << std::endl;
+    if (notification.getMediaContents() != nullptr)
+    {
+        std::cout << "MediaContents IconImage : " <<  notification.getMediaContents()->getIconImage()
+                  << std::endl;
+    }
+    std::cout << "ExtraInfo " << std::endl;
+    OC::OCRepresentation rep = notification.getExtraInfo();
+    for (auto it : rep.getResourceTypes())
+    {
+        std::cout << "resourceType : " << it << std::endl;
+    }
+    for (auto it : rep.getResourceInterfaces())
+    {
+        std::cout << "Interface : " << it << std::endl;
+    }
+    for (auto it : rep.getValues())
+    {
+        std::cout << "Key : " << it.first << std::endl;
+    }
+    mainMessageId = notification.getMessageId();
+}
+
+void onNotificationSyncCb(OIC::Service::NSSyncInfo sync)
+{
+    std::cout << "------------------------------------" << std::endl;
+    std::cout << "SyncInfo Received " << std::endl;
+    std::cout << "------------------------------------" << std::endl;
+    std::cout << "Sync ID : " <<  sync.getMessageId() << std::endl;
+    std::cout << "Provider ID : " <<  sync.getProviderId() << std::endl;
+    std::cout << "Sync STATE : " << (int) sync.getState() << std::endl;
+}
+
+void onProviderStateChangedCb(OIC::Service::NSProviderState state)
+{
+    std::cout << "onProviderStateChangedCb" << std::endl;
+    if (state == OIC::Service::NSProviderState::ALLOW)
+    {
+        std::cout << "Provider Subscription Accepted" << std::endl;
+    }
+    else if (state == OIC::Service::NSProviderState::DENY)
+    {
+        std::cout << "Provider Subscription Denied" << std::endl;
+        std::cout << "------------------------------------" << std::endl;
+    }
+    else if (state == OIC::Service::NSProviderState::TOPIC)
+    {
+        std::shared_ptr<OIC::Service::NSProvider> provider =
+            NSConsumerService::getInstance()->getProvider(mainProvider);
+        if (provider != nullptr)
+        {
+            auto topicList = provider->getTopicList();
+            if (topicList != nullptr)
+            {
+                for (auto it : topicList->getTopicsList())
+                {
+                    std::cout << "Topic Name: " << it.getTopicName() << std::endl;
+                    std::cout << "Topic state: " << (int) it.getState() << std::endl;
+                }
+            }
+        }
+    }
+    else if (state == OIC::Service::NSProviderState::STOPPED)
+    {
+        std::cout << "Provider Stopped" << std::endl;
+        std::cout << "------------------------------------" << std::endl;
+    }
+}
+
+void onDiscoverNotificationCb(std::shared_ptr<OIC::Service::NSProvider> provider)
+{
+    std::cout << "Notification Resource Discovered" << std::endl;
+    std::cout << "SetListeners for callbacks" << std::endl;
+    std::cout << "ProviderID : " << provider->getProviderId() << std::endl;
+    provider->setListener(onProviderStateChangedCb, onNotificationPostedCb, onNotificationSyncCb);
+    if (!provider->isSubscribed())
+    {
+        std::cout << "startSubscribing" << std::endl;
+        provider->subscribe();
+    }
+    if (mainProvider.empty())
+    {
+        mainProvider = provider->getProviderId();
+    }
+}
+
+void *OCProcessThread(void *ptr)
+{
+    (void) ptr;
+
+    while (!isExit)
+    {
+        usleep(2000);
+        if (OCProcess() != OC_STACK_OK)
+        {
+            OCStop();
+            break;
+        }
+    }
+
+    return NULL;
+}
+
+int main(void)
+{
+    pthread_t OCThread = 0;
+
+    std::cout << "start Iotivity" << std::endl;
+
+    // open oic_db
+    static OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink};
+    OCRegisterPersistentStorageHandler(&ps);
+
+    if (OCInit1(OC_CLIENT_SERVER, OC_DEFAULT_FLAGS, OC_DEFAULT_FLAGS) != OC_STACK_OK)
+    {
+        std::cout << "OCInit fail" << std::endl;
+        return 0;
+    }
+
+    pthread_create(&OCThread, NULL, OCProcessThread, NULL);
+
+    std::cout << "Start notification consumer service" << std::endl;
+    while (!isExit)
+    {
+        int num = 0;
+
+        std::cout << "1. Start Consumer" << std::endl;
+        std::cout << "2. Stop Consumer" << std::endl;
+        std::cout << "3. SendSyncInfo" << std::endl;
+        std::cout << "4. GetTopicList" << std::endl;
+        std::cout << "5. UpdateTopicList" << std::endl;
+        std::cout << "6. Subscribe provider" << std::endl;
+        std::cout << "7. UnSubscribe provider" << std::endl;
+        std::cout << "8. Rescan provider" << std::endl;
+#ifdef WITH_CLOUD
+        std::cout << "9. Enable  NS Consumer RemoteService" << std::endl;
+#endif
+        std::cout << "10. Exit" << std::endl;
+
+        std::cout << "Input: " << std::endl;
+        std::cin >> num;
+        switch (num)
+        {
+            case 1:
+                {
+                    std::cout << "Start the Notification Consumer" << std::endl;
+                    NSConsumerService::getInstance()->start(onDiscoverNotificationCb);
+                    break;
+                }
+            case 2:
+                {
+                    std::cout << "Stop the Notification Consumer" << std::endl;
+                    NSConsumerService::getInstance()->stop();
+                    break;
+                }
+            case 3:
+                {
+                    std::cout <<  "SendSyncInfo" << std::endl;
+                    if (!mainMessageId)
+                    {
+                        std::cout <<  "Message ID is empty" << std::endl;
+                        break;
+                    }
+                    std::cout << "1. Send Read Sync" << std::endl;
+                    std::cout << "2. Send Delete Sync" << std::endl;
+                    int syn = 0;
+                    while (!(std::cin >> syn))
+                    {
+                        std::cout << "Bad value!" << std::endl;;
+                        std::cin.clear();
+                        std::cin.ignore(numeric_limits<streamsize>::max(), '\n');
+                    }
+                    switch (syn)
+                    {
+                        case 1:
+                            {
+                                std::cout << "Sending Read Sync" << std::endl;
+                                auto provider = NSConsumerService::getInstance()->getProvider(
+                                                    mainProvider);
+                                if (provider != nullptr)
+                                {
+                                    provider->sendSyncInfo(mainMessageId,
+                                                           OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_READ);
+                                }
+                            }
+                            break;
+                        case 2:
+                            {
+                                std::cout << "Sending Delete Sync" << std::endl;
+                                auto provider = NSConsumerService::getInstance()->getProvider(
+                                                    mainProvider);
+                                if (provider != nullptr)
+                                {
+                                    provider->sendSyncInfo(mainMessageId,
+                                                           OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_DELETED);
+                                }
+                            }
+                            break;
+                        default:
+                            {
+                                cout << "Invalid Input!. sending default Read Sync";
+                                auto provider = NSConsumerService::getInstance()->getProvider(
+                                                    mainProvider);
+                                if (provider != nullptr)
+                                {
+                                    provider->sendSyncInfo(mainMessageId,
+                                                           OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_READ);
+                                }
+                                std::cin.clear();
+                                std::cin.ignore(numeric_limits<streamsize>::max(), '\n');
+                                break;
+                            }
+                    }
+                    break;
+                }
+            case 4:
+                {
+                    std::cout <<  "GetTopicList" << std::endl;
+                    std::shared_ptr<OIC::Service::NSProvider> provider =
+                        NSConsumerService::getInstance()->getProvider(mainProvider);
+                    if (provider != nullptr)
+                    {
+                        auto topicList = provider->getTopicList();
+                        if (topicList != nullptr)
+                        {
+                            for (auto it : topicList->getTopicsList())
+                            {
+                                std::cout << "Topic Name: " << it.getTopicName() << std::endl;
+                                std::cout << "Topic state: " << (int) it.getState() << std::endl;
+                            }
+                        }
+                    }
+                    break;
+                }
+            case 5:
+                {
+                    std::cout <<  "UpdateTopicList" << std::endl;
+                    std::shared_ptr<OIC::Service::NSProvider> provider =
+                        NSConsumerService::getInstance()->getProvider(mainProvider);
+                    if (provider != nullptr)
+                    {
+                        std::shared_ptr<NSTopicsList> topicList = std::make_shared<NSTopicsList>();
+                        topicList->addTopic("OCF_TOPIC1", NSTopic::NSTopicState::SUBSCRIBED);
+                        topicList->addTopic("OCF_TOPIC2", NSTopic::NSTopicState::SUBSCRIBED);
+                        topicList->addTopic("OCF_TOPIC3", NSTopic::NSTopicState::UNSUBSCRIBED);
+
+                        provider->updateTopicList(topicList);
+                    }
+                    break;
+                }
+            case 6:
+                {
+                    std::cout << "Subscribe provider" << std::endl;
+                    if (!mainProvider.empty())
+                    {
+                        std::shared_ptr<OIC::Service::NSProvider> provider =
+                            NSConsumerService::getInstance()->getProvider(mainProvider);
+                        if (provider != nullptr )
+                        {
+                            std::cout << "calling Subscribe on discovered mainProvider" << std::endl;
+                            if (!provider->isSubscribed())
+                            {
+                                std::cout << "start Subscribing" << std::endl;
+                                provider->subscribe();
+                            }
+                        }
+                    }
+                    break;
+                }
+            case 7:
+                {
+                    std::cout << "UnSubscribe provider" << std::endl;
+                    if (!mainProvider.empty())
+                    {
+                        std::shared_ptr<OIC::Service::NSProvider> provider =
+                            NSConsumerService::getInstance()->getProvider(mainProvider);
+                        if (provider != nullptr )
+                        {
+                            std::cout << "calling UnSubscribe on discovered mainProvider" << std::endl;
+                            if (provider->isSubscribed())
+                            {
+                                std::cout << "start UnSubscribing" << std::endl;
+                                provider->unsubscribe();
+                            }
+                        }
+                    }
+                    break;
+                }
+            case 8:
+                {
+                    std::cout << "Rescan Provider" << std::endl;
+                    NSConsumerService::getInstance()->rescanProvider();
+                    break;
+                }
+
+#ifdef WITH_CLOUD
+            case 9:
+                {
+                    std::cout << "Enable NS Consumer RemoteService" << std::endl;
+                    std::cout << "Input the Server Address :";
+                    std::cin >> REMOTE_SERVER_ADDRESS;
+                    NSConsumerService::getInstance()->enableRemoteService(REMOTE_SERVER_ADDRESS);
+                    break;
+                }
+#endif
+            case 10:
+                {
+                    std::cout << "Exit" << std::endl;
+                    NSConsumerService::getInstance()->stop();
+                    isExit = true;
+                    break;
+                }
+            default:
+                {
+                    std::cout << "Under Construction" << std::endl;
+                    std::cin.clear();
+                    std::cin.ignore(numeric_limits<streamsize>::max(), '\n');
+                    break;
+                }
+        }
+    }
+
+    return 0;
+}
index 57f635e..87d33d6 100755 (executable)
-/******************************************************************\r
- *\r
- * Copyright 2016 Samsung Electronics All Rights Reserved.\r
- *\r
- *\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *      http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- *\r
- ******************************************************************/\r
-\r
-// std\r
-#include <iostream>\r
-#include <stdlib.h>\r
-#include <cstdint>\r
-#include <limits>\r
-\r
-// ns\r
-#include "NSCommon.h"\r
-#include "NSProviderService.h"\r
-#include "NSUtils.h"\r
-#include "NSTopicsList.h"\r
-\r
-// base\r
-#include "logger.h"\r
-#include "octypes.h"\r
-#include "oic_string.h"\r
-#include "oic_malloc.h"\r
-#include "ocstack.h"\r
-\r
-// external\r
-#include "pthread.h"\r
-\r
-#define TAG "NotiProviderWrapperExample"\r
-using namespace std;\r
-using namespace OIC::Service;\r
-std::vector<std::string> discoveredConsumers;\r
-uint64_t mainMessageId = 0;\r
-\r
-extern char *strdup(const char *s);\r
-\r
-bool isExit = false;\r
-\r
-int id = 0;\r
-std::string REMOTE_SERVER_ADDRESS;\r
-\r
-void *OCProcessThread(void *ptr)\r
-{\r
-    (void) ptr;\r
-    while (!isExit)\r
-    {\r
-        usleep(2000);\r
-        if (OCProcess() != OC_STACK_OK)\r
-        {\r
-            std::cout << "OCStack process error" << std::endl;\r
-            return NULL;\r
-        }\r
-    }\r
-\r
-    return NULL;\r
-}\r
-\r
-void subscribeRequestCallback(OIC::Service::NSConsumer *consumer)\r
-{\r
-    std::cout << "consumer requested to subscribe" << std::endl;\r
-\r
-    std::cout << "Consumer Device ID: " << consumer->getConsumerId() << std::endl;\r
-    discoveredConsumers.push_back(consumer->getConsumerId());\r
-    consumer->acceptSubscription(true);\r
-}\r
-\r
-void syncCallback(OIC::Service::NSSyncInfo *sync)\r
-{\r
-    std::cout << "SyncInfo Received " << std::endl;\r
-    std::cout << "Sync ID : " <<  sync->getMessageId() << std::endl;\r
-    std::cout << "Provider ID : " <<  sync->getProviderId() << std::endl;\r
-    std::cout << "Sync State: " << (int) sync->getState() << std::endl;\r
-}\r
-\r
-OIC::Service::NSConsumer *printAvailableConsumers()\r
-{\r
-    std::cout << "Choose the Consumer ID for operation" << std::endl;\r
-    int pos = 1;\r
-    unsigned int option = 0;\r
-    for (auto it : discoveredConsumers)\r
-    {\r
-        std::cout << pos << ". " << it << std::endl;\r
-        pos++;\r
-    }\r
-    while (!(std::cin >> option))\r
-    {\r
-        std::cout << "Bad value!" << std::endl;;\r
-        std::cin.clear();\r
-        std::cin.ignore(numeric_limits<streamsize>::max(), '\n');\r
-    }\r
-    option--;\r
-    if (option > discoveredConsumers.size())\r
-    {\r
-        return NULL;\r
-    }\r
-    std::string consumerId = discoveredConsumers[option];\r
-    OIC::Service::NSConsumer *consumer = NSProviderService::getInstance()->getConsumer(\r
-            consumerId);\r
-    return consumer;\r
-}\r
-\r
-int main()\r
-{\r
-    int num = 0;\r
-    pthread_t processThread = 0;\r
-\r
-    std::cout << "start Iotivity" << std::endl;\r
-\r
-\r
-    if (OCInit(NULL, 0, OC_CLIENT_SERVER) != OC_STACK_OK)\r
-    {\r
-        std::cout << "OCStack init error" << std::endl;\r
-        return 0;\r
-    }\r
-\r
-    pthread_create(&processThread, NULL, OCProcessThread, NULL);\r
-\r
-    while (!isExit)\r
-    {\r
-        std::cout << "1. Start the Notification Provider(Accepter: Provider)" << std::endl;\r
-        std::cout << "2. Start the Notification Provider(Accepter: Consumer)" << std::endl;\r
-        std::cout << "3. Allow Subscription" << std::endl;\r
-        std::cout << "4. Deny Subscription" << std::endl;\r
-        std::cout << "5. SendMessage " << std::endl;\r
-        std::cout << "6. SendSyncInfo" << std::endl;\r
-\r
-        std::cout << "7. RegisterTopic" << std::endl;\r
-        std::cout << "8. UnregisterTopic" << std::endl;\r
-        std::cout << "9. SetTopic" << std::endl;\r
-        std::cout << "10. UnsetTopic" << std::endl;\r
-        std::cout << "11. GetConsumerTopicList" << std::endl;\r
-        std::cout << "12. GetRegisteredTopicList" << std::endl;\r
-#ifdef WITH_CLOUD\r
-        std::cout << "13. Enable NS Provider RemoteService" << std::endl;\r
-        std::cout << "14. Disable NS Provider RemoteService" << std::endl;\r
-#endif\r
-        std::cout << "15. Stop the Notification Provider" << std::endl;\r
-        std::cout << "16. Exit()" << std::endl;\r
-\r
-        std::cout << "input : ";\r
-\r
-        std::cin >> num;\r
-\r
-        switch (num)\r
-        {\r
-            case 1:\r
-                {\r
-                    std::cout << "Start (Accepter: Provider)" << std::endl;\r
-                    NSProviderService::ProviderConfig cfg;\r
-                    cfg.m_subscribeRequestCb = subscribeRequestCallback;\r
-                    cfg.m_syncInfoCb = syncCallback;\r
-                    cfg.subControllability = true;\r
-\r
-                    NSProviderService::getInstance()->start(cfg);\r
-                    break;\r
-                }\r
-            case 2:\r
-                {\r
-                    std::cout << "Start (Accepter: Consumer)" << std::endl;\r
-                    NSProviderService::ProviderConfig cfg;\r
-                    cfg.m_subscribeRequestCb = subscribeRequestCallback;\r
-                    cfg.m_syncInfoCb = syncCallback;\r
-                    cfg.subControllability = false;\r
-\r
-                    NSProviderService::getInstance()->start(cfg);\r
-                    break;\r
-                }\r
-            case 3:\r
-                {\r
-                    std::cout << "Allow Subscription" << std::endl;\r
-                    OIC::Service::NSConsumer *consumer = printAvailableConsumers();\r
-                    if (consumer != nullptr)\r
-                    {\r
-                        std::cout << "ALLOW" << std::endl;\r
-                        consumer->acceptSubscription(true);\r
-                    }\r
-                    break;\r
-                }\r
-            case 4:\r
-                {\r
-                    std::cout << "Deny Subscription" << std::endl;\r
-                    OIC::Service::NSConsumer *consumer = printAvailableConsumers();\r
-                    if (consumer != nullptr)\r
-                    {\r
-                        std::cout << "DENY" << std::endl;\r
-                        consumer->acceptSubscription(false);\r
-                    }\r
-                    break;\r
-                }\r
-            case 5:\r
-                {\r
-                    std::cout << "------------------------------------" << std::endl;\r
-                    std::cout << "SendMessage" << std::endl;\r
-                    std::cout << "------------------------------------" << std::endl;\r
-\r
-                    std::string dummy;\r
-                    std::string title;\r
-                    std::string body;\r
-                    std::string topic;\r
-\r
-                    std::cout << "id : " << ++id << std::endl;\r
-                    std::cout << "title : ";\r
-\r
-                    std::getline(std::cin, dummy);\r
-                    std::getline(std::cin, title);\r
-\r
-                    std::cout << "body : ";\r
-                    std::getline(std::cin, body);\r
-\r
-                    std::cout << "topic : ";\r
-                    std::getline(std::cin, topic);\r
-\r
-                    std::cout << "app - mTitle : " << title << std::endl;\r
-                    std::cout << "app - mContentText : " << body << std::endl;\r
-                    std::cout << "app - mTopic : " << topic << std::endl;\r
-\r
-                    OIC::Service::NSMessage *msg = NSProviderService::getInstance()->createMessage();\r
-\r
-                    msg->setType(OIC::Service::NSMessage::NSMessageType::NS_MESSAGE_INFO);\r
-                    msg->setTitle(title.c_str());\r
-                    msg->setContentText(body.c_str());\r
-                    msg->setSourceName("OCF");\r
-                    msg->setTopic(topic);\r
-                    msg->setTTL(40);\r
-                    msg->setTime("12:30");\r
-                    OIC::Service::NSMediaContents *mediaContents =\r
-                        new OIC::Service::NSMediaContents("iconImage");\r
-                    msg->setMediaContents(mediaContents);\r
-\r
-                    OC::OCRepresentation rep;\r
-                    rep.setValue("Key1", "Value1");\r
-                    rep.setValue("Key2", "Value2");\r
-                    msg->setExtraInfo(rep);\r
-\r
-                    mainMessageId = msg->getMessageId();\r
-                    std::cout << "ProviderID for Message : " << msg->getProviderId() << std::endl;\r
-                    std::cout << "MessageID for Message : " << msg->getMessageId() << std::endl;\r
-\r
-                    NSProviderService::getInstance()->sendMessage(msg);\r
-                    delete msg;\r
-                    break;\r
-                }\r
-            case 6:\r
-                {\r
-                    std::cout << "------------------------------------" << std::endl;\r
-                    std::cout <<  "SendSyncInfo" << std::endl;\r
-                    std::cout << "------------------------------------" << std::endl;\r
-                    if (!mainMessageId)\r
-                    {\r
-                        std::cout <<  "Message ID is empty" << std::endl;\r
-                        break;\r
-                    }\r
-                    std::cout << "1. Send Read Sync" << std::endl;\r
-                    std::cout << "2. Send Delete Sync" << std::endl;\r
-                    int syn = 0;\r
-                    while (!(std::cin >> syn))\r
-                    {\r
-                        std::cout << "Bad value!" << std::endl;;\r
-                        std::cin.clear();\r
-                        std::cin.ignore(numeric_limits<streamsize>::max(), '\n');\r
-                    }\r
-                    switch (syn)\r
-                    {\r
-                        case 1:\r
-                            {\r
-                                std::cout << "Sending Read Sync" << std::endl;\r
-                                NSProviderService::getInstance()->sendSyncInfo(mainMessageId,\r
-                                        OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_READ);\r
-                            }\r
-                            break;\r
-                        case 2:\r
-                            {\r
-                                std::cout << "Sending Delete Sync" << std::endl;\r
-                                NSProviderService::getInstance()->sendSyncInfo(mainMessageId,\r
-                                        OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_DELETED);\r
-                            }\r
-                            break;\r
-                        default:\r
-                            {\r
-                                cout << "Invalid Input!. sending default Read Sync";\r
-                                NSProviderService::getInstance()->sendSyncInfo(mainMessageId,\r
-                                        OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_READ);\r
-                                std::cin.clear();\r
-                                std::cin.ignore(numeric_limits<streamsize>::max(), '\n');\r
-                                break;\r
-                            }\r
-                    }\r
-                    break;\r
-                }\r
-\r
-            case 7:\r
-                {\r
-                    std::cout <<  "RegisterTopic" << std::endl;\r
-                    NSProviderService::getInstance()->registerTopic("OCF_TOPIC1");\r
-                    NSProviderService::getInstance()->registerTopic("OCF_TOPIC2");\r
-                    NSProviderService::getInstance()->registerTopic("OCF_TOPIC3");\r
-                    NSProviderService::getInstance()->registerTopic("OCF_TOPIC4");\r
-                    break;\r
-                }\r
-            case 8:\r
-                {\r
-                    std::cout <<  "UnregisterTopic" << std::endl;\r
-                    NSProviderService::getInstance()->unregisterTopic("OCF_TOPIC2");\r
-                    break;\r
-                }\r
-            case 9:\r
-                {\r
-                    std::cout <<  "SetTopic" << std::endl;\r
-                    OIC::Service::NSConsumer *consumer = printAvailableConsumers();\r
-                    if (consumer != nullptr)\r
-                    {\r
-                        consumer->setTopic("OCF_TOPIC1");\r
-                        consumer->setTopic("OCF_TOPIC2");\r
-                        consumer->setTopic("OCF_TOPIC3");\r
-                        std::cout <<  "SelectTopic completed" << std::endl;\r
-                    }\r
-                    break;\r
-                }\r
-            case 10:\r
-                {\r
-                    std::cout <<  "UnsetTopic" << std::endl;\r
-                    OIC::Service::NSConsumer *consumer = printAvailableConsumers();\r
-                    if (consumer != nullptr)\r
-                    {\r
-                        consumer->unsetTopic("OCF_TOPIC1");\r
-                        std::cout <<  "UnSelectTopic completed" << std::endl;\r
-                    }\r
-                    break;\r
-                }\r
-                break;\r
-\r
-            case 11:\r
-                {\r
-                    std::cout <<  "GetConsumerTopicList" << std::endl;\r
-                    OIC::Service::NSConsumer *consumer = printAvailableConsumers();\r
-                    if (consumer != nullptr)\r
-                    {\r
-                        auto nsTopics = consumer->getConsumerTopicList();\r
-                        if (nsTopics != nullptr)\r
-                        {\r
-                            for (auto it : nsTopics->getTopicsList())\r
-                            {\r
-\r
-                                std::cout << it->getTopicName() << std::endl;\r
-                                std::cout << (int) it->getState() << std::endl;\r
-                            }\r
-                            delete nsTopics;\r
-                        }\r
-                        std::cout <<  "GetConsumerTopicList completed" << std::endl;\r
-                    }\r
-                }\r
-                break;\r
-\r
-            case 12:\r
-                {\r
-                    std::cout <<  "GetRegisteredTopicList" << std::endl;\r
-                    auto nsTopics = NSProviderService::getInstance()->getRegisteredTopicList();\r
-                    for (auto it : nsTopics->getTopicsList())\r
-                    {\r
-\r
-                        std::cout << it->getTopicName() << std::endl;\r
-                        std::cout << (int) it->getState() << std::endl;\r
-                    }\r
-                    delete nsTopics;\r
-                }\r
-                break;\r
-#ifdef WITH_CLOUD\r
-            case 13:\r
-                {\r
-                    std::cout << "Enable NS Provider RemoteService" << std::endl;\r
-                    std::cout << "Input the Server Address :";\r
-                    std::cin >> REMOTE_SERVER_ADDRESS;\r
-                    NSProviderService::getInstance()->enableRemoteService(REMOTE_SERVER_ADDRESS);\r
-                    break;\r
-                }\r
-            case 14:\r
-                {\r
-                    std::cout << "Disable NS Provider RemoteService" << std::endl;\r
-                    std::cout << "Input the Server Address :";\r
-                    NSProviderService::getInstance()->disableRemoteService(REMOTE_SERVER_ADDRESS);\r
-                    break;\r
-                }\r
-#endif\r
-            case 15:\r
-                {\r
-                    std::cout << "Stop the Notification Provider" << std::endl;\r
-                    NSProviderService::getInstance()->stop();\r
-                    break;\r
-                }\r
-            case 16:\r
-                {\r
-                    std::cout << "Exit()" << std::endl;\r
-                    NSProviderService::getInstance()->stop();\r
-                    isExit = true;\r
-                    break;\r
-                }\r
-            default:\r
-                {\r
-                    std::cout << "Under Construction" << std::endl;\r
-                    std::cin.clear();\r
-                    std::cin.ignore(numeric_limits<streamsize>::max(), '\n');\r
-                    break;\r
-                }\r
-        }\r
-\r
-        std::cout << std::endl;\r
-    }\r
-\r
-    return 0;\r
-}\r
+/******************************************************************
+ *
+ * Copyright 2016 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.
+ *
+ ******************************************************************/
+
+// std
+#include <iostream>
+#include <stdlib.h>
+#include <cstdint>
+#include <limits>
+
+// ns
+#include "NSCommon.h"
+#include "NSProviderService.h"
+#include "NSUtils.h"
+#include "NSTopicsList.h"
+
+// base
+#include "logger.h"
+#include "octypes.h"
+#include "oic_string.h"
+#include "oic_malloc.h"
+#include "ocstack.h"
+
+// external
+#include "pthread.h"
+
+#define TAG "NotiProviderWrapperExample"
+using namespace std;
+using namespace OIC::Service;
+std::vector<std::string> discoveredConsumers;
+uint64_t mainMessageId = 0;
+
+extern char *strdup(const char *s);
+
+bool isExit = false;
+
+int id = 0;
+std::string REMOTE_SERVER_ADDRESS;
+
+void *OCProcessThread(void *ptr)
+{
+    (void) ptr;
+    while (!isExit)
+    {
+        usleep(2000);
+        if (OCProcess() != OC_STACK_OK)
+        {
+            std::cout << "OCStack process error" << std::endl;
+            return NULL;
+        }
+    }
+
+    return NULL;
+}
+
+void subscribeRequestCallback(std::shared_ptr<OIC::Service::NSConsumer> consumer)
+{
+    std::cout << "consumer requested to subscribe" << std::endl;
+
+    std::cout << "Consumer Device ID: " << consumer->getConsumerId() << std::endl;
+    discoveredConsumers.push_back(consumer->getConsumerId());
+    consumer->acceptSubscription(true);
+}
+
+void syncCallback(OIC::Service::NSSyncInfo sync)
+{
+    std::cout << "SyncInfo Received " << std::endl;
+    std::cout << "Sync ID : " <<  sync.getMessageId() << std::endl;
+    std::cout << "Provider ID : " <<  sync.getProviderId() << std::endl;
+    std::cout << "Sync State: " << (int) sync.getState() << std::endl;
+}
+
+std::shared_ptr<OIC::Service::NSConsumer> printAvailableConsumers()
+{
+    std::cout << "Choose the Consumer ID for operation" << std::endl;
+    int pos = 1;
+    unsigned int option = 0;
+    for (auto it : discoveredConsumers)
+    {
+        std::cout << pos << ". " << it << std::endl;
+        pos++;
+    }
+    while (!(std::cin >> option))
+    {
+        std::cout << "Bad value!" << std::endl;;
+        std::cin.clear();
+        std::cin.ignore(numeric_limits<streamsize>::max(), '\n');
+    }
+    option--;
+    if (option > discoveredConsumers.size())
+    {
+        return NULL;
+    }
+    std::string consumerId = discoveredConsumers[option];
+    std::shared_ptr<OIC::Service::NSConsumer> consumer =
+        NSProviderService::getInstance()->getConsumer(consumerId);
+    return consumer;
+}
+
+int main()
+{
+    int num = 0;
+    pthread_t processThread = 0;
+
+    std::cout << "start Iotivity" << std::endl;
+
+
+    if (OCInit(NULL, 0, OC_CLIENT_SERVER) != OC_STACK_OK)
+    {
+        std::cout << "OCStack init error" << std::endl;
+        return 0;
+    }
+
+    pthread_create(&processThread, NULL, OCProcessThread, NULL);
+
+    while (!isExit)
+    {
+        std::cout << "1. Start the Notification Provider(Accepter: Provider)" << std::endl;
+        std::cout << "2. Start the Notification Provider(Accepter: Consumer)" << std::endl;
+        std::cout << "3. Allow Subscription" << std::endl;
+        std::cout << "4. Deny Subscription" << std::endl;
+        std::cout << "5. SendMessage " << std::endl;
+        std::cout << "6. SendSyncInfo" << std::endl;
+
+        std::cout << "7. RegisterTopic" << std::endl;
+        std::cout << "8. UnregisterTopic" << std::endl;
+        std::cout << "9. SetTopic" << std::endl;
+        std::cout << "10. UnsetTopic" << std::endl;
+        std::cout << "11. GetConsumerTopicList" << std::endl;
+        std::cout << "12. GetRegisteredTopicList" << std::endl;
+#ifdef WITH_CLOUD
+        std::cout << "13. Enable NS Provider RemoteService" << std::endl;
+        std::cout << "14. Disable NS Provider RemoteService" << std::endl;
+#endif
+        std::cout << "15. Stop the Notification Provider" << std::endl;
+        std::cout << "16. Exit()" << std::endl;
+
+        std::cout << "input : ";
+
+        std::cin >> num;
+
+        switch (num)
+        {
+            case 1:
+                {
+                    std::cout << "Start (Accepter: Provider)" << std::endl;
+                    NSProviderService::ProviderConfig cfg;
+                    cfg.m_subscribeRequestCb = subscribeRequestCallback;
+                    cfg.m_syncInfoCb = syncCallback;
+                    cfg.subControllability = true;
+
+                    NSProviderService::getInstance()->start(cfg);
+                    break;
+                }
+            case 2:
+                {
+                    std::cout << "Start (Accepter: Consumer)" << std::endl;
+                    NSProviderService::ProviderConfig cfg;
+                    cfg.m_subscribeRequestCb = subscribeRequestCallback;
+                    cfg.m_syncInfoCb = syncCallback;
+                    cfg.subControllability = false;
+
+                    NSProviderService::getInstance()->start(cfg);
+                    break;
+                }
+            case 3:
+                {
+                    std::cout << "Allow Subscription" << std::endl;
+                    std::shared_ptr<OIC::Service::NSConsumer> consumer = printAvailableConsumers();
+                    if (consumer != nullptr)
+                    {
+                        std::cout << "ALLOW" << std::endl;
+                        consumer->acceptSubscription(true);
+                    }
+                    break;
+                }
+            case 4:
+                {
+                    std::cout << "Deny Subscription" << std::endl;
+                    std::shared_ptr<OIC::Service::NSConsumer>consumer = printAvailableConsumers();
+                    if (consumer != nullptr)
+                    {
+                        std::cout << "DENY" << std::endl;
+                        consumer->acceptSubscription(false);
+                    }
+                    break;
+                }
+            case 5:
+                {
+                    std::cout << "------------------------------------" << std::endl;
+                    std::cout << "SendMessage" << std::endl;
+                    std::cout << "------------------------------------" << std::endl;
+
+                    std::string dummy;
+                    std::string title;
+                    std::string body;
+                    std::string topic;
+
+                    std::cout << "id : " << ++id << std::endl;
+                    std::cout << "title : ";
+
+                    std::getline(std::cin, dummy);
+                    std::getline(std::cin, title);
+
+                    std::cout << "body : ";
+                    std::getline(std::cin, body);
+
+                    std::cout << "topic : ";
+                    std::getline(std::cin, topic);
+
+                    std::cout << "app - mTitle : " << title << std::endl;
+                    std::cout << "app - mContentText : " << body << std::endl;
+                    std::cout << "app - mTopic : " << topic << std::endl;
+
+                    OIC::Service::NSMessage msg = NSProviderService::getInstance()->createMessage();
+
+                    msg.setType(OIC::Service::NSMessage::NSMessageType::NS_MESSAGE_INFO);
+                    msg.setTitle(title.c_str());
+                    msg.setContentText(body.c_str());
+                    msg.setSourceName("OCF");
+                    msg.setTopic(topic);
+                    msg.setTTL(40);
+                    msg.setTime("12:30");
+                    OIC::Service::NSMediaContents *mediaContents =
+                        new OIC::Service::NSMediaContents("iconImage");
+                    msg.setMediaContents(mediaContents);
+
+                    OC::OCRepresentation rep;
+                    rep.setValue("Key1", "Value1");
+                    rep.setValue("Key2", "Value2");
+                    msg.setExtraInfo(rep);
+
+                    mainMessageId = msg.getMessageId();
+                    std::cout << "ProviderID for Message : " << msg.getProviderId() << std::endl;
+                    std::cout << "MessageID for Message : " << msg.getMessageId() << std::endl;
+
+                    NSProviderService::getInstance()->sendMessage(msg);
+                    break;
+                }
+            case 6:
+                {
+                    std::cout << "------------------------------------" << std::endl;
+                    std::cout <<  "SendSyncInfo" << std::endl;
+                    std::cout << "------------------------------------" << std::endl;
+                    if (!mainMessageId)
+                    {
+                        std::cout <<  "Message ID is empty" << std::endl;
+                        break;
+                    }
+                    std::cout << "1. Send Read Sync" << std::endl;
+                    std::cout << "2. Send Delete Sync" << std::endl;
+                    int syn = 0;
+                    while (!(std::cin >> syn))
+                    {
+                        std::cout << "Bad value!" << std::endl;;
+                        std::cin.clear();
+                        std::cin.ignore(numeric_limits<streamsize>::max(), '\n');
+                    }
+                    switch (syn)
+                    {
+                        case 1:
+                            {
+                                std::cout << "Sending Read Sync" << std::endl;
+                                NSProviderService::getInstance()->sendSyncInfo(mainMessageId,
+                                        OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_READ);
+                            }
+                            break;
+                        case 2:
+                            {
+                                std::cout << "Sending Delete Sync" << std::endl;
+                                NSProviderService::getInstance()->sendSyncInfo(mainMessageId,
+                                        OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_DELETED);
+                            }
+                            break;
+                        default:
+                            {
+                                cout << "Invalid Input!. sending default Read Sync";
+                                NSProviderService::getInstance()->sendSyncInfo(mainMessageId,
+                                        OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_READ);
+                                std::cin.clear();
+                                std::cin.ignore(numeric_limits<streamsize>::max(), '\n');
+                                break;
+                            }
+                    }
+                    break;
+                }
+
+            case 7:
+                {
+                    std::cout <<  "RegisterTopic" << std::endl;
+                    NSProviderService::getInstance()->registerTopic("OCF_TOPIC1");
+                    NSProviderService::getInstance()->registerTopic("OCF_TOPIC2");
+                    NSProviderService::getInstance()->registerTopic("OCF_TOPIC3");
+                    NSProviderService::getInstance()->registerTopic("OCF_TOPIC4");
+                    break;
+                }
+            case 8:
+                {
+                    std::cout <<  "UnregisterTopic" << std::endl;
+                    NSProviderService::getInstance()->unregisterTopic("OCF_TOPIC2");
+                    break;
+                }
+            case 9:
+                {
+                    std::cout <<  "SetTopic" << std::endl;
+                    std::shared_ptr<OIC::Service::NSConsumer> consumer = printAvailableConsumers();
+                    if (consumer != nullptr)
+                    {
+                        consumer->setTopic("OCF_TOPIC1");
+                        consumer->setTopic("OCF_TOPIC2");
+                        consumer->setTopic("OCF_TOPIC3");
+                        std::cout <<  "SelectTopic completed" << std::endl;
+                    }
+                    break;
+                }
+            case 10:
+                {
+                    std::cout <<  "UnsetTopic" << std::endl;
+                    std::shared_ptr<OIC::Service::NSConsumer> consumer = printAvailableConsumers();
+                    if (consumer != nullptr)
+                    {
+                        consumer->unsetTopic("OCF_TOPIC1");
+                        std::cout <<  "UnSelectTopic completed" << std::endl;
+                    }
+                    break;
+                }
+
+            case 11:
+                {
+                    std::cout <<  "GetConsumerTopicList" << std::endl;
+                    std::shared_ptr<OIC::Service::NSConsumer> consumer = printAvailableConsumers();
+                    if (consumer != nullptr)
+                    {
+                        auto nsTopics = consumer->getConsumerTopicList();
+                        if (nsTopics != nullptr)
+                        {
+                            for (auto it : nsTopics->getTopicsList())
+                            {
+
+                                std::cout << it.getTopicName() << std::endl;
+                                std::cout << (int) it.getState() << std::endl;
+                            }
+                        }
+                        std::cout <<  "GetConsumerTopicList completed" << std::endl;
+                    }
+                    break;
+                }
+
+            case 12:
+                {
+                    std::cout <<  "GetRegisteredTopicList" << std::endl;
+                    auto nsTopics = NSProviderService::getInstance()->getRegisteredTopicList();
+                    for (auto it : nsTopics->getTopicsList())
+                    {
+
+                        std::cout << it.getTopicName() << std::endl;
+                        std::cout << (int) it.getState() << std::endl;
+                    }
+                    break;
+                }
+#ifdef WITH_CLOUD
+            case 13:
+                {
+                    std::cout << "Enable NS Provider RemoteService" << std::endl;
+                    std::cout << "Input the Server Address :";
+                    std::cin >> REMOTE_SERVER_ADDRESS;
+                    NSProviderService::getInstance()->enableRemoteService(REMOTE_SERVER_ADDRESS);
+                    break;
+                }
+            case 14:
+                {
+                    std::cout << "Disable NS Provider RemoteService" << std::endl;
+                    std::cout << "Input the Server Address :";
+                    NSProviderService::getInstance()->disableRemoteService(REMOTE_SERVER_ADDRESS);
+                    break;
+                }
+#endif
+            case 15:
+                {
+                    std::cout << "Stop the Notification Provider" << std::endl;
+                    NSProviderService::getInstance()->stop();
+                    break;
+                }
+            case 16:
+                {
+                    std::cout << "Exit()" << std::endl;
+                    NSProviderService::getInstance()->stop();
+                    isExit = true;
+                    break;
+                }
+            default:
+                {
+                    std::cout << "Under Construction" << std::endl;
+                    std::cin.clear();
+                    std::cin.ignore(numeric_limits<streamsize>::max(), '\n');
+                    break;
+                }
+        }
+
+        std::cout << std::endl;
+    }
+
+    return 0;
+}
index 2be55f1..742cceb 100755 (executable)
@@ -53,7 +53,8 @@ notification_env.PrependUnique(LIBS = [
        'oc_logger',
        'oc',
        'octbstack',
-       'notification_provider'
+       'notification_provider',
+        'resource_directory'
        ])
 notification_env.AppendUnique(CXXFLAGS = ['-std=c++0x','-frtti'])
 
@@ -77,6 +78,18 @@ if not env.get('RELEASE') and target_os not in ['ios']:
 if env.get('WITH_CLOUD') == True:
        notification_env.AppendUnique(CPPDEFINES = ['WITH_CLOUD'])
 
+with_mq = env.get('WITH_MQ')
+if 'SUB' in with_mq:
+    notification_env.AppendUnique(CPPDEFINES = ['MQ_SUBSCRIBER', 'WITH_MQ'])
+    print "MQ SUB support"
+
+if 'PUB' in with_mq:
+    notification_env.AppendUnique(CPPDEFINES = ['MQ_PUBLISHER', 'WITH_MQ'])
+    print "MQ PUB support"
+
+if 'BROKER' in with_mq:
+    notification_env.AppendUnique(CPPDEFINES = ['MQ_BROKER', 'WITH_MQ'])
+    print "MQ Broker support"
 ######################################################################
 # Source files and Targets for Provider
 ######################################################################
diff --git a/service/notification/cpp-wrapper/provider/inc/NSAcceptedConsumers.h b/service/notification/cpp-wrapper/provider/inc/NSAcceptedConsumers.h
new file mode 100755 (executable)
index 0000000..6341f45
--- /dev/null
@@ -0,0 +1,116 @@
+//******************************************************************
+//
+// Copyright 2017 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 C++ Wrapper APIs of Notification Service for accepted consumers.
+ */
+
+#ifndef _NS_ACCEPTED_CONSUMERS_H_
+#define _NS_ACCEPTED_CONSUMERS_H_
+
+#include <map>
+#include <mutex>
+#include <algorithm>
+#include <memory>
+#include "NSConsumer.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        /**
+              * @class   NSAcceptedConsumers
+              * @brief   This class provides a set of C++APIs for managing accepted Consumers.
+              */
+        class NSAcceptedConsumers
+        {
+            public :
+                /**
+                     * Constructor of NSAcceptedConsumers.
+                     *
+                     */
+                NSAcceptedConsumers()
+                {
+                    removeConsumers();
+                }
+
+                /**
+                      * Destructor of NSAcceptedConsumers.
+                      */
+                ~NSAcceptedConsumers()
+                {
+                    removeConsumers();
+                }
+                /**
+                      *  request to get NSConsumer pointer
+                      * @param id -id as string
+                      *
+                      * @return pointer to NSConsumer
+                      */
+                std::shared_ptr<NSConsumer> getConsumer(const std::string &id);
+
+                /**
+                      *  request to add NSConsumer pointer
+                      * @param pointer to NSConsumer
+                      *
+                      */
+                void addConsumer(std::shared_ptr<NSConsumer> consumer);
+
+                /**
+                      *  request to remove NSConsumer
+                      * @param id -id as string
+                      *
+                      */
+                void removeConsumer(const std::string &id);
+
+                /**
+                      *  request to check if NSConsumer is accepted
+                      * @param id -id as string
+                      *
+                      * @return true if accepted else false
+                      */
+                bool isAccepted(const std::string &id);
+
+                /**
+                      *  get size of Consumers accepted.
+                      * @return m_consumers size
+                      */
+                int size();
+
+                /**
+                      *  request to remove all NSConsumer
+                      */
+                void removeConsumers();
+
+                /**
+                      *  get the map of Consumers accepted.
+                      * @return m_consumers  -map of accepted Consumers
+                      */
+                std::map<std::string, std::shared_ptr<NSConsumer> > getConsumers();
+
+            private :
+                std::map<std::string, std::shared_ptr<NSConsumer> > m_consumers;
+                std::mutex m_mutex;
+        };
+    }
+}
+#endif /* _NS_ACCEPTED_CONSUMERS_H_ */
index 203ab9e..6a3f89d 100755 (executable)
@@ -29,6 +29,7 @@
 \r
 \r
 #include <string>\r
+#include <memory>\r
 #include "NSCommon.h"\r
 #include "NSUtils.h"\r
 #include "NSTopicsList.h"\r
@@ -82,8 +83,9 @@ namespace OIC
                       * This method is for setting icon image for the Notification service media contents.\r
                       * This function is valid only when subControllability is set true.\r
                       * @param accepted - as bool.\r
+                      * @return :: OK or result code of NSResult\r
                       */\r
-                int acceptSubscription(bool accepted);\r
+                NSResult acceptSubscription(bool accepted);\r
 \r
                 /**\r
                      * Select a topic name for a consumer\r
@@ -103,10 +105,11 @@ namespace OIC
                      * Request topic list with selection state for the consumer\r
                      * @return :: Topic list\r
                      */\r
-                NSTopicsList *getConsumerTopicList();\r
+                std::shared_ptr<NSTopicsList> getConsumerTopicList();\r
 \r
             private:\r
                 ::NSConsumer *getNSConsumer();\r
+                bool isValid() const;\r
 \r
             private:\r
                 std::string m_consumerId;\r
index f96d239..575ea93 100755 (executable)
@@ -38,26 +38,26 @@ namespace OIC
 {\r
     namespace Service\r
     {\r
+        class NSAcceptedConsumers;\r
         /**\r
          * @class   NSProviderService\r
          * @brief   This class provides a set of C++APIs for Notification Provider.\r
          */\r
         class NSProviderService\r
         {\r
-\r
             public:\r
                 /**\r
                       * Provider uses this callback function to receive subscription request of consumer\r
                       * @param[in] consumer  Consumer who subscribes the notification message resource\r
                       */\r
-                typedef void (*ConsumerSubscribedCallback)(NSConsumer *);\r
+                typedef void (*ConsumerSubscribedCallback)(std::shared_ptr<NSConsumer> );\r
 \r
                 /**\r
                       * Provider use this callback function to receive the status of the message\r
                       * synchronization\r
                       * @param[in] sync Synchronization information of the notification message\r
                       */\r
-                typedef void (*MessageSynchronizedCallback)(NSSyncInfo *);\r
+                typedef void (*MessageSynchronizedCallback)(NSSyncInfo );\r
 \r
 \r
                 /**\r
@@ -118,25 +118,34 @@ namespace OIC
                 NSResult disableRemoteService(const std::string &serverAddress);\r
 \r
                 /**\r
+                      * Request to subscribe to remote MQ address as parameter.\r
+                      * @param[in] server address combined with IP address and port number and MQ broker uri using delimiter :\r
+                      * @param[in] topicName the interest Topic name for subscription.\r
+                      * @return ::NS_OK or result code of NSResult\r
+                      */\r
+                NSResult subscribeMQService(const std::string &serverAddress, const std::string &topicName);\r
+\r
+                /**\r
                       * Send notification message to all subscribers\r
                       * @param[in]  msg  Notification message including id, title, contentText\r
                       * @return :: result code of Provider Service\r
                       */\r
-                NSResult sendMessage(NSMessage *msg);\r
+                NSResult sendMessage(const NSMessage &msg);\r
 \r
 \r
                 /**\r
                       * Send read-check to provider in order to synchronize notification status with other consumers\r
                       * @param[in]  messageId  ID of Notification message to synchronize the status\r
                       * @param[in]  type  NotificationSyncType of the SyncInfo message\r
+                      * @return :: OK or result code of NSResult\r
                       */\r
-                void sendSyncInfo(uint64_t messageId, NSSyncInfo::NSSyncType type);\r
+                NSResult sendSyncInfo(uint64_t messageId, NSSyncInfo::NSSyncType type);\r
 \r
                 /**\r
                      * Initialize NSMessage class, This function is valid only when subControllability is set true.\r
                      * @return NSMessage *\r
                      */\r
-                NSMessage *createMessage();\r
+                NSMessage createMessage();\r
 \r
                 /**\r
                      * Add topic to topic list which is located in provider service storage\r
@@ -156,7 +165,7 @@ namespace OIC
                      * Request topics list already registered by provider user\r
                      * @return :: Topic list\r
                      */\r
-                NSTopicsList *getRegisteredTopicList();\r
+                std::shared_ptr<NSTopicsList> getRegisteredTopicList();\r
 \r
                 /**\r
                       *  get Provider config values\r
@@ -168,33 +177,31 @@ namespace OIC
                       *  request to get NSConsumer pointer\r
                       * @param id -id as string\r
                       *\r
-                      * @return pointer to NSConsumer\r
+                      * @return shared pointer to NSConsumer\r
                       */\r
-                NSConsumer *getConsumer(const std::string &id);\r
+                std::shared_ptr<NSConsumer> getConsumer(const std::string &id);\r
 \r
                 /**\r
-                      *  get list of Consumers accepted.\r
-                      * @return m_acceptedConsumers -list of accepted Consumers\r
+                      *  get handle of Consumers accepted.\r
+                      * @return m_acceptedConsumers -accepted Consumers\r
                       */\r
-                std::list<NSConsumer *> &getAcceptedConsumers();\r
+                NSAcceptedConsumers *getAcceptedConsumers();\r
 \r
             private :\r
                 ProviderConfig m_config;\r
-                std::list<NSConsumer *> m_acceptedConsumers;\r
+                NSAcceptedConsumers *m_acceptedConsumers;\r
 \r
             private:\r
-                NSProviderService()\r
-                {\r
-                    m_config.m_subscribeRequestCb = NULL;\r
-                    m_config.m_syncInfoCb = NULL;\r
-                }\r
+                NSProviderService();\r
                 ~NSProviderService();\r
                 NSProviderService(const NSProviderService &) = delete;\r
                 NSProviderService &operator=(const NSProviderService &) = delete;\r
                 NSProviderService(const NSProviderService &&) = delete;\r
                 NSProviderService &operator=(const NSProviderService && ) = delete;\r
 \r
-                ::NSMessage *getNSMessage(NSMessage *msg);\r
+                ::NSMessage *getNSMessage(const NSMessage &msg);\r
+                static void onConsumerSubscribedCallback(::NSConsumer *consumer);\r
+                static void onMessageSynchronizedCallback(::NSSyncInfo *syncInfo);\r
         };\r
     }\r
 }\r
diff --git a/service/notification/cpp-wrapper/provider/src/NSAcceptedConsumers.cpp b/service/notification/cpp-wrapper/provider/src/NSAcceptedConsumers.cpp
new file mode 100755 (executable)
index 0000000..241317a
--- /dev/null
@@ -0,0 +1,98 @@
+//******************************************************************
+//
+// Copyright 2017 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 "NSProviderService.h"
+#include <cstring>
+#include "NSCommon.h"
+#include "NSConstants.h"
+#include "NSAcceptedConsumers.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        std::shared_ptr<NSConsumer> NSAcceptedConsumers::getConsumer(const std::string &id)
+        {
+            std::lock_guard<std::mutex> lock(m_mutex);
+            NS_LOG_V(DEBUG, "AcceptedConsumers::getConsumer size  : %d", (int) m_consumers.size());
+            auto it = m_consumers.find(id);
+            if (it != m_consumers.end() )
+            {
+                NS_LOG(DEBUG, "getConsumer : Found Consumer with given ID");
+                return it->second;
+            }
+            NS_LOG(DEBUG, "getConsumer : Not Found Consumer with given ID");
+            return NULL;
+        }
+        void NSAcceptedConsumers::addConsumer(std::shared_ptr<NSConsumer> consumer)
+        {
+            std::lock_guard<std::mutex> lock(m_mutex);
+            NS_LOG_V(INFO_PRIVATE, "AcceptedConsumers::addConsumer  Id : %s", consumer->getConsumerId().c_str());
+            m_consumers[consumer->getConsumerId()] = consumer;
+            return;
+        }
+
+        void NSAcceptedConsumers::removeConsumer(const std::string &id)
+        {
+            std::lock_guard<std::mutex> lock(m_mutex);
+            NS_LOG_V(INFO_PRIVATE, "AcceptedConsumers::removeConsumer  Id : %s", id.c_str());
+            m_consumers.erase(id);
+            return;
+        }
+
+        bool NSAcceptedConsumers::isAccepted(const std::string &id)
+        {
+            std::lock_guard<std::mutex> lock(m_mutex);
+            NS_LOG_V(INFO_PRIVATE, "AcceptedConsumers::isAccepted  Id : %s", id.c_str());
+            if ( m_consumers.find(id) == m_consumers.end() )
+            {
+                NS_LOG(DEBUG, "isAccepted : Not Found Consumer with given ID");
+                return false;
+            }
+            else
+            {
+                NS_LOG(DEBUG, "isAccepted : Found Consumer with given ID");
+                return true;
+            }
+        }
+
+        int NSAcceptedConsumers::size()
+        {
+            std::lock_guard<std::mutex> lock(m_mutex);
+            NS_LOG_V(DEBUG, "AcceptedConsumers::size  : %d", (int) m_consumers.size());
+            return m_consumers.size();
+        }
+
+        void NSAcceptedConsumers::removeConsumers()
+        {
+            std::lock_guard<std::mutex> lock(m_mutex);
+            NS_LOG(DEBUG, "AcceptedConsumers::removeConsumers ");
+            m_consumers.clear();
+            return;
+        }
+
+        std::map<std::string, std::shared_ptr<NSConsumer> > NSAcceptedConsumers::getConsumers()
+        {
+            std::lock_guard<std::mutex> lock(m_mutex);
+            return m_consumers;
+        }
+    }
+}
index a81f875..5d3c472 100755 (executable)
 \r
 #include "NSConsumer.h"\r
 #include <cstring>\r
+#include "NSProviderService.h"\r
+#include "NSAcceptedConsumers.h"\r
 #include "NSProviderInterface.h"\r
+#include "NSException.h"\r
 #include "NSConstants.h"\r
 #include "oic_string.h"\r
 #include "oic_malloc.h"\r
@@ -49,17 +52,25 @@ namespace OIC
             return m_consumerId;\r
         }\r
 \r
-        int NSConsumer::acceptSubscription(bool accepted)\r
+        NSResult NSConsumer::acceptSubscription(bool accepted)\r
         {\r
             NS_LOG(DEBUG, "acceptSubscription - IN");\r
+            if (!isValid())\r
+            {\r
+                throw NSException("Invalid Operation with stale reference of Consumer");\r
+            }\r
             NSResult result = (NSResult) NSAcceptSubscription(getConsumerId().c_str(), accepted);\r
             NS_LOG(DEBUG, "acceptSubscription - OUT");\r
-            return (int) result;\r
+            return result;\r
         }\r
 \r
         NSResult NSConsumer::setTopic(const std::string &topicName)\r
         {\r
             NS_LOG(DEBUG, "setTopic - IN");\r
+            if (!isValid())\r
+            {\r
+                throw NSException("Invalid Operation with stale reference of Consumer");\r
+            }\r
             NSResult result = (NSResult) NSProviderSetConsumerTopic(getConsumerId().c_str(),\r
                               topicName.c_str());\r
             NS_LOG(DEBUG, "setTopic - OUT");\r
@@ -69,20 +80,38 @@ namespace OIC
         NSResult NSConsumer::unsetTopic(const std::string &topicName)\r
         {\r
             NS_LOG(DEBUG, "unsetTopic - IN");\r
+            if (!isValid())\r
+            {\r
+                throw NSException("Invalid Operation with stale reference of Consumer");\r
+            }\r
             NSResult result = (NSResult) NSProviderUnsetConsumerTopic(getConsumerId().c_str(),\r
                               topicName.c_str());\r
             NS_LOG(DEBUG, "unsetTopic - OUT");\r
             return result;\r
         }\r
 \r
-        NSTopicsList *NSConsumer::getConsumerTopicList()\r
+        std::shared_ptr<NSTopicsList> NSConsumer::getConsumerTopicList()\r
         {\r
             NS_LOG(DEBUG, "getConsumerTopicList - IN");\r
+            if (!isValid())\r
+            {\r
+                throw NSException("Invalid Operation with stale reference of Consumer");\r
+            }\r
             ::NSTopicLL *topics = NSProviderGetConsumerTopics(getConsumerId().c_str());\r
 \r
-            NSTopicsList *nsTopics = new NSTopicsList(topics);\r
+            std::shared_ptr<NSTopicsList> nsTopics = std::make_shared<NSTopicsList>(topics, false);\r
             NS_LOG(DEBUG, "getConsumerTopicList - OUT");\r
             return nsTopics;\r
         }\r
+\r
+        bool NSConsumer::isValid() const\r
+        {\r
+            if (!NSProviderService::getInstance()->getAcceptedConsumers()->isAccepted(getConsumerId()))\r
+            {\r
+                NS_LOG(DEBUG, "Invalid Operation with stale reference of Consumer. Consumer ID doesnot exist");\r
+                return false;\r
+            }\r
+            return true;\r
+        }\r
     }\r
 }\r
index 7fd88d6..c6332cc 100755 (executable)
@@ -23,6 +23,7 @@
 #include <cstring>\r
 #include "NSCommon.h"\r
 #include "NSProviderInterface.h"\r
+#include "NSAcceptedConsumers.h"\r
 #include "NSConsumer.h"\r
 #include "NSSyncInfo.h"\r
 #include "NSConstants.h"\r
@@ -35,11 +36,11 @@ namespace OIC
 {\r
     namespace Service\r
     {\r
-        void onConsumerSubscribedCallback(::NSConsumer *consumer)\r
+        void NSProviderService::onConsumerSubscribedCallback(::NSConsumer *consumer)\r
         {\r
             NS_LOG(DEBUG, "onConsumerSubscribedCallback - IN");\r
-            NSConsumer *nsConsumer = new NSConsumer(consumer);\r
-            NSProviderService::getInstance()->getAcceptedConsumers().push_back(nsConsumer);\r
+            std::shared_ptr<NSConsumer> nsConsumer = std::make_shared<NSConsumer>(consumer);\r
+            NSProviderService::getInstance()->getAcceptedConsumers()->addConsumer(nsConsumer);\r
             if (NSProviderService::getInstance()->getProviderConfig().m_subscribeRequestCb != NULL)\r
             {\r
                 NS_LOG(DEBUG, "initiating the callback for consumer subscribed");\r
@@ -48,52 +49,57 @@ namespace OIC
             NS_LOG(DEBUG, "onConsumerSubscribedCallback - OUT");\r
         }\r
 \r
-        void onMessageSynchronizedCallback(::NSSyncInfo *syncInfo)\r
+        void NSProviderService::onMessageSynchronizedCallback(::NSSyncInfo *syncInfo)\r
         {\r
             NS_LOG(DEBUG, "onMessageSynchronizedCallback - IN");\r
-            NSSyncInfo *nsSyncInfo = new NSSyncInfo(syncInfo);\r
+            NSSyncInfo nsSyncInfo(syncInfo);\r
             if (NSProviderService::getInstance()->getProviderConfig().m_syncInfoCb != NULL)\r
             {\r
                 NS_LOG(DEBUG, "initiating the callback for synchronized");\r
                 NSProviderService::getInstance()->getProviderConfig().m_syncInfoCb(nsSyncInfo);\r
             }\r
-            delete nsSyncInfo;\r
             NS_LOG(DEBUG, "onMessageSynchronizedCallback - OUT");\r
         }\r
 \r
-        ::NSMessage *NSProviderService::getNSMessage(NSMessage *msg)\r
+        ::NSMessage *NSProviderService::getNSMessage(const NSMessage &msg)\r
         {\r
             ::NSMessage *nsMsg = new ::NSMessage;\r
-            nsMsg->messageId = msg->getMessageId();\r
-            OICStrcpy(nsMsg->providerId, NS_UTILS_UUID_STRING_SIZE, msg->getProviderId().c_str());\r
-            nsMsg->sourceName = OICStrdup(msg->getSourceName().c_str());\r
-            nsMsg->type = (::NSMessageType) msg->getType();\r
-            nsMsg->dateTime = OICStrdup(msg->getTime().c_str());\r
-            nsMsg->ttl = msg->getTTL();\r
-            nsMsg->title = OICStrdup(msg->getTitle().c_str());\r
-            nsMsg->contentText = OICStrdup(msg->getContentText().c_str());\r
-            nsMsg->topic = OICStrdup(msg->getTopic().c_str());\r
-\r
-            if (msg->getMediaContents() != nullptr)\r
+            nsMsg->messageId = msg.getMessageId();\r
+            OICStrcpy(nsMsg->providerId, NS_UTILS_UUID_STRING_SIZE, msg.getProviderId().c_str());\r
+            nsMsg->sourceName = OICStrdup(msg.getSourceName().c_str());\r
+            nsMsg->type = (::NSMessageType) msg.getType();\r
+            nsMsg->dateTime = OICStrdup(msg.getTime().c_str());\r
+            nsMsg->ttl = msg.getTTL();\r
+            nsMsg->title = OICStrdup(msg.getTitle().c_str());\r
+            nsMsg->contentText = OICStrdup(msg.getContentText().c_str());\r
+            nsMsg->topic = OICStrdup(msg.getTopic().c_str());\r
+\r
+            if (msg.getMediaContents() != nullptr)\r
             {\r
                 nsMsg->mediaContents = new ::NSMediaContents;\r
-                nsMsg->mediaContents->iconImage = OICStrdup(msg->getMediaContents()->getIconImage().c_str());\r
+                nsMsg->mediaContents->iconImage = OICStrdup(msg.getMediaContents()->getIconImage().c_str());\r
             }\r
             else\r
             {\r
                 nsMsg->mediaContents = nullptr;\r
             }\r
-            nsMsg->extraInfo = msg->getExtraInfo().getPayload();\r
+            nsMsg->extraInfo = msg.getExtraInfo().getPayload();\r
             return nsMsg;\r
         }\r
 \r
+        NSProviderService::NSProviderService()\r
+        {\r
+            m_config.m_subscribeRequestCb = NULL;\r
+            m_config.m_syncInfoCb = NULL;\r
+            m_acceptedConsumers = new NSAcceptedConsumers();\r
+        }\r
+\r
         NSProviderService::~NSProviderService()\r
         {\r
-            for (auto it : getAcceptedConsumers())\r
-            {\r
-                delete it;\r
-            }\r
-            getAcceptedConsumers().clear();\r
+            m_config.m_subscribeRequestCb = NULL;\r
+            m_config.m_syncInfoCb = NULL;\r
+            m_acceptedConsumers->removeConsumers();\r
+            delete m_acceptedConsumers;\r
         }\r
 \r
         NSProviderService *NSProviderService::getInstance()\r
@@ -105,6 +111,7 @@ namespace OIC
         NSResult NSProviderService::start(NSProviderService::ProviderConfig config)\r
         {\r
             NS_LOG(DEBUG, "start - IN");\r
+            m_acceptedConsumers->removeConsumers();\r
 \r
             m_config = config;\r
             NSProviderConfig nsConfig;\r
@@ -123,6 +130,11 @@ namespace OIC
         NSResult NSProviderService::stop()\r
         {\r
             NS_LOG(DEBUG, "stop - IN");\r
+\r
+            m_config.m_subscribeRequestCb = NULL;\r
+            m_config.m_syncInfoCb = NULL;\r
+            m_acceptedConsumers->removeConsumers();\r
+\r
             NSResult result = (NSResult) NSStopProvider();\r
             NS_LOG(DEBUG, "stop - OUT");\r
             return result;\r
@@ -131,7 +143,7 @@ namespace OIC
         NSResult NSProviderService::enableRemoteService(const std::string &serverAddress)\r
         {\r
             NS_LOG(DEBUG, "enableRemoteService - IN");\r
-            NS_LOG_V(DEBUG, "Server Address : %s", serverAddress.c_str());\r
+            NS_LOG_V(INFO_PRIVATE, "Server Address : %s", serverAddress.c_str());\r
             NSResult result = NSResult::ERROR;\r
 #ifdef WITH_CLOUD\r
             result = (NSResult) NSProviderEnableRemoteService(OICStrdup(serverAddress.c_str()));\r
@@ -146,7 +158,7 @@ namespace OIC
         NSResult NSProviderService::disableRemoteService(const std::string &serverAddress)\r
         {\r
             NS_LOG(DEBUG, "disableRemoteService - IN");\r
-            NS_LOG_V(DEBUG, "Server Address : %s", serverAddress.c_str());\r
+            NS_LOG_V(INFO_PRIVATE, "Server Address : %s", serverAddress.c_str());\r
             NSResult result = NSResult::ERROR;\r
 #ifdef WITH_CLOUD\r
             result = (NSResult) NSProviderDisableRemoteService(OICStrdup(serverAddress.c_str()));\r
@@ -158,58 +170,71 @@ namespace OIC
             return result;\r
         }\r
 \r
-        NSResult NSProviderService::sendMessage(NSMessage *msg)\r
+        NSResult NSProviderService::subscribeMQService(const std::string &serverAddress,\r
+                const std::string &topicName)\r
+        {\r
+            NS_LOG(DEBUG, "subscribeMQService - IN");\r
+            NS_LOG_V(INFO_PRIVATE, "Server Address : %s", serverAddress.c_str());\r
+            NSResult result = NSResult::ERROR;\r
+#ifdef WITH_MQ\r
+            result = (NSResult) NSProviderSubscribeMQService(\r
+                         serverAddress.c_str(), topicName.c_str());\r
+#else\r
+            NS_LOG(ERROR, "MQ Services feature is not enabled in the Build");\r
+            (void) serverAddress;\r
+            (void) topicName;\r
+#endif\r
+            NS_LOG(DEBUG, "subscribeMQService - OUT");\r
+            return result;\r
+        }\r
+\r
+        NSResult NSProviderService::sendMessage(const NSMessage &msg)\r
         {\r
             NS_LOG(DEBUG, "sendMessage - IN");\r
             NSResult result = NSResult::ERROR;\r
-            if (msg != nullptr)\r
+\r
+            ::NSMessage *nsMsg = getNSMessage(msg);\r
+\r
+            NS_LOG_V(INFO_PRIVATE, "nsMsg->providerId : %s", nsMsg->providerId);\r
+            result = (NSResult) NSSendMessage(nsMsg);\r
+            OICFree(nsMsg->dateTime);\r
+            OICFree(nsMsg->title);\r
+            OICFree(nsMsg->contentText);\r
+            OICFree(nsMsg->sourceName);\r
+            OICFree(nsMsg->topic);\r
+            if (nsMsg->mediaContents != NULL)\r
             {\r
-                ::NSMessage *nsMsg = getNSMessage(msg);\r
-\r
-                NS_LOG_V(DEBUG, "nsMsg->providerId : %s", nsMsg->providerId);\r
-                result = (NSResult) NSSendMessage(nsMsg);\r
-                OICFree(nsMsg->dateTime);\r
-                OICFree(nsMsg->title);\r
-                OICFree(nsMsg->contentText);\r
-                OICFree(nsMsg->sourceName);\r
-                OICFree(nsMsg->topic);\r
-                if (nsMsg->mediaContents != NULL)\r
+                if (nsMsg->mediaContents->iconImage != NULL)\r
                 {\r
-                    if (nsMsg->mediaContents->iconImage != NULL)\r
-                    {\r
-                        OICFree(nsMsg->mediaContents->iconImage);\r
-                    }\r
-                    delete nsMsg->mediaContents;\r
+                    OICFree(nsMsg->mediaContents->iconImage);\r
                 }\r
-                OCPayloadDestroy((OCPayload *) nsMsg->extraInfo);\r
-                delete nsMsg;\r
-            }\r
-            else\r
-            {\r
-                NS_LOG(DEBUG, "Empty Message");\r
+                delete nsMsg->mediaContents;\r
             }\r
+            OCPayloadDestroy((OCPayload *) nsMsg->extraInfo);\r
+            delete nsMsg;\r
+\r
             NS_LOG(DEBUG, "sendMessage - OUT");\r
             return result;\r
         }\r
 \r
-        void NSProviderService::sendSyncInfo(uint64_t messageId,\r
-                                             NSSyncInfo::NSSyncType type)\r
+        NSResult NSProviderService::sendSyncInfo(uint64_t messageId,\r
+                NSSyncInfo::NSSyncType type)\r
         {\r
             NS_LOG(DEBUG, "sendSyncInfo - IN");\r
-            NSProviderSendSyncInfo(messageId, (NSSyncType)type);\r
+            NSResult result = (NSResult) NSProviderSendSyncInfo(messageId, (NSSyncType)type);\r
             NS_LOG(DEBUG, "sendSyncInfo - OUT");\r
-            return;\r
+            return result;\r
         }\r
 \r
-        NSMessage *NSProviderService::createMessage()\r
+        NSMessage NSProviderService::createMessage()\r
         {\r
             NS_LOG(DEBUG, "createMessage - IN");\r
 \r
             ::NSMessage *message = NSCreateMessage();\r
-            NSMessage *nsMessage = new NSMessage(message);\r
+            NSMessage nsMessage(message);\r
 \r
-            NS_LOG_V(DEBUG, "Message ID : %lld", (long long int) nsMessage->getMessageId());\r
-            NS_LOG_V(DEBUG, "Provider ID : %s", nsMessage->getProviderId().c_str());\r
+            NS_LOG_V(DEBUG, "Message ID : %lld", (long long int) nsMessage.getMessageId());\r
+            NS_LOG_V(INFO_PRIVATE, "Provider ID : %s", nsMessage.getProviderId().c_str());\r
             NS_LOG(DEBUG, "createMessage - OUT");\r
 \r
             OICFree(message);\r
@@ -232,12 +257,12 @@ namespace OIC
             return result;\r
         }\r
 \r
-        NSTopicsList *NSProviderService::getRegisteredTopicList()\r
+        std::shared_ptr<NSTopicsList> NSProviderService::getRegisteredTopicList()\r
         {\r
             NS_LOG(DEBUG, "getRegisteredTopicList - IN");\r
             ::NSTopicLL *topics = NSProviderGetTopics();\r
 \r
-            NSTopicsList *nsTopics = new NSTopicsList(topics);\r
+            std::shared_ptr<NSTopicsList> nsTopics = std::make_shared<NSTopicsList>(topics, false);\r
             NS_LOG(DEBUG, "getRegisteredTopicList - OUT");\r
             return nsTopics;\r
         }\r
@@ -247,21 +272,12 @@ namespace OIC
             return m_config;\r
         }\r
 \r
-        NSConsumer *NSProviderService::getConsumer(const std::string &id)\r
+        std::shared_ptr<NSConsumer> NSProviderService::getConsumer(const std::string &id)\r
         {\r
-            for (auto it : getAcceptedConsumers())\r
-            {\r
-                if (it->getConsumerId() == id)\r
-                {\r
-                    NS_LOG(DEBUG, "getConsumer : Found Consumer with given ID");\r
-                    return it;\r
-                }\r
-            }\r
-            NS_LOG(DEBUG, "getConsumer : Not Found Consumer with given ID");\r
-            return NULL;\r
+            return m_acceptedConsumers->getConsumer(id);\r
         }\r
 \r
-        std::list<NSConsumer *> &NSProviderService::getAcceptedConsumers()\r
+        NSAcceptedConsumers *NSProviderService::getAcceptedConsumers()\r
         {\r
             return m_acceptedConsumers;\r
         }\r
index 054f76c..f279d80 100755 (executable)
@@ -53,7 +53,7 @@ class NSConsumerSimulator
 
         void findProvider()
         {
-            OC::OCPlatform::findResource("", std::string("/oic/res?rt=oic.wk.notification"),
+            OC::OCPlatform::findResource("", std::string("/oic/res?rt=x.org.iotivity.notification"),
                                          OCConnectivityType::CT_DEFAULT,
                                          std::bind(&NSConsumerSimulator::findResultCallback, this, std::placeholders::_1),
                                          OC::QualityOfService::LowQos);
@@ -67,9 +67,9 @@ class NSConsumerSimulator
             }
 
             OC::OCRepresentation rep;
-            rep.setValue("providerid", providerID);
-            rep.setValue("messageid", id);
-            rep.setValue("state", type);
+            rep.setValue("x.org.iotivity.ns.providerid", providerID);
+            rep.setValue("x.org.iotivity.ns.messageid", id);
+            rep.setValue("x.org.iotivity.ns.state", type);
 
             m_syncResource->post(rep, OC::QueryParamsMap(), &onPost, OC::QualityOfService::LowQos);
         }
@@ -115,13 +115,13 @@ class NSConsumerSimulator
         {
 
             OC::QueryParamsMap map;
-            map.insert(std::pair<std::string, std::string>(std::string("consumerid"),
+            map.insert(std::pair<std::string, std::string>(std::string("x.org.iotivity.ns.consumerid"),
                        std::string("123456789012345678901234567890123456")));
 
             try
             {
 
-                std::vector<std::string> rts{"oic.wk.notification"};
+                std::vector<std::string> rts{"x.org.iotivity.notification"};
 
                 m_msgResource
                     = OC::OCPlatform::constructResourceObject(
@@ -160,14 +160,14 @@ class NSConsumerSimulator
                        std::shared_ptr<OC::OCResource> )
         {
 
-            if (rep.getUri() == "/notification/message" && rep.hasAttribute("messageid")
-                && rep.getValue<int>("messageid") != 1)
+            if (rep.getUri() == "/notification/message" && rep.hasAttribute("x.org.iotivity.ns.messageid")
+                && rep.getValue<int>("x.org.iotivity.ns.messageid") != 1)
             {
-                m_messageFunc(int(rep.getValue<int>("messageid")),
-                              std::string(rep.getValueToString("title")),
-                              std::string(rep.getValueToString("contenttext")),
-                              std::string(rep.getValueToString("source")));
-                if (rep.getValue<int>("messageid") == 3)
+                m_messageFunc(int(rep.getValue<int>("x.org.iotivity.ns.messageid")),
+                              std::string(rep.getValueToString("x.org.iotivity.ns.title")),
+                              std::string(rep.getValueToString("x.org.iotivity.ns.contenttext")),
+                              std::string(rep.getValueToString(".x.org.iotivity.ns.source")));
+                if (rep.getValue<int>("x.org.iotivity.ns.messageid") == 3)
                 {
                     m_topicResource->get(OC::QueryParamsMap(),
                                          std::bind(&NSConsumerSimulator::onTopicGet, this, std::placeholders::_1,
@@ -177,7 +177,7 @@ class NSConsumerSimulator
             }
             else if (rep.getUri() == "/notification/sync")
             {
-                m_syncFunc(int(rep.getValue<int>("state")), int(rep.getValue<int>("messageid")));
+                m_syncFunc(int(rep.getValue<int>("x.org.iotivity.ns.state")), int(rep.getValue<int>("x.org.iotivity.ns.messageid")));
             }
         }
         void onTopicGet(const OC::HeaderOptions &/*headerOption*/,
index 295a35e..caa1502 100755 (executable)
@@ -39,7 +39,7 @@
 namespace
 {
     NSProviderSimulator g_providerSimul;
-    OIC::Service::NSProvider *g_provider;
+    std::shared_ptr<OIC::Service::NSProvider> g_provider;
 
     std::atomic_bool g_isStartedStack(false);
 
@@ -87,17 +87,17 @@ class NotificationServiceConsumerTest : public TestWithMock
         NotificationServiceConsumerTest() = default;
         ~NotificationServiceConsumerTest() = default;
 
-        static void ProviderDiscoveredCallbackEmpty( OIC::Service::NSProvider *)
+        static void ProviderDiscoveredCallbackEmpty( std::shared_ptr<OIC::Service::NSProvider> )
         {
             std::cout << __func__ << std::endl;
         }
 
-        static void NotificationReceivedCallbackEmpty( OIC::Service::NSMessage *)
+        static void NotificationReceivedCallbackEmpty( OIC::Service::NSMessage )
         {
             std::cout << __func__ << std::endl;
         }
 
-        static void SyncCallbackEmpty(OIC::Service::NSSyncInfo *)
+        static void SyncCallbackEmpty(OIC::Service::NSSyncInfo)
         {
             std::cout << __func__ << std::endl;
         }
@@ -164,7 +164,7 @@ TEST_F(NotificationServiceConsumerTest, StopConsumerPositive)
 TEST_F(NotificationServiceConsumerTest, DiscoverProviderWithNonAccepterWhenStartedConsumerFirst)
 {
     mocks.ExpectCallFunc(ProviderDiscoveredCallbackEmpty).Do(
-        [this]( OIC::Service::NSProvider * provider)
+        [this]( std::shared_ptr<OIC::Service::NSProvider> provider)
     {
         std::cout << "Call Discovered" << std::endl;
         std::cout << provider->getProviderId() << std::endl;
@@ -193,7 +193,7 @@ TEST_F(NotificationServiceConsumerTest, DiscoverProviderWithNonAccepterWhenStart
     }
 
     mocks.ExpectCallFunc(ProviderDiscoveredCallbackEmpty).Do(
-        [this]( OIC::Service::NSProvider * provider)
+        [this]( std::shared_ptr<OIC::Service::NSProvider> provider)
     {
         std::cout << "Call Discovered" << std::endl;
         g_provider = provider;
@@ -214,7 +214,7 @@ TEST_F(NotificationServiceConsumerTest, DiscoverProviderWithNonAccepterWhenResca
 {
     g_providerSimul.setAccepter((int)NSSelector::NS_SELECTION_CONSUMER);
     mocks.OnCallFunc(ProviderDiscoveredCallbackEmpty).Do(
-        [this]( OIC::Service::NSProvider * provider)
+        [this]( std::shared_ptr<OIC::Service::NSProvider> provider)
     {
         std::cout << "Call Discovered" << std::endl;
         g_provider = provider;
@@ -261,9 +261,9 @@ TEST_F(NotificationServiceConsumerTest, ExpectReceiveNotification)
     std::string msg = "msg";
 
     mocks.ExpectCallFunc(NotificationReceivedCallbackEmpty).Do(
-        [this]( OIC::Service::NSMessage message)
+        [this]( OIC::Service::NSMessage message)
     {
-        std::cout << "Income Notification : " << message->getMessageId() << std::endl;
+        std::cout << "Income Notification : " << message.getMessageId() << std::endl;
         responseCon.notify_all();
     });
 
@@ -280,7 +280,7 @@ TEST_F(NotificationServiceConsumerTest, DiscoverProviderWithAccepterisProvider)
     g_providerSimul.setAccepter((int)NSSelector::NS_SELECTION_PROVIDER);
 
     mocks.ExpectCallFunc(ProviderDiscoveredCallbackEmpty).Do(
-        [this]( OIC::Service::NSProvider * provider)
+        [this]( std::shared_ptr<OIC::Service::NSProvider> provider)
     {
         std::cout << "Call Discovered" << std::endl;
         g_provider = provider;
@@ -310,10 +310,10 @@ TEST_F(NotificationServiceConsumerTest, ExpectReceiveNotificationWithAccepterisP
     uint64_t revId = 1;
 
     mocks.OnCallFunc(NotificationReceivedCallbackEmpty).Do(
-        [this, & id, & revId](OIC::Service::NSMessage message)
+        [this, & id, & revId](OIC::Service::NSMessage message)
     {
-        std::cout << "Income Notification : " << message->getMessageId() << std::endl;
-        revId =  message->getMessageId();
+        std::cout << "Income Notification : " << message.getMessageId() << std::endl;
+        revId =  message.getMessageId();
         responseCon.notify_all();
     });
 
@@ -333,17 +333,17 @@ TEST_F(NotificationServiceConsumerTest, ExpectCallbackReadCheckWhenProviderNotif
     OIC::Service::NSSyncInfo::NSSyncType type = OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_DELETED;
 
     mocks.OnCallFunc(NotificationReceivedCallbackEmpty).Do(
-        [this]( OIC::Service::NSMessage message)
+        [this]( OIC::Service::NSMessage message)
     {
-        std::cout << "Income Notification : " << message->getMessageId() << std::endl;
+        std::cout << "Income Notification : " << message.getMessageId() << std::endl;
     });
 
     mocks.OnCallFunc(SyncCallbackEmpty).Do(
-        [& type, this](OIC::Service::NSSyncInfo sync)
+        [& type, this](OIC::Service::NSSyncInfo sync)
     {
-        std::cout << "Income SyncInfo : " << sync->getMessageId()
-                  << ", State : " << (int) sync->getState() << std::endl;
-        type = sync->getState();
+        std::cout << "Income SyncInfo : " << sync.getMessageId()
+                  << ", State : " << (int) sync.getState() << std::endl;
+        type = sync.getState();
         responseCon.notify_all();
     });
 
@@ -370,17 +370,17 @@ TEST_F(NotificationServiceConsumerTest, ExpectCallbackDismissCheckWhenProviderNo
     OIC::Service::NSSyncInfo::NSSyncType type = OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_READ;
 
     mocks.OnCallFunc(NotificationReceivedCallbackEmpty).Do(
-        [this]( OIC::Service::NSMessage message)
+        [this]( OIC::Service::NSMessage message)
     {
-        std::cout << "Income Notification : " << message->getMessageId() << std::endl;
+        std::cout << "Income Notification : " << message.getMessageId() << std::endl;
     });
 
     mocks.OnCallFunc(SyncCallbackEmpty).Do(
-        [& type, this](OIC::Service::NSSyncInfo sync)
+        [& type, this](OIC::Service::NSSyncInfo sync)
     {
-        std::cout << "Income Notification : " << sync->getMessageId()
-                  << ", State : " << (int) sync->getState() << std::endl;
-        type = sync->getState();
+        std::cout << "Income Notification : " << sync.getMessageId()
+                  << ", State : " << (int) sync.getState() << std::endl;
+        type = sync.getState();
         responseCon.notify_all();
     });
 
@@ -409,21 +409,21 @@ TEST_F(NotificationServiceConsumerTest, ExpectCallbackReadCheckWhenConsumerPostS
     ASSERT_NE(nullptr, g_provider) << "error: discovery failure";
 
     mocks.OnCallFunc(NotificationReceivedCallbackEmpty).Do(
-        [this]( OIC::Service::NSMessage message)
+        [this]( OIC::Service::NSMessage message)
     {
-        std::cout << "Income Notification : " << message->getMessageId() << std::endl;
-        g_provider->sendSyncInfo(message->getMessageId(),
+        std::cout << "Income Notification : " << message.getMessageId() << std::endl;
+        g_provider->sendSyncInfo(message.getMessageId(),
                                  OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_READ);
         std::unique_lock< std::mutex > lock { mutexForCondition };
         responseCon.wait_for(lock, g_waitForResponse);
     });
 
     mocks.OnCallFunc(SyncCallbackEmpty).Do(
-        [& type, this](OIC::Service::NSSyncInfo sync)
+        [& type, this](OIC::Service::NSSyncInfo sync)
     {
-        std::cout << "Income Notification : " << sync->getMessageId()
-                  << ", State : " << (int) sync->getState() << std::endl;
-        type = sync->getState();
+        std::cout << "Income Notification : " << sync.getMessageId()
+                  << ", State : " << (int) sync.getState() << std::endl;
+        type = sync.getState();
         responseCon.notify_all();
     });
 
@@ -446,21 +446,21 @@ TEST_F(NotificationServiceConsumerTest, ExpectCallbackDismissCheckWhenConsumerPo
     ASSERT_NE(nullptr, g_provider) << "error: discovery failure";
 
     mocks.OnCallFunc(NotificationReceivedCallbackEmpty).Do(
-        [this]( OIC::Service::NSMessage message)
+        [this]( OIC::Service::NSMessage message)
     {
-        std::cout << "Income Notification : " << message->getMessageId() << std::endl;
-        g_provider->sendSyncInfo(message->getMessageId(),
+        std::cout << "Income Notification : " << message.getMessageId() << std::endl;
+        g_provider->sendSyncInfo(message.getMessageId(),
                                  OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_DELETED);
         std::unique_lock< std::mutex > lock { mutexForCondition };
         responseCon.wait_for(lock, g_waitForResponse);
     });
 
     mocks.OnCallFunc(SyncCallbackEmpty).Do(
-        [& type, this](OIC::Service::NSSyncInfo sync)
+        [& type, this](OIC::Service::NSSyncInfo sync)
     {
-        std::cout << "Income Notification : " << sync->getMessageId()
-                  << ", State : " << (int) sync->getState() << std::endl;
-        type = sync->getState();
+        std::cout << "Income Notification : " << sync.getMessageId()
+                  << ", State : " << (int) sync.getState() << std::endl;
+        type = sync.getState();
         responseCon.notify_all();
     });
 
@@ -477,17 +477,20 @@ TEST_F(NotificationServiceConsumerTest, ExpectGetProviderSuccessWithValidProvide
 {
     ASSERT_NE(nullptr, g_provider) << "error: discovery failure";
 
-    OIC::Service::NSProvider *provider =
-        OIC::Service::NSConsumerService::getInstance()->getProvider(g_provider->getProviderId());
+    std::shared_ptr<OIC::Service::NSProvider> provider =
+        OIC::Service::NSConsumerService::getInstance()->getProvider(
+            g_provider->getProviderId());
     int ret = strcmp(provider->getProviderId().c_str(), g_provider->getProviderId().c_str());
     EXPECT_EQ(0, ret);
 }
 
 TEST_F(NotificationServiceConsumerTest, ExpectGetProviderSuccessWithInvalidProviderId)
 {
-    OIC::Service::NSProvider *provider =
-        OIC::Service::NSConsumerService::getInstance()->getProvider("123456789012345678901234567890123457");
-    EXPECT_EQ(provider, (void *)NULL);
+    std::shared_ptr<OIC::Service::NSProvider> provider =
+        OIC::Service::NSConsumerService::getInstance()->getProvider(
+            "123456789012345678901234567890123457");
+    bool res = (provider == nullptr);
+    EXPECT_EQ(res, 1);
 }
 
 TEST_F(NotificationServiceConsumerTest, ExpectCallbackTopicUpdated)
@@ -525,12 +528,12 @@ TEST_F(NotificationServiceConsumerTest, ExpectEQTopicList)
 
     ASSERT_NE(nullptr, g_provider) << "error: discovery failure";
 
-    std::list<OIC::Service::NSTopic *>  retTopic = g_provider->getTopicList()->getTopicsList();
+    auto  retTopic = g_provider->getTopicList()->getTopicsList();
     auto it1 = retTopic.begin();
     auto it2 = topics.begin();
     while ( it1 != retTopic.end() || it2 != topics.end() )
     {
-        if ((*it1)->getTopicName() !=  *it2)
+        if ((*it1).getTopicName() !=  *it2)
         {
             isSame = false; break;
         }
@@ -545,12 +548,15 @@ TEST_F(NotificationServiceConsumerTest, ExpectFailUpdateTopicOnConsumer)
 {
     ASSERT_NE(nullptr, g_provider) << "error: discovery failure";
 
-    OIC::Service::NSTopicsList *retTopic = g_provider->getTopicList();
+    auto retTopic = g_provider->getTopicList();
     for (auto it : retTopic->getTopicsList())
     {
-        it->setState(OIC::Service::NSTopic::NSTopicState::SUBSCRIBED);
+        std::cout << "Topic Name: " << it.getTopicName() << std::endl;
+        std::cout << "state : " << (int) it.getState() << std::endl;
+        it.setState(OIC::Service::NSTopic::NSTopicState::SUBSCRIBED);
     }
     OIC::Service::NSResult ret = g_provider->updateTopicList(retTopic);
+    std::cout << "ret : " << (int) ret << std::endl;
 
     EXPECT_EQ(OIC::Service::NSResult::ERROR, ret);
 }
index 5d515a3..d7dbee4 100755 (executable)
@@ -124,11 +124,11 @@ class NSProviderSimulator
                         std::string syncUri = m_notificationUri + m_syncUri;
                         std::string topicUri = m_notificationUri + m_topicUri;
                         std::string providerId = "123456789012345678901234567890123456";
-                        rep.setValue("subcontrollability", m_accepter);
-                        rep.setValue("messageuri", msgUri);
-                        rep.setValue("syncuri", syncUri);
-                        rep.setValue("topicuri", topicUri);
-                        rep.setValue("providerid", providerId);
+                        rep.setValue("x.org.iotivity.ns.subcontrollability", m_accepter);
+                        rep.setValue("x.org.iotivity.ns.messageuri", msgUri);
+                        rep.setValue("x.org.iotivity.ns.syncuri", syncUri);
+                        rep.setValue("x.org.iotivity.ns.topicuri", topicUri);
+                        rep.setValue("x.org.iotivity.ns.providerid", providerId);
                     }
                     else if (type == requestType::NS_SYNC)
                     {
@@ -158,14 +158,14 @@ class NSProviderSimulator
                                        [& topicArr](const NS_TopicState & topicState)
                         {
                             OC::OCRepresentation topic;
-                            topic.setValue("topicname", topicState.first);
-                            topic.setValue("topicstate", (int) topicState.second);
+                            topic.setValue("x.org.iotivity.ns.topicname", topicState.first);
+                            topic.setValue("x.org.iotivity.ns.topicstate", (int) topicState.second);
                             topicArr.push_back(topic);
                         }
                                       );
 
                         rep.setValue<std::vector<OC::OCRepresentation>>
-                                ("topiclist", topicArr);
+                                ("x.org.iotivity.ns.topiclist", topicArr);
                     }
                     else
                     {
@@ -183,8 +183,8 @@ class NSProviderSimulator
                         m_syncRep = requests->getResourceRepresentation();
 
                         std::cout << "Receive POST for Sync" << std::endl;
-                        std::cout << "provider Id : " << m_syncRep.getValueToString("providerid") << std::endl;
-                        std::cout << "Sync State : " << m_syncRep.getValueToString("state") << std::endl;
+                        std::cout << "provider Id : " << m_syncRep.getValueToString("x.org.iotivity.ns.providerid") << std::endl;
+                        std::cout << "Sync State : " << m_syncRep.getValueToString("x.org.iotivity.ns.state") << std::endl;
 
                         response->setResourceRepresentation(m_syncRep);
 
@@ -196,15 +196,15 @@ class NSProviderSimulator
                     {
                         auto receivePayload =
                             requests->getResourceRepresentation()
-                            .getValue<std::vector<OC::OCRepresentation>>("topiclist");
+                            .getValue<std::vector<OC::OCRepresentation>>("x.org.iotivity.ns.topiclist");
 
                         std::for_each (receivePayload.begin(), receivePayload.end(),
                                        [this](const OC::OCRepresentation & rep)
                         {
-                            auto tmp = m_allowedTopicList.find(rep.getValueToString("topicname"));
+                            auto tmp = m_allowedTopicList.find(rep.getValueToString("x.org.iotivity.ns.topicname"));
                             if (tmp != m_allowedTopicList.end())
                             {
-                                tmp->second = (TopicAllowState) rep.getValue<int>("topicstate");
+                                tmp->second = (TopicAllowState) rep.getValue<int>("x.org.iotivity.ns.topicstate");
                             }
                         }
                                       );
@@ -235,8 +235,8 @@ class NSProviderSimulator
             {
                 OC::OCRepresentation rep;
                 std::string providerId = "123456789012345678901234567890123456";
-                rep.setValue<int>("messageid", (int)messageType::NS_ALLOW);
-                rep.setValue("providerid", providerId);
+                rep.setValue<int>("x.org.iotivity.ns.messageid", (int)messageType::NS_ALLOW);
+                rep.setValue("x.org.iotivity.ns.providerid", providerId);
 
                 auto response = std::make_shared<OC::OCResourceResponse>();
                 response->setRequestHandle(requests->getRequestHandle());
@@ -308,27 +308,27 @@ class NSProviderSimulator
         void sendRead(const uint64_t &id)
         {
             std::string providerId = "123456789012345678901234567890123456";
-            m_syncRep.setValue<int>("messageid", id);
-            m_syncRep.setValue("state", (int)1);
-            m_syncRep.setValue("providerid", providerId);
+            m_syncRep.setValue<int>("x.org.iotivity.ns.messageid", id);
+            m_syncRep.setValue("x.org.iotivity.ns.state", (int)1);
+            m_syncRep.setValue("x.org.iotivity.ns.providerid", providerId);
             OC::OCPlatform::notifyAllObservers(m_syncHandle);
         }
         void sendDismiss(const uint64_t &id)
         {
             std::string providerId = "123456789012345678901234567890123456";
-            m_syncRep.setValue<int>("messageid", id);
-            m_syncRep.setValue("state", (int)2);
-            m_syncRep.setValue("providerid", providerId);
+            m_syncRep.setValue<int>("x.org.iotivity.ns.messageid", id);
+            m_syncRep.setValue("x.org.iotivity.ns.state", (int)2);
+            m_syncRep.setValue("x.org.iotivity.ns.providerid", providerId);
             OC::OCPlatform::notifyAllObservers(m_syncHandle);
         }
 
         void setMessage(const uint64_t &id, const std::string &title, const std::string &content)
         {
             std::string providerId = "123456789012345678901234567890123456";
-            m_messageRep.setValue<int>("messageid", id);
-            m_messageRep.setValue("title", title);
-            m_messageRep.setValue("contenttext", content);
-            m_messageRep.setValue("providerid", providerId);
+            m_messageRep.setValue<int>("x.org.iotivity.ns.messageid", id);
+            m_messageRep.setValue("x.org.iotivity.ns.title", title);
+            m_messageRep.setValue("x.org.iotivity.ns.contenttext", content);
+            m_messageRep.setValue("x.org.iotivity.ns.providerid", providerId);
         }
 
         void setTopics(const NS_TopicList &topics)
@@ -400,7 +400,7 @@ class NSProviderSimulator
             OC::OCPlatform::startPresence(30);
 
             std::string notificationUri = m_notificationUri;
-            std::string resourceTypeName = "oic.wk.notification.topic";
+            std::string resourceTypeName = "x.org.iotivity.notification.topic";
             std::string resourceInterface = OC::DEFAULT_INTERFACE;
 
             uint8_t resourceProperty = OC_OBSERVABLE;
@@ -420,7 +420,7 @@ class NSProviderSimulator
             }
 
             //resourceProperty |= OC_OBSERVABLE;
-            resourceTypeName = "oic.wk.notification.message";
+            resourceTypeName = "x.org.iotivity.notification.message";
             childUri = uri + m_messageUri;
             try
             {
@@ -436,7 +436,7 @@ class NSProviderSimulator
                 std::cout << e.what() << std::endl;
             }
 
-            resourceTypeName = "oic.wk.notification.sync";
+            resourceTypeName = "x.org.iotivity.notification.sync";
             childUri = uri + m_syncUri;
             try
             {
@@ -453,7 +453,7 @@ class NSProviderSimulator
             }
 
             resourceProperty |= OC_DISCOVERABLE;
-            resourceTypeName = "oic.wk.notification";
+            resourceTypeName = "x.org.iotivity.notification";
             try
             {
                 OC::OCPlatform::registerResource(
index 215359a..7b6cd1c 100755 (executable)
@@ -43,7 +43,7 @@ namespace
     std::mutex mutexForCondition;
 
     NSConsumerSimulator g_consumerSimul;
-    OIC::Service::NSConsumer *g_consumer;
+    std::shared_ptr<OIC::Service::NSConsumer> g_consumer;
 }
 
 class TestWithMock: public testing::Test
@@ -76,12 +76,12 @@ class NotificationProviderServiceTest : public TestWithMock
         NotificationProviderServiceTest() = default;
         ~NotificationProviderServiceTest() = default;
 
-        static void ConsumerSubscribedCallbackEmpty(OIC::Service::NSConsumer *)
+        static void ConsumerSubscribedCallbackEmpty(std::shared_ptr<OIC::Service::NSConsumer> )
         {
             std::cout << __func__ << std::endl;
         }
 
-        static void MessageSynchronizedCallbackEmpty(OIC::Service::NSSyncInfo *)
+        static void MessageSynchronizedCallbackEmpty(OIC::Service::NSSyncInfo)
         {
             std::cout << __func__ << std::endl;
         }
@@ -173,7 +173,7 @@ TEST_F(NotificationProviderServiceTest,
 {
     g_consumer = NULL;
     mocks.ExpectCallFunc(ConsumerSubscribedCallbackEmpty).Do(
-        []( OIC::Service::NSConsumer * consumer)
+        []( std::shared_ptr<OIC::Service::NSConsumer> consumer)
     {
         std::cout << "ConsumerSubscribedCallbackEmpty" << std::endl;
         g_consumer = consumer;
@@ -222,12 +222,11 @@ TEST_F(NotificationProviderServiceTest, NeverCallNotifyOnConsumerByAcceptIsFalse
     ASSERT_NE(nullptr, g_consumer) << "error: discovery failure";
 
     g_consumer->acceptSubscription(false);
-
-    OIC::Service::NSMessage *msg =  OIC::Service::NSProviderService::getInstance()->createMessage();
-    msgID = (int)msg->getMessageId();
-    msg->setTitle(std::string("Title"));
-    msg->setContentText(std::string("ContentText"));
-    msg->setSourceName(std::string("OCF"));
+    OIC::Service::NSMessage msg =  OIC::Service::NSProviderService::getInstance()->createMessage();
+    msgID = (int)msg.getMessageId();
+    msg.setTitle(std::string("Title"));
+    msg.setContentText(std::string("ContentText"));
+    msg.setSourceName(std::string("OCF"));
 
     OIC::Service::NSProviderService::getInstance()->sendMessage(msg);
     {
@@ -238,8 +237,6 @@ TEST_F(NotificationProviderServiceTest, NeverCallNotifyOnConsumerByAcceptIsFalse
     std::unique_lock< std::mutex > lock { mutexForCondition };
     responseCon.wait_for(lock, g_waitForResponse);
 
-    delete msg;
-
     EXPECT_EQ(expectTrue, true);
 }
 
@@ -261,17 +258,16 @@ TEST_F(NotificationProviderServiceTest, ExpectCallNotifyOnConsumerByAcceptIsTrue
 
     g_consumer->acceptSubscription(true);
 
-    OIC::Service::NSMessage *msg =  OIC::Service::NSProviderService::getInstance()->createMessage();
-    msgID = (int)msg->getMessageId();
-    msg->setTitle(std::string("Title"));
-    msg->setContentText(std::string("ContentText"));
-    msg->setSourceName(std::string("OCF"));
+    OIC::Service::NSMessage msg =  OIC::Service::NSProviderService::getInstance()->createMessage();
+    msgID = (int)msg.getMessageId();
+    msg.setTitle(std::string("Title"));
+    msg.setContentText(std::string("ContentText"));
+    msg.setSourceName(std::string("OCF"));
 
     OIC::Service::NSProviderService::getInstance()->sendMessage(msg);
     std::unique_lock< std::mutex > lock { mutexForCondition };
     responseCon.wait_for(lock, g_waitForResponse);
 
-    delete msg;
 }
 
 TEST_F(NotificationProviderServiceTest, ExpectCallbackSyncOnReadToConsumer)
@@ -290,18 +286,16 @@ TEST_F(NotificationProviderServiceTest, ExpectCallbackSyncOnReadToConsumer)
         }
     });
 
-    OIC::Service::NSMessage *msg =  OIC::Service::NSProviderService::getInstance()->createMessage();
-    id = (int)msg->getMessageId();
-    msg->setTitle(std::string("Title"));
-    msg->setContentText(std::string("ContentText"));
-    msg->setSourceName(std::string("OCF"));
+    OIC::Service::NSMessage msg =  OIC::Service::NSProviderService::getInstance()->createMessage();
+    id = (int)msg.getMessageId();
+    msg.setTitle(std::string("Title"));
+    msg.setContentText(std::string("ContentText"));
+    msg.setSourceName(std::string("OCF"));
 
-    OIC::Service::NSProviderService::getInstance()->sendSyncInfo(msg->getMessageId(),
+    OIC::Service::NSProviderService::getInstance()->sendSyncInfo(msg.getMessageId(),
             OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_READ);
     std::unique_lock< std::mutex > lock { mutexForCondition };
     responseCon.wait_for(lock, g_waitForResponse);
-
-    delete msg;
 }
 
 TEST_F(NotificationProviderServiceTest, ExpectCallbackSyncOnReadFromConsumer)
@@ -309,27 +303,25 @@ TEST_F(NotificationProviderServiceTest, ExpectCallbackSyncOnReadFromConsumer)
     int type = (int)OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_READ;
     int id = 0;
     mocks.ExpectCallFunc(MessageSynchronizedCallbackEmpty).Do(
-        [& id](OIC::Service::NSSyncInfo sync)
+        [& id](OIC::Service::NSSyncInfo sync)
     {
         std::cout << "MessageSynchronizedCallbackEmpty" << std::endl;
-        if ((int)sync->getMessageId() == id
-            && sync->getState() == OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_READ)
+        if ((int)sync.getMessageId() == id
+            && sync.getState() == OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_READ)
         {
             std::cout << "ExpectCallbackSyncOnReadFromConsumer" << std::endl;
             responseCon.notify_all();
         }
     });
 
-    OIC::Service::NSMessage *msg =  OIC::Service::NSProviderService::getInstance()->createMessage();
-    id = (int)msg->getMessageId();
-    msg->setTitle(std::string("Title"));
-    msg->setContentText(std::string("ContentText"));
-    msg->setSourceName(std::string("OCF"));
-    g_consumerSimul.syncToProvider(type, id, msg->getProviderId());
+    OIC::Service::NSMessage msg =  OIC::Service::NSProviderService::getInstance()->createMessage();
+    id = (int)msg.getMessageId();
+    msg.setTitle(std::string("Title"));
+    msg.setContentText(std::string("ContentText"));
+    msg.setSourceName(std::string("OCF"));
+    g_consumerSimul.syncToProvider(type, id, msg.getProviderId());
     std::unique_lock< std::mutex > lock { mutexForCondition };
     responseCon.wait(lock);
-
-    delete msg;
 }
 
 TEST_F(NotificationProviderServiceTest, ExpectEqualAddedTopicsAndRegisteredTopics)
@@ -341,7 +333,7 @@ TEST_F(NotificationProviderServiceTest, ExpectEqualAddedTopicsAndRegisteredTopic
     std::unique_lock< std::mutex > lock { mutexForCondition };
     responseCon.wait_for(lock, g_waitForResponse);
     bool isSame = false;
-    OIC::Service::NSTopicsList *topicList =
+    auto topicList =
         OIC::Service::NSProviderService::getInstance()->getRegisteredTopicList();
     if (!topicList)
     {
@@ -354,7 +346,7 @@ TEST_F(NotificationProviderServiceTest, ExpectEqualAddedTopicsAndRegisteredTopic
         int i = 0;
         for (auto itr : topicList->getTopicsList())
         {
-            compString[i] = itr->getTopicName(); i++;
+            compString[i] = itr.getTopicName(); i++;
         }
         std::cout << compString[0] << std::endl;
         std::cout << compString[1] << std::endl;
@@ -367,10 +359,6 @@ TEST_F(NotificationProviderServiceTest, ExpectEqualAddedTopicsAndRegisteredTopic
 
     OIC::Service::NSProviderService::getInstance()->unregisterTopic(str1);
     OIC::Service::NSProviderService::getInstance()->unregisterTopic(str2);
-    if (topicList != nullptr)
-    {
-        delete topicList;
-    }
     responseCon.wait_for(lock, g_waitForResponse);
 }
 
@@ -384,7 +372,7 @@ TEST_F(NotificationProviderServiceTest, ExpectEqualUnregisteredTopicsAndRegister
     std::unique_lock< std::mutex > lock { mutexForCondition };
     responseCon.wait_for(lock, g_waitForResponse);
     bool isSame = false;
-    OIC::Service::NSTopicsList *topicList =
+    auto topicList =
         OIC::Service::NSProviderService::getInstance()->getRegisteredTopicList();
     if (!topicList)
     {
@@ -393,8 +381,9 @@ TEST_F(NotificationProviderServiceTest, ExpectEqualUnregisteredTopicsAndRegister
     }
     else
     {
-        std::list<OIC::Service::NSTopic *>::iterator it = topicList->getTopicsList().begin();
-        std::string compStr = (*it)->getTopicName() ;
+        auto topic = topicList->getTopicsList();
+        auto it = topic.begin();
+        std::string compStr = (*it).getTopicName() ;
         std::cout << compStr << std::endl;
         if (str1.compare(compStr) == 0 )
         {
@@ -404,10 +393,6 @@ TEST_F(NotificationProviderServiceTest, ExpectEqualUnregisteredTopicsAndRegister
     EXPECT_EQ(isSame, true);
 
     OIC::Service::NSProviderService::getInstance()->unregisterTopic(str1);
-    if (topicList != nullptr)
-    {
-        delete topicList;
-    }
     responseCon.wait_for(lock, g_waitForResponse);
 }
 
@@ -426,7 +411,7 @@ TEST_F(NotificationProviderServiceTest, ExpectEqualSetConsumerTopicsAndGetConsum
     responseCon.wait_for(lock, g_waitForResponse);
 
     bool isSame = false;
-    OIC::Service::NSTopicsList *topicList =  g_consumer->getConsumerTopicList();
+    auto topicList =  g_consumer->getConsumerTopicList();
 
     if (!topicList)
     {
@@ -439,8 +424,8 @@ TEST_F(NotificationProviderServiceTest, ExpectEqualSetConsumerTopicsAndGetConsum
         int i = 0, state[10] = {0};
         for (auto itr : topicList->getTopicsList())
         {
-            compString[i] = itr->getTopicName();
-            state[i++] = (int) itr->getState();
+            compString[i] = itr.getTopicName();
+            state[i++] = (int) itr.getState();
         }
         std::cout << compString[0] << std::endl;
         std::cout << compString[1] << std::endl;
@@ -455,10 +440,6 @@ TEST_F(NotificationProviderServiceTest, ExpectEqualSetConsumerTopicsAndGetConsum
 
     OIC::Service::NSProviderService::getInstance()->unregisterTopic(str1);
     OIC::Service::NSProviderService::getInstance()->unregisterTopic(str2);
-    if (topicList != nullptr)
-    {
-        delete topicList;
-    }
     responseCon.wait_for(lock, g_waitForResponse);
 }
 
@@ -479,7 +460,7 @@ TEST_F(NotificationProviderServiceTest, ExpectEqualUnSetConsumerTopicsAndGetCons
     responseCon.wait_for(lock, g_waitForResponse);
 
     bool isSame = false;
-    OIC::Service::NSTopicsList *topicList =  g_consumer->getConsumerTopicList();
+    auto topicList =  g_consumer->getConsumerTopicList();
 
     if (!topicList)
     {
@@ -492,8 +473,8 @@ TEST_F(NotificationProviderServiceTest, ExpectEqualUnSetConsumerTopicsAndGetCons
         int i = 0, state[10] = {0};
         for (auto itr : topicList->getTopicsList())
         {
-            compString[i] = itr->getTopicName();
-            state[i++] = (int) itr->getState();
+            compString[i] = itr.getTopicName();
+            state[i++] = (int) itr.getState();
         }
         std::cout << compString[0] << std::endl;
         std::cout << compString[1] << std::endl;
@@ -508,21 +489,9 @@ TEST_F(NotificationProviderServiceTest, ExpectEqualUnSetConsumerTopicsAndGetCons
 
     OIC::Service::NSProviderService::getInstance()->unregisterTopic(str1);
     OIC::Service::NSProviderService::getInstance()->unregisterTopic(str2);
-
-    if (topicList != nullptr)
-    {
-        delete topicList;
-    }
     responseCon.wait_for(lock, g_waitForResponse);
 }
 
-TEST_F(NotificationProviderServiceTest, ExpectFailSendMessage)
-{
-    OIC::Service::NSResult result = OIC::Service::NSResult::OK;
-    result = OIC::Service::NSProviderService::getInstance()->sendMessage(nullptr);
-
-    EXPECT_EQ(result, OIC::Service::NSResult::ERROR);
-}
 
 TEST_F(NotificationProviderServiceTest, CancelObserves)
 {
index 30e3328..bc3e301 100644 (file)
@@ -54,7 +54,7 @@ GTest_Main = File(gtest_dir + '/lib/.libs/libgtest_main.a')
 
 notification_wrapper_test_env.AppendUnique(LIBPATH = [lib_env.get('BUILD_DIR')])
 notification_wrapper_test_env.AppendUnique(LIBS = [
-    'connectivity_abstraction', 'oc', 'octbstack', 'oc_logger', 'coap', 
+    'connectivity_abstraction', 'oc', 'octbstack', 'oc_logger', 'coap', 'resource_directory',
     GTest_Main, GTest])
 
 if env.get('WITH_TCP') == True:
index e78f569..4d7890c 100644 (file)
@@ -77,7 +77,7 @@ jdk_env['BUILDERS']['Gradle'] = Builder(action = env.get('ANDROID_GRADLE') +
     emitter = ensure_libs)
 jdk_env['BUILD_DIR'] = env.get('BUILD_DIR')
 cmdBuildNotificationConsumerApp=jdk_env.Gradle(target="app/apk", 
-    source=["app/src/main/java/com/sec/noticonsumerexample/MainActivity.java",
-            "app/src/main/java/com/sec/noticonsumerexample/ConsumerSample.java"])
-
+    source=["app/src/main/java/org/iotivity/service/ns/sample/consumer/MainActivity.java",
+            "app/src/main/java/org/iotivity/service/ns/sample/consumer/ConsumerSample.java"])
+jdk_env.Clean(cmdBuildNotificationConsumerApp, '#/service/notification/examples/android/NotiConsumerExample/build')
 Depends(cmdBuildNotificationConsumerApp, env.get('notificationAAR'))
index 7e6dd9c..8c061d4 100755 (executable)
@@ -10,6 +10,11 @@ android {
         pickFirst 'lib/x86/libocstack-jni.so'
         pickFirst 'lib/x86_64/libocstack-jni.so'
         pickFirst 'lib/arm64-v8a/libocstack-jni.so'
+        pickFirst 'lib/armeabi/libresource_directory.so'
+        pickFirst 'lib/armeabi-v7a/libresource_directory.so'
+        pickFirst 'lib/x86/libresource_directory.so'
+        pickFirst 'lib/x86_64/libresource_directory.so'
+        pickFirst 'lib/arm64-v8a/libresource_directory.so'
     }
 
     defaultConfig {
diff --git a/service/notification/examples/android/NotiConsumerExample/app/src/androidTest/java/org/iotivity/service/ns/sample/consumer/ExampleUnitTest.java b/service/notification/examples/android/NotiConsumerExample/app/src/androidTest/java/org/iotivity/service/ns/sample/consumer/ExampleUnitTest.java
new file mode 100755 (executable)
index 0000000..11ef47a
--- /dev/null
@@ -0,0 +1,574 @@
+/*
+* Copyright 2016 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.
+*/
+
+package org.iotivity.service.ns.sample.consumer;
+
+import android.app.Application;
+import android.content.Context;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.ApplicationTestCase;
+import android.util.Log;
+
+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 org.iotivity.service.ns.common.Message;
+import org.iotivity.service.ns.common.NSException;
+import org.iotivity.service.ns.common.NSErrorCode;
+import org.iotivity.service.ns.common.Topic;
+import org.iotivity.service.ns.common.TopicsList;
+import org.iotivity.service.ns.common.SyncInfo;
+import org.iotivity.service.ns.consumer.ConsumerService;
+import org.iotivity.service.ns.provider.ProviderService;
+import org.iotivity.service.ns.consumer.Provider;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Iterator;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * To work on unit tests, switch the Test Artifact in the Build Variants view.
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleUnitTest extends ApplicationTestCase<Application> {
+    public ExampleUnitTest() {
+        super(Application.class);
+    }
+
+    private static Context                   mContext = null;
+    private ProviderService                  gProviderRes;
+    private ProviderSimulator                gProviderSimul;
+    private static ConsumerService           gConsumerRes;
+    private static DiscoveryCallbackListener disCb;
+    private static ProviderCallbackListener  provCb;
+    CountDownLatch                           lockObject;
+    Response                                 response;
+    private static String                    TAG      = "ConsumerExample UnitTest";
+
+    public void startBefore(boolean subControllability) {
+        Log.i(TAG, "startConsumerBefore - IN");
+        try {
+            gConsumerRes.start(disCb);
+            gProviderRes.start(gProviderSimul, gProviderSimul,
+                    subControllability, "nothing", false);
+            lockObject.await(4000, TimeUnit.MILLISECONDS);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        Log.i(TAG, "startConsumerBefore - OUT");
+    }
+
+    public void startAfter(boolean subControllability) {
+        Log.i(TAG, "startConsumerAfter - IN");
+        try {
+            gProviderRes.start(gProviderSimul, gProviderSimul,
+                    subControllability, "nothing", false);
+            gConsumerRes.start(disCb);
+            lockObject.await(4000, TimeUnit.MILLISECONDS);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        Log.i(TAG, "startConsumerAfter - OUT");
+    }
+
+    public void setListener(Provider mProvider) {
+        try {
+            mProvider.setListener(provCb, provCb, provCb);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void subscribe(Provider.ProviderState state) {
+        lockObject = new CountDownLatch(1);
+        response = new Response();
+        provCb.set(lockObject, response);
+        provCb.setState(state);
+        Provider mProvider = disCb.getProvider();
+        setListener(mProvider);
+        try {
+            if (!mProvider.isSubscribed()) {
+                Log.i(TAG, "not subscribed");
+                mProvider.subscribe();
+            }
+            lockObject.await(4000, TimeUnit.MILLISECONDS);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+    public void unsubscribe() {
+        lockObject = new CountDownLatch(1);
+        response = new Response();
+        provCb.set(lockObject, response);
+        provCb.setState(Provider.ProviderState.STOPPED);
+        Provider mProvider = disCb.getProvider();
+        setListener(mProvider);
+        try {
+            if (mProvider.isSubscribed()) {
+                Log.i(TAG, "subscribed");
+                mProvider.unsubscribe();
+            }
+            lockObject.await(4000, TimeUnit.MILLISECONDS);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public long sendMessage() {
+        lockObject = new CountDownLatch(1);
+        response = new Response();
+        provCb.set(lockObject, response);
+        org.iotivity.service.ns.common.Message msg = gProviderSimul
+                .getMessage();
+        long Id = msg.getMessageId();
+        provCb.setId(Id);
+        try {
+            gProviderRes.sendMessage(msg);
+            lockObject.await(4000, TimeUnit.MILLISECONDS);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return Id;
+    }
+
+    public void sendSyncInfo(long id, SyncInfo.SyncType type) {
+        try {
+            lockObject = new CountDownLatch(1);
+            response = new Response();
+            provCb.set(lockObject, response);
+            provCb.setType(type);
+            gProviderRes.sendSyncInfo(id, type);
+            lockObject.await(4000, TimeUnit.MILLISECONDS);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void providerSendSyncInfo(Provider provider, long id,
+            SyncInfo.SyncType type) {
+        try {
+            lockObject = new CountDownLatch(1);
+            response = new Response();
+            provCb.set(lockObject, response);
+            provCb.setType(type);
+            provider.sendSyncInfo(id, type);
+            lockObject.await(4000, TimeUnit.MILLISECONDS);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void registerTopic(String topic) {
+        lockObject = new CountDownLatch(1);
+        response = new Response();
+        provCb.set(lockObject, response);
+        provCb.setState(Provider.ProviderState.TOPIC);
+        try {
+            gProviderRes.registerTopic(topic);
+            lockObject.await(4000, TimeUnit.MILLISECONDS);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    @BeforeClass
+    public static void Initialize() {
+        PlatformConfig platformConfig = new PlatformConfig(mContext,
+                ServiceType.IN_PROC, ModeType.CLIENT_SERVER, "0.0.0.0",
+                0, // Uses randomly available port
+                QualityOfService.LOW);
+
+        OcPlatform.Configure(platformConfig);
+        try {
+            OcPlatform.stopPresence(); // Initialize OcPlatform
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Before
+    public void SetUp() {
+        Log.i(TAG, "SetUp - IN");
+        disCb = new DiscoveryCallbackListener();
+        provCb = new ProviderCallbackListener();
+        gConsumerRes = ConsumerService.getInstance();
+        gProviderRes = ProviderService.getInstance();
+        gProviderSimul = new ProviderSimulator();
+        lockObject = new CountDownLatch(1);
+        response = new Response();
+        disCb.set(lockObject, response);
+        Log.i(TAG, "SetUp - OUT");
+    }
+
+    @After
+    public void TearDown() {
+        Log.i(TAG, "TearDown - IN");
+        try {
+            gConsumerRes.stop();
+            gProviderRes.stop();
+            lockObject = new CountDownLatch(1);
+            lockObject.await(2000, TimeUnit.MILLISECONDS);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        Log.i(TAG, "TearDown - OUT");
+    }
+
+    @Test
+    public void DiscoverProviderWithNonAccepterWhenStartedConsumerFirst() {
+        startBefore(false);
+        assertEquals(true, response.get());
+    }
+
+    @Test
+    public void DiscoverProviderWithNonAccepterWhenStartedConsumerAfter() {
+        startAfter(false);
+        assertEquals(true, response.get());
+    }
+
+    @Test
+    public void DiscoverProviderWithNonAccepterWhenRescan() {
+        startAfter(false);
+        assertEquals(true, response.get());
+        try {
+            gConsumerRes.rescanProvider();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        assertEquals(true, response.get());
+    }
+
+    @Test
+    public void ExpectSubscribeSuccess() {
+        startAfter(false);
+        assertEquals(true, response.get());
+
+        Provider.ProviderState state = Provider.ProviderState.ALLOW;
+        subscribe(state);
+        assertEquals(true, response.get());
+    }
+    @Test
+    public void ExpectUnSubscribeSuccess() {
+        startAfter(false);
+        assertEquals(true, response.get());
+
+        Provider.ProviderState state = Provider.ProviderState.ALLOW;
+        subscribe(state);
+        assertEquals(true, response.get());
+        unsubscribe();
+        assertEquals(true, response.get());
+    }
+    @Test
+    public void ExpectReceiveNotification() {
+        startAfter(false);
+        assertEquals(true, response.get());
+
+        Provider.ProviderState state = Provider.ProviderState.ALLOW;
+        subscribe(state);
+        assertEquals(true, response.get());
+
+        sendMessage();
+        assertEquals(true, response.get());
+
+    }
+
+    @Test
+    public void DiscoverProviderWithAccepterisProvider() {
+        startAfter(true);
+        assertEquals(true, response.get());
+    }
+
+    @Test
+    public void ExpectReceiveNotificationWithAccepterisProvider() {
+        startAfter(true);
+        assertEquals(true, response.get());
+
+        Provider mProvider = disCb.getProvider();
+        setListener(mProvider);
+
+        sendMessage();
+        assertEquals(true, response.get());
+    }
+
+    @Test
+    public void ExpectCallbackReadCheckWhenProviderNotifySync() {
+        startAfter(true);
+        assertEquals(true, response.get());
+
+        Provider mProvider = disCb.getProvider();
+        setListener(mProvider);
+
+        long id = sendMessage();
+        assertEquals(true, response.get());
+
+        sendSyncInfo(id, SyncInfo.SyncType.READ);
+        assertEquals(true, response.get());
+    }
+
+    @Test
+    public void ExpectCallbackDismissCheckWhenProviderNotifySync() {
+        startAfter(true);
+        assertEquals(true, response.get());
+
+        Provider mProvider = disCb.getProvider();
+        setListener(mProvider);
+
+        long id = sendMessage();
+        assertEquals(true, response.get());
+
+        sendSyncInfo(id, SyncInfo.SyncType.DELETED);
+        assertEquals(true, response.get());
+    }
+
+    @Test
+    public void ExpectCallbackReadCheckWhenConsumerPostSync() {
+        startAfter(true);
+        assertEquals(true, response.get());
+
+        Provider mProvider = disCb.getProvider();
+        setListener(mProvider);
+
+        long id = sendMessage();
+        assertEquals(true, response.get());
+
+        providerSendSyncInfo(mProvider, id, SyncInfo.SyncType.READ);
+        assertEquals(true, response.get());
+    }
+
+    @Test
+    public void ExpectCallbackDismissCheckWhenConsumerPostSync() {
+        startAfter(true);
+        assertEquals(true, response.get());
+
+        Provider mProvider = disCb.getProvider();
+        setListener(mProvider);
+
+        long id = sendMessage();
+        assertEquals(true, response.get());
+
+        providerSendSyncInfo(mProvider, id, SyncInfo.SyncType.DELETED);
+        assertEquals(true, response.get());
+    }
+
+    @Test
+    public void ExpectCallbackTopicUpdated() {
+        startAfter(true);
+        assertEquals(true, response.get());
+
+        Provider mProvider = disCb.getProvider();
+        setListener(mProvider);
+
+        registerTopic("OIC_TOPIC1");
+        assertEquals(true, response.get());
+    }
+
+    @Test
+    public void ExpectEQTopicList() {
+        startAfter(true);
+        assertEquals(true, response.get());
+
+        Provider mProvider = disCb.getProvider();
+        setListener(mProvider);
+
+        try {
+            registerTopic("OIC_TOPIC1");
+            assertEquals(true, response.get());
+            registerTopic("OIC_TOPIC2");
+            assertEquals(true, response.get());
+            registerTopic("OIC_TOPIC3");
+            assertEquals(true, response.get());
+
+            response = new Response();
+            Iterator<Topic> it = mProvider.getTopicList().getTopicsList()
+                    .iterator();
+            Iterator<Topic> it2 = gProviderRes.getRegisteredTopicList()
+                    .getTopicsList().iterator();
+            while (it.hasNext()) {
+                Topic element = it.next();
+                Topic element2 = it2.next();
+                Log.i(TAG, element2.getTopicName());
+                if (!element.getTopicName().equals(element2.getTopicName())) {
+                    response.set(false);
+                    break;
+                }
+                response.set(true);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        assertEquals(true, response.get());
+    }
+
+    @Test
+    public void ExpectFailUpdateTopicOnConsumer() {
+        startAfter(true);
+        assertEquals(true, response.get());
+
+        Provider mProvider = disCb.getProvider();
+        setListener(mProvider);
+
+        registerTopic("OIC_TOPIC1");
+        assertEquals(true, response.get());
+
+        try {
+            TopicsList list = mProvider.getTopicList();
+            Iterator<Topic> it = list.getTopicsList().iterator();
+            while (it.hasNext()) {
+                Topic element = it.next();
+                element.setState(Topic.TopicState.SUBSCRIBED);
+            }
+            mProvider.updateTopicList(list);
+        } catch (NSException e) {
+            e.printStackTrace();
+            assertEquals(NSErrorCode.ERROR, e.getErrorCode());
+        }
+    }
+
+    @Test
+    public void ExpectCallbackStoppedProvider() {
+        startAfter(true);
+        assertEquals(true, response.get());
+
+        Provider mProvider = disCb.getProvider();
+        setListener(mProvider);
+
+        lockObject = new CountDownLatch(1);
+        response = new Response();
+        provCb.set(lockObject, response);
+        provCb.setState(Provider.ProviderState.STOPPED);
+
+        try {
+            gProviderRes.stop();
+            lockObject.await(4000, TimeUnit.MILLISECONDS);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        assertEquals(true, response.get());
+
+    }
+}
+
+class DiscoveryCallbackListener
+        implements ConsumerService.OnProviderDiscoveredListener {
+    private CountDownLatch mLockObject;
+    private Response       mResponse;
+    private Provider       mProvider;
+    private static String  TAG = "UnitTest DiscoveryCallbackListener";
+
+    public void set(CountDownLatch lockObject, Response response) {
+        mLockObject = lockObject;
+        mResponse = response;
+    }
+
+    public Provider getProvider() {
+        return mProvider;
+    }
+
+    @Override
+    public void onProviderDiscovered(Provider provider) {
+        Log.i(TAG, provider.getProviderId());
+        mProvider = provider;
+        if (mResponse != null) {
+            Log.i(TAG, "onProviderDiscovered: Lock released");
+            mResponse.set(true);
+            mLockObject.countDown();
+        }
+    }
+}
+
+class ProviderCallbackListener implements Provider.OnProviderStateListener,
+        Provider.OnMessageReceivedListener, Provider.OnSyncInfoReceivedListener {
+
+    private CountDownLatch         mLockObject;
+    private Response               mResponse;
+    private Provider.ProviderState mState;
+    private SyncInfo.SyncType      mType;
+    private long                   mId;
+    private static String          TAG = "UnitTest ProviderCallbackListener";
+
+    public void set(CountDownLatch lockObject, Response response) {
+        mLockObject = lockObject;
+        mResponse = response;
+    }
+
+    public void setState(Provider.ProviderState state) {
+        mState = state;
+    }
+
+    public void setId(long id) {
+        mId = id;
+    }
+
+    void setType(SyncInfo.SyncType type) {
+        mType = type;
+    }
+
+    @Override
+    public void onProviderStateReceived(Provider.ProviderState state) {
+        Log.i(TAG, "onProviderStateReceived: " + state);
+        if (mState == state) {
+            Log.i(TAG, "onProviderStateReceived: Lock released");
+            mResponse.set(true);
+            mLockObject.countDown();
+        }
+
+    }
+
+    @Override
+    public void onMessageReceived(org.iotivity.service.ns.common.Message msg) {
+        Log.i(TAG, "onMessageReceived: " + msg.getMessageId());
+        if (mId == msg.getMessageId()) {
+            Log.i(TAG, "onMessageReceived: Lock released");
+            mResponse.set(true);
+            mLockObject.countDown();
+        }
+    }
+
+    @Override
+    public void onSyncInfoReceived(SyncInfo syncInfo) {
+        Log.i(TAG, "onSyncInfoReceived: " + syncInfo.getState());
+        if (mType == syncInfo.getState()) {
+            Log.i(TAG, "onSyncInfoReceived: Lock released");
+            mResponse.set(true);
+            mLockObject.countDown();
+        }
+    }
+}
+
+class Response {
+    private boolean state;
+
+    Response() {
+        state = false;
+    }
+
+    public void set(boolean val) {
+        state = val;
+    }
+
+    public boolean get() {
+        return state;
+    }
+}
diff --git a/service/notification/examples/android/NotiConsumerExample/app/src/androidTest/java/org/iotivity/service/ns/sample/consumer/ProviderSimulator.java b/service/notification/examples/android/NotiConsumerExample/app/src/androidTest/java/org/iotivity/service/ns/sample/consumer/ProviderSimulator.java
new file mode 100755 (executable)
index 0000000..7a46eb8
--- /dev/null
@@ -0,0 +1,68 @@
+//******************************************************************
+//
+// Copyright 2016 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+package org.iotivity.service.ns.sample.consumer;
+
+import android.util.Log;
+
+import org.iotivity.service.ns.common.MediaContents;
+import org.iotivity.service.ns.common.Message;
+import org.iotivity.service.ns.common.SyncInfo;
+import org.iotivity.service.ns.provider.Consumer;
+import org.iotivity.service.ns.provider.ProviderService;
+
+class ProviderSimulator
+        implements ProviderService.OnMessageSynchronizedListener,
+        ProviderService.OnConsumerSubscribedListener {
+    private String   TAG = "Provider Simulator";
+    private Consumer gConsumer;
+
+    @Override
+    public void onMessageSynchronized(SyncInfo syncInfo) {
+        Log.i(TAG, "Notification onMessageSynchronized: ");
+    }
+
+    @Override
+    public void onConsumerSubscribed(Consumer consumer) {
+        gConsumer = consumer;
+        try {
+            gConsumer.acceptSubscription(true);
+            Log.i(TAG, "Notification AcceptSubscription" );
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public Message getMessage() {
+        try {
+            Message msg = ProviderService.getInstance().createMessage();
+            msg.setTitle("Title");
+            msg.setSourceName("provider");
+            msg.setContentText("notification");
+            MediaContents media = new MediaContents("new");
+            msg.setMediaContents(media);
+            return msg;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+}
index fe09e0e..788bdd8 100755 (executable)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>\r
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"\r
-    package="com.sec.noticonsumerexample">\r
+    package="org.iotivity.service.ns.sample.consumer">\r
 \r
     <uses-feature android:name="android.hardware.nfc" />\r
     <uses-permission android:name="android.permission.READ_PHONE_STATE" />\r
@@ -29,7 +29,7 @@
                 <category android:name="android.intent.category.LAUNCHER" />\r
             </intent-filter>\r
         </activity>\r
-\r
+        <activity android:name=".LoginActivity" />\r
 \r
     </application>\r
 \r
diff --git a/service/notification/examples/android/NotiConsumerExample/app/src/main/java/com/sec/noticonsumerexample/MainActivity.java b/service/notification/examples/android/NotiConsumerExample/app/src/main/java/com/sec/noticonsumerexample/MainActivity.java
deleted file mode 100755 (executable)
index f332ac2..0000000
+++ /dev/null
@@ -1,271 +0,0 @@
-/******************************************************************\r
- * Copyright 2016 Samsung Electronics All Rights Reserved.\r
- * <p>\r
- * <p>\r
- * <p>\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- * <p>\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- * <p>\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- ******************************************************************/\r
-\r
-package com.sec.noticonsumerexample;\r
-\r
-import android.os.Bundle;\r
-import android.os.Handler;\r
-import android.os.Message;\r
-import android.app.Activity;\r
-import android.util.Log;\r
-import android.view.View;\r
-import android.widget.Button;\r
-import android.widget.TextView;\r
-import android.widget.Toast;\r
-\r
-import org.iotivity.service.ns.common.TopicsList;\r
-import org.iotivity.service.ns.common.Topic;\r
-\r
-public class MainActivity extends Activity\r
-{\r
-    private final String TAG = "NS_MAIN_ACTIVITY";\r
-\r
-    private Button btnStart;\r
-    private Button btnStop;\r
-    private Button btnRescan;\r
-    private Button btnEnableRemoteService;\r
-    private Button btnGetTopicList;\r
-    private Button btnUpdateTopicList;\r
-    private Button btnClearLog;\r
-    private static TextView TvLog;\r
-\r
-    private boolean isStarted = false;\r
-\r
-    private ConsumerSample mConsumerSample = null;\r
-\r
-    private static final int PROVIDER_DISCOVERED = 1;\r
-    private static final int STATE_CHANGED = 2;\r
-    private static final int MESSAGE_RECEIVED = 3;\r
-    private static final int SYNCINFO_RECEIVED = 4;\r
-    private static final int TOPICS_RECEIVED = 5;\r
-\r
-    public static Handler mHandler = new Handler()\r
-    {\r
-        @Override\r
-        public void handleMessage(Message msg)\r
-        {\r
-            switch (msg.what)\r
-            {\r
-                case PROVIDER_DISCOVERED:\r
-                    {\r
-                        String providerId = (String) msg.obj;\r
-                        if (providerId != null)\r
-                        {\r
-                            TvLog.append( providerId + "\n");\r
-                        }\r
-                        break;\r
-                    }\r
-                case STATE_CHANGED:\r
-                    {\r
-                        String state = (String) msg.obj;\r
-                        if (state != null)\r
-                        {\r
-                            TvLog.append( state + "\n");\r
-                        }\r
-                        break;\r
-                    }\r
-                case MESSAGE_RECEIVED:\r
-                    {\r
-                        String message = (String) msg.obj;\r
-                        if (message != null)\r
-                        {\r
-                            TvLog.append( message + "\n");\r
-                        }\r
-                        break;\r
-                    }\r
-                case SYNCINFO_RECEIVED:\r
-                    {\r
-                        String sync = (String) msg.obj;\r
-                        if (sync != null)\r
-                        {\r
-                            TvLog.append( sync + "\n");\r
-                        }\r
-                        break;\r
-                    }\r
-                case TOPICS_RECEIVED:\r
-                    {\r
-                        String topicList = (String) msg.obj;\r
-                        if (topicList != null)\r
-                        {\r
-                            TvLog.append( topicList + "\n");\r
-                        }\r
-                        break;\r
-                    }\r
-                default:\r
-                    break;\r
-            }\r
-        }\r
-    };\r
-\r
-    public void showToast(final String toast)\r
-    {\r
-        runOnUiThread(new Runnable()\r
-        {\r
-            @Override\r
-            public void run()\r
-            {\r
-                Toast.makeText(getApplicationContext(), toast, Toast.LENGTH_SHORT).show();\r
-            }\r
-        });\r
-    }\r
-\r
-    @Override\r
-    protected void onCreate(Bundle savedInstanceState)\r
-    {\r
-        super.onCreate(savedInstanceState);\r
-        setContentView(R.layout.activity_main);\r
-\r
-        btnStart = (Button) findViewById(R.id.BtnStart);\r
-        btnStop = (Button) findViewById(R.id.BtnStop);\r
-        btnRescan = (Button) findViewById(R.id.BtnRescan);\r
-        btnEnableRemoteService = (Button) findViewById(R.id.BtnEnableRemoteService);\r
-        btnGetTopicList = (Button) findViewById(R.id.BtnGetTopicList);\r
-        btnUpdateTopicList = (Button) findViewById(R.id.BtnUpdateTopicList);\r
-        btnClearLog = (Button) findViewById(R.id.BtnClearLog);\r
-\r
-        TvLog = (TextView) findViewById(R.id.TvLog);\r
-\r
-        btnStart.setOnClickListener(mClickListener);\r
-        btnStop.setOnClickListener(mClickListener);\r
-        btnRescan.setOnClickListener(mClickListener);\r
-        btnEnableRemoteService.setOnClickListener(mClickListener);\r
-        btnGetTopicList.setOnClickListener(mClickListener);\r
-        btnUpdateTopicList.setOnClickListener(mClickListener);\r
-        btnClearLog.setOnClickListener(mClickListener);\r
-\r
-        mConsumerSample = new ConsumerSample(getApplicationContext());\r
-        mConsumerSample.setHandler(mHandler);\r
-    }\r
-\r
-    @Override\r
-    protected void onDestroy()\r
-    {\r
-        if (isStarted)\r
-            mConsumerSample.stopNotificationConsumer();\r
-        super.onDestroy();\r
-    }\r
-\r
-    Button.OnClickListener mClickListener = new View.OnClickListener()\r
-    {\r
-        public void onClick(View v)\r
-        {\r
-            switch (v.getId())\r
-            {\r
-                case R.id.BtnStart:\r
-                    {\r
-                        if (!isStarted)\r
-                        {\r
-                            Log.i(TAG, "Start NS Consumer Service");\r
-\r
-                            TvLog.setText("Start NS-Consumer\n");\r
-                            mConsumerSample.startNotificationConsumer();\r
-                            isStarted = true;\r
-                        }\r
-                        else\r
-                        {\r
-                            Log.e(TAG, "NS Consumer Service has already started");\r
-                            showToast("Error : Service has already started");\r
-                        }\r
-                    }\r
-                    break;\r
-\r
-                case R.id.BtnStop:\r
-                    {\r
-                        if (!isStarted)\r
-                        {\r
-                            Log.e(TAG, "Fail to stop service. Service has not been started");\r
-                            showToast("Error : Service has not been started");\r
-                            break;\r
-                        }\r
-                        TvLog.append("Stop NS-Consumer\n");\r
-                        mConsumerSample.stopNotificationConsumer();\r
-                        isStarted = false;\r
-                    }\r
-                    break;\r
-                case R.id.BtnRescan:\r
-                    {\r
-                        if (!isStarted)\r
-                        {\r
-                            Log.e(TAG, "Fail to rescan. Service has not been started");\r
-                            showToast("Error : Service has not been started");\r
-                            break;\r
-                        }\r
-                        TvLog.append("Rescan NS-Consumer\n");\r
-                        mConsumerSample.rescanProvider();\r
-                    }\r
-                    break;\r
-                case R.id.BtnEnableRemoteService:\r
-                    {\r
-                        if (!isStarted)\r
-                        {\r
-                            Log.e(TAG, "Fail to Enable RemoteService. Service has not been started");\r
-                            showToast("Error : Service has not been started");\r
-                            break;\r
-                        }\r
-                        TvLog.append("EnableRemoteService NS-Consumer\n");\r
-\r
-                        //TODO: Update to read the serverAddress from UI\r
-                        String serverAddress = new String();\r
-                        mConsumerSample.enableRemoteService(serverAddress);\r
-                    }\r
-                    break;\r
-                case R.id.BtnGetTopicList:\r
-                    {\r
-                        if (!isStarted)\r
-                        {\r
-                            Log.e(TAG, "Fail to GetTopicList. Service has not been started");\r
-                            showToast("Error : Service has not been started");\r
-                            break;\r
-                        }\r
-                        TvLog.append("GetTopicList NS-Consumer\n");\r
-                        mConsumerSample.getTopicsList();\r
-                    }\r
-                    break;\r
-                case R.id.BtnUpdateTopicList:\r
-                    {\r
-                        if (!isStarted)\r
-                        {\r
-                            Log.e(TAG, "Fail to UpdateTopicList. Service has not been started");\r
-                            showToast("Error : Service has not been started");\r
-                            break;\r
-                        }\r
-                        if(mConsumerSample.getAcceptor())\r
-                        {\r
-                            Log.e(TAG, "Operation Not Allowed. ProviderService Acceptor is not Consumer");\r
-                            showToast("Operation Not Allowed. ProviderService Acceptor is not Consumer");\r
-                            break;\r
-                        }\r
-                        TvLog.append("UpdateTopicList NS-Consumer\n");\r
-\r
-                        TopicsList topicList = new TopicsList();\r
-                        topicList.addTopic("OCF_TOPIC1", Topic.TopicState.SUBSCRIBED);\r
-                        topicList.addTopic("OCF_TOPIC2", Topic.TopicState.SUBSCRIBED);\r
-                        topicList.addTopic("OCF_TOPIC3", Topic.TopicState.UNSUBSCRIBED);\r
-\r
-                        mConsumerSample.updateTopicList(topicList);\r
-                    }\r
-                    break;\r
-                case R.id.BtnClearLog:\r
-                {\r
-                    TvLog.setText("");\r
-                }\r
-                break;\r
-            }\r
-        }\r
-    };\r
-}\r
@@ -16,7 +16,7 @@
  * limitations under the License.
  ******************************************************************/
 
-package com.sec.noticonsumerexample;
+package org.iotivity.service.ns.sample.consumer;
 
 import android.content.Context;
 import android.os.Handler;
@@ -36,214 +36,198 @@ import org.iotivity.service.ns.consumer.ConsumerService;
 import org.iotivity.service.ns.consumer.Provider;
 
 public class ConsumerSample
-    implements ConsumerService.OnProviderDiscoveredListener,
-    Provider.OnProviderStateListener,
-    Provider.OnMessageReceivedListner, Provider.OnSyncInfoReceivedListner
-{
-    private static final String TAG = "NS_CONSUMER_SAMPLE";
+        implements ConsumerService.OnProviderDiscoveredListener,
+        Provider.OnProviderStateListener, Provider.OnMessageReceivedListener,
+        Provider.OnSyncInfoReceivedListener {
+    private static final String TAG                 = "NS_CONSUMER_SAMPLE";
 
-    private Context mContext = null;
-    private ConsumerService consumerService = null;
-    private boolean mAcceptor = true;
-    private Provider mProvider = null;
+    private Context             mContext            = null;
+    private ConsumerService     consumerService     = null;
+    private boolean             mAcceptor           = true;
+    private Provider            mProvider           = null;
 
-    private Handler mHandler = null;
+    private Handler             mHandler            = null;
 
-    private static final int PROVIDER_DISCOVERED = 1;
-    private static final int STATE_CHANGED = 2;
-    private static final int MESSAGE_RECEIVED = 3;
-    private static final int SYNCINFO_RECEIVED = 4;
-    private static final int TOPICS_RECEIVED = 5;
+    private static final int    PROVIDER_DISCOVERED = 1;
+    private static final int    STATE_CHANGED       = 2;
+    private static final int    MESSAGE_RECEIVED    = 3;
+    private static final int    SYNCINFO_RECEIVED   = 4;
+    private static final int    TOPICS_RECEIVED     = 5;
 
-    public ConsumerSample(Context context)
-    {
+    public ConsumerSample(Context context) {
         Log.i(TAG, "Create consumer sample Instance");
 
         this.mContext = context;
         consumerService = new ConsumerService();
     }
 
-    public void setHandler(Handler handler)
-    {
+    public void setHandler(Handler handler) {
         this.mHandler = handler;
     }
 
-    public boolean getAcceptor()
-    {
+    public boolean getAcceptor() {
         return mAcceptor;
     }
 
-    private void configurePlatform()
-    {
+    private void configurePlatform() {
 
-        PlatformConfig platformConfig = new PlatformConfig(
-            mContext,
-            ServiceType.IN_PROC,
-            ModeType.CLIENT_SERVER,
-            "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
-            0,         // Uses randomly available port
-            QualityOfService.LOW
-        );
+        PlatformConfig platformConfig = new PlatformConfig(mContext,
+                ServiceType.IN_PROC, ModeType.CLIENT_SERVER, "0.0.0.0",
+                0, // Uses randomly available port
+                QualityOfService.LOW);
 
         Log.i(TAG, "Configuring platform.");
         OcPlatform.Configure(platformConfig);
-        try
-        {
+        try {
             OcPlatform.stopPresence(); // Initialize OcPlatform
-        }
-        catch (Exception e)
-        {
-            Log.e(TAG, "Exception: stopping presence when configuration step: " + e);
+        } catch (Exception e) {
+            Log.e(TAG, "Exception: stopping presence when configuration step: "
+                    + e);
         }
         Log.i(TAG, "Configuration done Successfully");
     }
 
-    public void startNotificationConsumer()
-    {
+    public void startNotificationConsumer() {
         configurePlatform();
-        try
-        {
+        try {
             consumerService.start(this);
-        }
-        catch (Exception e)
-        {
+        } catch (Exception e) {
             Log.e(TAG, "Exception: startNotificationConsumer : " + e);
         }
     }
 
-    public void stopNotificationConsumer()
-    {
-        try
-        {
+    public void stopNotificationConsumer() {
+        try {
             consumerService.stop();
             mProvider = null;
-        }
-        catch (Exception e)
-        {
+        } catch (Exception e) {
             Log.e(TAG, "Exception: stopNotificationConsumer : " + e);
         }
     }
 
-    public void enableRemoteService(String serverAddress)
-    {
-        try
-        {
+    public void enableRemoteService(String serverAddress) {
+        try {
             consumerService.enableRemoteService(serverAddress);
-        }
-        catch (NSException e)
-        {
+        } catch (NSException e) {
             Log.e(TAG, "NSException: enableRemoteService : " + e);
         }
     }
 
-    public void rescanProvider()
-    {
-        try
-        {
-            consumerService.rescanProvider();
+    public void subscribeMQService(String servAdd, String topicName) {
+        Log.i(TAG, "SubscribeMQService  - IN");
+        try {
+            consumerService.subscribeMQService(servAdd, topicName);
+        } catch (Exception e) {
+            Log.e(TAG, "Exception: subscribeMQService : " + e);
         }
-        catch (Exception e)
-        {
+        Log.i(TAG, "SubscribeMQService  - OUT");
+        return;
+    }
+
+    public void rescanProvider() {
+        try {
+            consumerService.rescanProvider();
+        } catch (Exception e) {
             Log.e(TAG, "Exception: rescanProvider : " + e);
         }
     }
-    public void getTopicsList()
-    {
-        if (mProvider != null)
-        {
-            try
-            {
+
+    public void subscribe() {
+        try {
+            mProvider.subscribe();
+            Log.i(TAG, "Notification consumer subscribe: " );
+        } catch (Exception e) {
+            Log.e(TAG, "Exception: subscribe : " + e);
+        }
+    }
+
+    public void unsubscribe() {
+        try {
+            mProvider.unsubscribe();
+            Log.i(TAG, "Notification consumer unsubscribe: ");
+        } catch (Exception e) {
+            Log.e(TAG, "Exception: unsubscribe : " + e);
+        }
+    }
+    public void getTopicsList() {
+        if (mProvider != null) {
+            try {
                 TopicsList topicsList = mProvider.getTopicList();
                 StringBuilder stringBuilder = new StringBuilder();
                 stringBuilder.append("TopicList Received :");
-                for(Topic topic : topicsList.getTopicsList())
-                {
-                    Log.i(TAG, "Topic Name : " + topic.getTopicName() );
-                    Log.i(TAG, "Topic State : " + topic.getState() );
-                    stringBuilder.append("\nTopic Name : " + topic.getTopicName());
+                for (Topic topic : topicsList.getTopicsList()) {
+                    Log.i(TAG, "Topic Name : " + topic.getTopicName());
+                    Log.i(TAG, "Topic State : " + topic.getState());
+                    stringBuilder
+                            .append("\nTopic Name : " + topic.getTopicName());
                     stringBuilder.append("\nTopic State : " + topic.getState());
                 }
-                Message msg = mHandler.obtainMessage(TOPICS_RECEIVED, stringBuilder.toString());
+                Message msg = mHandler.obtainMessage(TOPICS_RECEIVED,
+                        stringBuilder.toString());
                 mHandler.sendMessage(msg);
-            }
-            catch (Exception e)
-            {
+            } catch (Exception e) {
                 Log.e(TAG, "Exception: getTopicsList : " + e);
             }
-        }
-        else
-        {
+        } else {
             Log.e(TAG, "getTopicsList Provider NULL");
         }
     }
-    public void updateTopicList(TopicsList topicsList)
-    {
-        if (mProvider != null)
-        {
-            try
-            {
+
+    public void updateTopicList(TopicsList topicsList) {
+        if (mProvider != null) {
+            try {
                 mProvider.updateTopicList(topicsList);
-            }
-            catch (Exception e)
-            {
+            } catch (Exception e) {
                 Log.e(TAG, "Exception: updateTopicList : " + e);
             }
-        }
-        else
-        {
+        } else {
             Log.e(TAG, "updateTopicList Provider NULL");
         }
     }
+
     @Override
-    public void onProviderDiscovered(Provider provider)
-    {
+    public void onProviderDiscovered(Provider provider) {
         Log.i(TAG, "onProviderDiscovered");
-        if (provider == null)
-        {
+        if (provider == null) {
             Log.e(TAG, "providerID is Null  ");
             return;
         }
         mProvider = provider;
-        Log.i(TAG, "Provider ID: " + provider.getProviderId() );
+        Log.i(TAG, "Provider ID: " + provider.getProviderId());
         Message msg = mHandler.obtainMessage(PROVIDER_DISCOVERED,
-                                             "Provider Discovered Id: " + provider.getProviderId());
+                "Provider Discovered Id: " + provider.getProviderId());
         mHandler.sendMessage(msg);
-        try
-        {
+        try {
             Log.i(TAG, "setListeners to Discovered Provider");
             provider.setListener(this, this, this);
             Log.i(TAG, "setListeners done");
-            if (! provider.isSubscribed())
-            {
+            if (!provider.isSubscribed()) {
                 Log.i(TAG, "Provider not subscribed. Acceptor is Consumer");
                 mAcceptor = false;
                 provider.subscribe();
-            }
-            else
-            {
-                Log.i(TAG, "Provider is already subscribed. Acceptor is Provider");
+            } else {
+                Log.i(TAG,
+                        "Provider is already subscribed. Acceptor is Provider");
                 mAcceptor = true;
             }
-        }
-        catch (Exception e)
-        {
+        } catch (Exception e) {
             Log.e(TAG, "Exception : " + e);
         }
     }
 
     @Override
-    public void onProviderStateReceived(Provider.ProviderState state)
-    {
+    public void onProviderStateReceived(Provider.ProviderState state) {
         Log.i(TAG, "onProviderStateReceived");
 
-        Log.i(TAG, "ProviderState Received : " + state );
-        Message msg = mHandler.obtainMessage(STATE_CHANGED, "ProviderState Received : " + state);
+        Log.i(TAG, "ProviderState Received : " + state);
+        Message msg = mHandler.obtainMessage(STATE_CHANGED,
+                "ProviderState Received : " + state);
         mHandler.sendMessage(msg);
     }
 
     @Override
-    public void onMessageReceived(org.iotivity.service.ns.common.Message message)
-    {
+    public void onMessageReceived(
+            org.iotivity.service.ns.common.Message message) {
         Log.i(TAG, "onMessageReceived");
 
         Log.i(TAG, "Message Id: " + message.getMessageId());
@@ -253,33 +237,30 @@ public class ConsumerSample
         Log.i(TAG, "Message Source: " + message.getSourceName());
 
         Message msg = mHandler.obtainMessage(MESSAGE_RECEIVED,
-                                             "Message Id: " + message.getMessageId() + "\n" +
-                                             "Message title: " + message.getTitle() + "\n" +
-                                             "Message Content: " + message.getContentText() + "\n" +
-                                             "Message Topic: " + message.getTopic() + "\n" +
-                                             "Message Source: " + message.getSourceName() );
+                "Message Id: " + message.getMessageId() + "\n"
+                        + "Message title: " + message.getTitle() + "\n"
+                        + "Message Content: " + message.getContentText() + "\n"
+                        + "Message Topic: " + message.getTopic() + "\n"
+                        + "Message Source: " + message.getSourceName());
         mHandler.sendMessage(msg);
-        try
-        {
+        try {
             Log.i(TAG, "send READ syncInfo");
-            mProvider.sendSyncInfo(message.getMessageId(), SyncInfo.SyncType.READ);
-        }
-        catch (Exception e)
-        {
+            mProvider.sendSyncInfo(message.getMessageId(),
+                    SyncInfo.SyncType.READ);
+        } catch (Exception e) {
             Log.e(TAG, "Exception : " + e);
         }
     }
 
     @Override
-    public void onSyncInfoReceived(SyncInfo sync)
-    {
+    public void onSyncInfoReceived(SyncInfo sync) {
         Log.i(TAG, "onSyncInfoReceived");
 
         Log.i(TAG, "Sync Id: " + sync.getMessageId());
         Log.i(TAG, "Sync STATE: " + sync.getState());
         Message msg = mHandler.obtainMessage(SYNCINFO_RECEIVED,
-                                             "Sync Id: " + sync.getMessageId() + "\n" +
-                                             "Sync STATE: " + sync.getState());
+                "Sync Id: " + sync.getMessageId() + "\n" + "Sync STATE: "
+                        + sync.getState());
         mHandler.sendMessage(msg);
     }
 }
diff --git a/service/notification/examples/android/NotiConsumerExample/app/src/main/java/org/iotivity/service/ns/sample/consumer/LoginActivity.java b/service/notification/examples/android/NotiConsumerExample/app/src/main/java/org/iotivity/service/ns/sample/consumer/LoginActivity.java
new file mode 100644 (file)
index 0000000..287e4b7
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * ******************************************************************
+ *
+ * Copyright 2016 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.
+ *
+ * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.service.ns.sample.consumer;
+
+import android.app.Activity;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.Intent;
+import android.net.UrlQuerySanitizer;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+import android.widget.Button;
+import android.widget.EditText;
+
+/**
+ * This class is for login to the provider. Can be get auth code via web page.
+ */
+public class LoginActivity extends Activity {
+    private static final String TAG           = "OIC_SIMPLE_LOGIN";
+
+    private final Context       context       = this;
+    private WebView             mWebView      = null;
+    private static String       loginAccount  = null;
+    private static String       mAuthProvider = null;
+
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_login);
+
+        final Dialog dialog = new Dialog(context);
+        dialog.setContentView(R.layout.dialog_auth);
+        dialog.setTitle("Login Details");
+        final EditText auth = (EditText) dialog.findViewById(R.id.EditTextAuth);
+        final EditText url = (EditText) dialog.findViewById(R.id.EditTextUrl);
+        if (loginAccount != null && mAuthProvider != null) {
+            url.setText(loginAccount);
+            auth.setText(mAuthProvider);
+        }
+
+        Button dialogButton = (Button) dialog.findViewById(R.id.dialogButtonOK);
+        dialog.setCanceledOnTouchOutside(false);
+        dialogButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                dialog.dismiss();
+                loginAccount = url.getText().toString();
+                mAuthProvider = auth.getText().toString();
+
+                mWebView = (WebView) findViewById(R.id.webView);
+                mWebView.setInitialScale(200);
+                mWebView.getSettings().setJavaScriptEnabled(true);
+                mWebView.getSettings().setBuiltInZoomControls(true);
+                mWebView.setWebViewClient(new WebViewClientClass());
+
+                mWebView.loadUrl(loginAccount);
+            }
+        });
+        dialog.show();
+    }
+
+    public void onDestroy() {
+        super.onDestroy();
+    }
+
+    private class WebViewClientClass extends WebViewClient {
+
+        @Override
+        public void onPageFinished(WebView view, String url) {
+            Log.i(TAG,
+                    "onPageFinished!!! Response received: called url=" + url);
+
+            if (url.contains("code") && url.contains("code_expires_in")) {
+
+                mWebView.setVisibility(View.INVISIBLE);
+
+                // parsing url
+                UrlQuerySanitizer sanitizer = new UrlQuerySanitizer();
+                sanitizer.setAllowUnregisteredParamaters(true);
+                sanitizer.parseUrl(url);
+
+                String mAuthCode = sanitizer.getValue("code");
+                Log.i(TAG, "onPageFinished!!! authCode=" + mAuthCode);
+
+                Intent intent = getIntent();
+                intent.putExtra("authCode", mAuthCode);
+                intent.putExtra("authProvider", mAuthProvider);
+                setResult(RESULT_OK, intent);
+
+                finish();
+            }
+        }
+    }
+}
diff --git a/service/notification/examples/android/NotiConsumerExample/app/src/main/java/org/iotivity/service/ns/sample/consumer/MainActivity.java b/service/notification/examples/android/NotiConsumerExample/app/src/main/java/org/iotivity/service/ns/sample/consumer/MainActivity.java
new file mode 100755 (executable)
index 0000000..5348d8b
--- /dev/null
@@ -0,0 +1,671 @@
+/******************************************************************
+ * Copyright 2016 Samsung Electronics All Rights Reserved.
+ * <p>
+ * <p>
+ * <p>
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.service.ns.sample.consumer;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.app.Activity;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import org.iotivity.base.ErrorCode;
+import org.iotivity.base.OcAccountManager;
+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.service.ns.common.TopicsList;
+import org.iotivity.service.ns.common.Topic;
+
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class MainActivity extends Activity
+        implements OcAccountManager.OnPostListener {
+    private final String        TAG                 = "NS_MAIN_ACTIVITY";
+    private final int           REQUEST_LOGIN       = 1;
+    private static final String CI_SERVER_PREFIX    = "coap+tcp://";
+    private final Context       context             = this;
+
+    public static String        deviceID            = null;
+    public static String        CIServer            = null;
+    public static String        RemoteAddress       = null;
+    public static String        MQCloudAddress      = null;
+    public static String        MQCloudTopic        = null;
+
+    private Button              btnStart;
+    private Button              btnStop;
+    private Button              btnRescan;
+    private Button              btnSubscribe;
+    private Button              btnUnsubscribe;
+    private Button              btnEnableRemoteService;
+    private Button              btnGetTopicList;
+    private Button              btnUpdateTopicList;
+    private Button              btnClearLog;
+    private static TextView     TvLog;
+    private Button              signUp, signIn, signOut;
+    private Button              subscribeMQ;
+
+    private boolean             isStarted           = false;
+
+    private ConsumerSample      mConsumerSample     = null;
+    private OcAccountManager    mAccountManager;
+    String                      mAuthCode;
+    String                      mAuthProvider;
+    String                      mRefreshtoken;
+    String                      mUserID;
+    String                      mAccessToken;
+
+    private static final int    PROVIDER_DISCOVERED = 1;
+    private static final int    STATE_CHANGED       = 2;
+    private static final int    MESSAGE_RECEIVED    = 3;
+    private static final int    SYNCINFO_RECEIVED   = 4;
+    private static final int    TOPICS_RECEIVED     = 5;
+
+    public static Handler       mHandler            = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case PROVIDER_DISCOVERED: {
+                    String providerId = (String) msg.obj;
+                    if (providerId != null) {
+                        TvLog.append(providerId + "\n");
+                    }
+                    break;
+                }
+                case STATE_CHANGED: {
+                    String state = (String) msg.obj;
+                    if (state != null) {
+                        TvLog.append(state + "\n");
+                    }
+                    break;
+                }
+                case MESSAGE_RECEIVED: {
+                    String message = (String) msg.obj;
+                    if (message != null) {
+                        TvLog.append(message + "\n");
+                    }
+                    break;
+                }
+                case SYNCINFO_RECEIVED: {
+                    String sync = (String) msg.obj;
+                    if (sync != null) {
+                        TvLog.append(sync + "\n");
+                    }
+                    break;
+                }
+                case TOPICS_RECEIVED: {
+                    String topicList = (String) msg.obj;
+                    if (topicList != null) {
+                        TvLog.append(topicList + "\n");
+                    }
+                    break;
+                }
+                default:
+                    break;
+            }
+        }
+    };
+
+    public void showToast(final String toast) {
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                Toast.makeText(getApplicationContext(), toast,
+                        Toast.LENGTH_SHORT).show();
+            }
+        });
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+
+        btnStart = (Button) findViewById(R.id.BtnStart);
+        btnStop = (Button) findViewById(R.id.BtnStop);
+        btnRescan = (Button) findViewById(R.id.BtnRescan);
+        btnSubscribe = (Button) findViewById(R.id.BtnSubscribe);
+        btnUnsubscribe = (Button) findViewById(R.id.BtnUnsubscribe);
+        btnEnableRemoteService = (Button) findViewById(
+                R.id.BtnEnableRemoteService);
+        btnGetTopicList = (Button) findViewById(R.id.BtnGetTopicList);
+        btnUpdateTopicList = (Button) findViewById(R.id.BtnUpdateTopicList);
+        btnClearLog = (Button) findViewById(R.id.BtnClearLog);
+
+        signUp = (Button) findViewById(R.id.signup);
+        signIn = (Button) findViewById(R.id.signin);
+        signOut = (Button) findViewById(R.id.signout);
+        subscribeMQ = (Button) findViewById(R.id.subscribeMQService);
+        TvLog = (TextView) findViewById(R.id.TvLog);
+
+        btnStart.setOnClickListener(mClickListener);
+        btnStop.setOnClickListener(mClickListener);
+        btnRescan.setOnClickListener(mClickListener);
+        btnEnableRemoteService.setOnClickListener(mClickListener);
+        btnGetTopicList.setOnClickListener(mClickListener);
+        btnUpdateTopicList.setOnClickListener(mClickListener);
+        btnClearLog.setOnClickListener(mClickListener);
+
+        signIn.setEnabled(false);
+        signOut.setEnabled(false);
+        btnEnableRemoteService.setEnabled(false);
+
+        btnSubscribe.setOnClickListener(mClickListener);
+        btnUnsubscribe.setOnClickListener(mClickListener);
+        signUp.setOnClickListener(mClickListener);
+        signIn.setOnClickListener(mClickListener);
+        signOut.setOnClickListener(mClickListener);
+        subscribeMQ.setOnClickListener(mClickListener);
+
+        mConsumerSample = new ConsumerSample(getApplicationContext());
+        mConsumerSample.setHandler(mHandler);
+    }
+
+    @Override
+    protected void onDestroy() {
+        if (isStarted)
+            mConsumerSample.stopNotificationConsumer();
+        super.onDestroy();
+    }
+
+    Button.OnClickListener mClickListener = new View.OnClickListener() {
+        public void onClick(View v) {
+            switch (v.getId()) {
+                case R.id.BtnStart: {
+                    if (!isStarted) {
+                        Log.i(TAG, "Start NS Consumer Service");
+
+                        TvLog.setText("Start NS-Consumer\n");
+                        mConsumerSample.startNotificationConsumer();
+                        isStarted = true;
+                    } else {
+                        Log.e(TAG, "NS Consumer Service has already started");
+                        showToast("Error : Service has already started");
+                    }
+                }
+                    break;
+
+                case R.id.BtnStop: {
+                    if (!isStarted) {
+                        Log.e(TAG,
+                                "Fail to stop service. Service has not been started");
+                        showToast("Error : Service has not been started");
+                        break;
+                    }
+                    TvLog.append("Stop NS-Consumer\n");
+                    mConsumerSample.stopNotificationConsumer();
+                    isStarted = false;
+                }
+                    break;
+                case R.id.BtnRescan: {
+                    if (!isStarted) {
+                        Log.e(TAG,
+                                "Fail to rescan. Service has not been started");
+                        showToast("Error : Service has not been started");
+                        break;
+                    }
+                    TvLog.append("Rescan NS-Consumer\n");
+                    mConsumerSample.rescanProvider();
+                }
+                    break;
+                case R.id.BtnSubscribe: {
+                    if (!isStarted) {
+                        Log.e(TAG,
+                                "Fail to Subscribe. Service has not been started");
+                        showToast("Error : Service has not been started");
+                        break;
+                    }
+                    TvLog.append("Subscribe NS-Consumer\n");
+                    mConsumerSample.subscribe();
+                }
+                break;
+                case R.id.BtnUnsubscribe: {
+                    if (!isStarted) {
+                        Log.e(TAG,
+                                "Fail to Unsubscribe. Service has not been started");
+                        showToast("Error : Service has not been started");
+                        break;
+                    }
+                    TvLog.append("Unsubscribe NS-Consumer\n");
+                    mConsumerSample.unsubscribe();
+                }
+                break;
+                case R.id.BtnEnableRemoteService: {
+                    if (!isStarted) {
+                        Log.e(TAG,
+                                "Fail to Enable RemoteService. Service has not been started");
+                        showToast("Error : Service has not been started");
+                        break;
+                    }
+                    TvLog.append("EnableRemoteService NS-Consumer\n");
+                    mConsumerSample.enableRemoteService(RemoteAddress);
+                }
+                    break;
+                case R.id.BtnGetTopicList: {
+                    if (!isStarted) {
+                        Log.e(TAG,
+                                "Fail to GetTopicList. Service has not been started");
+                        showToast("Error : Service has not been started");
+                        break;
+                    }
+                    TvLog.append("GetTopicList NS-Consumer\n");
+                    mConsumerSample.getTopicsList();
+                }
+                    break;
+                case R.id.BtnUpdateTopicList: {
+                    if (!isStarted) {
+                        Log.e(TAG,
+                                "Fail to UpdateTopicList. Service has not been started");
+                        showToast("Error : Service has not been started");
+                        break;
+                    }
+                    if (mConsumerSample.getAcceptor()) {
+                        Log.e(TAG,
+                                "Operation Not Allowed. ProviderService Acceptor is not Consumer");
+                        showToast(
+                                "Operation Not Allowed. ProviderService Acceptor is not Consumer");
+                        break;
+                    }
+                    TvLog.append("UpdateTopicList NS-Consumer\n");
+
+                    TopicsList topicList = new TopicsList();
+                    topicList.addTopic("OCF_TOPIC1",
+                            Topic.TopicState.SUBSCRIBED);
+                    topicList.addTopic("OCF_TOPIC2",
+                            Topic.TopicState.SUBSCRIBED);
+                    topicList.addTopic("OCF_TOPIC3",
+                            Topic.TopicState.UNSUBSCRIBED);
+
+                    mConsumerSample.updateTopicList(topicList);
+                }
+                    break;
+                case R.id.BtnClearLog: {
+                    TvLog.setText("");
+                }
+                    break;
+                case R.id.signup: {
+                    if (isStarted == false) {
+                        Log.e(TAG, "Fail to Sign Up");
+                        showToast("Start ConsumerService First");
+                        break;
+                    }
+                    TvLog.append("Initiating SignUp\n");
+                    signUp();
+                }
+                    break;
+                case R.id.signin: {
+                    if (isStarted == false) {
+                        Log.e(TAG, "Fail to Sign In");
+                        showToast("Start ConsumerService First");
+                        break;
+                    }
+                    TvLog.append("Initiating SignIn\n");
+                    signIn();
+                }
+                    break;
+                case R.id.signout: {
+                    if (isStarted == false) {
+                        Log.e(TAG, "Fail to Sign out");
+                        showToast("Start ConsumerService First");
+                        break;
+                    }
+                    TvLog.append("Initiating SignOut\n");
+                    signOut();
+                }
+                    break;
+                case R.id.subscribeMQService: {
+                    if (isStarted == false) {
+                        Log.e(TAG, "Fail to SubscribeMQService");
+                        showToast("Start ProviderService First");
+                        break;
+                    }
+                    final Dialog dialog = new Dialog(context);
+                    dialog.setContentView(R.layout.dialog_mq);
+                    dialog.setTitle("MQ Cloud Service Details");
+
+                    final EditText ip = (EditText) dialog
+                            .findViewById(R.id.EditTextIp);
+                    final EditText mqTopic = (EditText) dialog
+                            .findViewById(R.id.EditTextMqTopic);
+                    if (MQCloudAddress != null && MQCloudTopic != null) {
+                        ip.setText(MQCloudAddress);
+                        mqTopic.setText(MQCloudTopic);
+                    }
+
+                    Button dialogButton = (Button) dialog
+                            .findViewById(R.id.mqButtonOK);
+
+                    dialogButton.setOnClickListener(new View.OnClickListener() {
+                        @Override
+                        public void onClick(View v) {
+                            dialog.dismiss();
+                            MQCloudAddress = ip.getText().toString();
+                            MQCloudTopic = mqTopic.getText().toString();
+                            mConsumerSample.subscribeMQService(
+                                    MQCloudAddress, MQCloudTopic);
+                            TvLog.append("SubscribeMQService success\n");
+                        }
+                    });
+                    dialog.show();
+                }
+                    break;
+            }
+        }
+    };
+
+    public void logMessage(final String text) {
+        runOnUiThread(new Runnable() {
+            public void run() {
+                Message msg = new Message();
+                msg.obj = text;
+                TvLog.append(text + "\n");
+            }
+        });
+        Log.i(TAG, text);
+    }
+
+    OcAccountManager.OnPostListener onSignUp  = new OcAccountManager.OnPostListener() {
+        @Override
+        public synchronized void onPostCompleted(List<OcHeaderOption> list,
+                OcRepresentation ocRepresentation) {
+            logMessage("signUp was successful");
+            runOnUiThread(new Runnable() {
+                public void run() {
+                    signIn.setEnabled(true);
+                    signUp.setEnabled(false);
+                }
+            });
+            try {
+                mUserID = ocRepresentation.getValue("uid");
+                mAccessToken = ocRepresentation.getValue("accesstoken");
+                mRefreshtoken = ocRepresentation.getValue("refreshtoken");
+
+                logMessage("\tuserID: " + mUserID);
+                logMessage("\taccessToken: " + mAccessToken);
+                logMessage("\trefreshToken: " + mRefreshtoken);
+
+                if (ocRepresentation.hasAttribute("expiresin")) {
+                    int expiresIn = ocRepresentation.getValue("expiresin");
+                    logMessage("\texpiresIn: " + expiresIn);
+                }
+            } catch (OcException e) {
+                Log.e(TAG, e.toString());
+            }
+        }
+
+        @Override
+        public synchronized void onPostFailed(Throwable throwable) {
+            logMessage("Failed to signUp");
+            if (throwable instanceof OcException) {
+                OcException ocEx = (OcException) throwable;
+                Log.e(TAG, ocEx.toString());
+                ErrorCode errCode = ocEx.getErrorCode();
+                logMessage("Error code: " + errCode);
+            }
+        }
+    };
+
+    OcAccountManager.OnPostListener onSignIn  = new OcAccountManager.OnPostListener() {
+        @Override
+        public synchronized void onPostCompleted(List<OcHeaderOption> list,
+                OcRepresentation ocRepresentation) {
+            logMessage("signIn was successful");
+            runOnUiThread(new Runnable() {
+                public void run() {
+                    signIn.setEnabled(false);
+                    signOut.setEnabled(true);
+                    btnEnableRemoteService.setEnabled(true);
+                }
+            });
+
+        }
+
+        @Override
+        public synchronized void onPostFailed(Throwable throwable) {
+            logMessage("Failed to signIn");
+            if (throwable instanceof OcException) {
+                OcException ocEx = (OcException) throwable;
+                Log.e(TAG, ocEx.toString());
+                ErrorCode errCode = ocEx.getErrorCode();
+                logMessage("Error code: " + errCode);
+                if (ErrorCode.UNAUTHORIZED_REQ != errCode) {
+                    refreshToken();
+                }
+            }
+        }
+    };
+
+    OcAccountManager.OnPostListener onSignOut = new OcAccountManager.OnPostListener() {
+        @Override
+        public synchronized void onPostCompleted(List<OcHeaderOption> list,
+                OcRepresentation ocRepresentation) {
+            logMessage("signOut was successful");
+            runOnUiThread(new Runnable() {
+                public void run() {
+                    signIn.setEnabled(true);
+                    signOut.setEnabled(false);
+                    btnEnableRemoteService.setEnabled(false);
+                }
+            });
+
+        }
+
+        @Override
+        public synchronized void onPostFailed(Throwable throwable) {
+            logMessage("Failed to signOut");
+            if (throwable instanceof OcException) {
+                OcException ocEx = (OcException) throwable;
+                Log.e(TAG, ocEx.toString());
+                ErrorCode errCode = ocEx.getErrorCode();
+                logMessage("Error code: " + errCode);
+                if (ErrorCode.UNAUTHORIZED_REQ != errCode) {
+                    refreshToken();
+                }
+            }
+        }
+    };
+
+
+    @Override
+    public void onPostCompleted(List<OcHeaderOption> ocHeaderOptions,
+            OcRepresentation ocRepresentation) {
+
+    }
+
+    @Override
+    public void onPostFailed(Throwable throwable) {
+
+    }
+
+    private void signIn() {
+        try {
+            if (mAccountManager == null) {
+                mAccountManager = OcPlatform.constructAccountManagerObject(
+                        CIServer,
+                        EnumSet.of(OcConnectivityType.CT_ADAPTER_TCP));
+            }
+
+            mAccountManager.signIn(mUserID, mAccessToken, onSignIn);
+        } catch (OcException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void signOut() {
+        try {
+            logMessage("signOut");
+            if (mAccountManager == null) {
+                try {
+                    mAccountManager = OcPlatform.constructAccountManagerObject(
+                            CIServer,
+                            EnumSet.of(OcConnectivityType.CT_ADAPTER_TCP));
+                } catch (OcException e) {
+                    e.printStackTrace();
+                }
+            }
+            mAccountManager.signOut(mAccessToken, onSignOut);
+            signIn.setEnabled(false);
+            signUp.setEnabled(true);
+            btnEnableRemoteService.setEnabled(false);
+            logMessage("signOut Successful");
+        } catch (OcException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void signUp() {
+        Intent intentLogin = new Intent(this, LoginActivity.class);
+        startActivityForResult(intentLogin, REQUEST_LOGIN);
+    }
+
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+        if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_LOGIN) {
+            mAuthCode = data.getStringExtra("authCode");
+            mAuthProvider = data.getStringExtra("authProvider");
+            logMessage("authCode: " + mAuthCode);
+            logMessage("authProvider: " + mAuthProvider);
+
+            final Dialog dialog = new Dialog(context);
+            dialog.setContentView(R.layout.dialog_entry);
+            dialog.setTitle("SignUp Acccount IP Address");
+            final EditText ip = (EditText) dialog
+                    .findViewById(R.id.EditTextEntry);
+            if (RemoteAddress != null) {
+                ip.setText(RemoteAddress);
+            }
+            Button dialogButton = (Button) dialog
+                    .findViewById(R.id.entryButtonOK);
+            dialogButton.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    dialog.dismiss();
+                    RemoteAddress = ip.getText().toString();
+                    CIServer = CI_SERVER_PREFIX + RemoteAddress;
+                    logMessage("server address for signup is: \n" + CIServer);
+                    try {
+                        mAccountManager = OcPlatform
+                                .constructAccountManagerObject(CIServer, EnumSet
+                                        .of(OcConnectivityType.CT_ADAPTER_TCP));
+                        logMessage("Calling signup API");
+
+                        if (mAuthProvider.equals("samsung")
+                                || mAuthProvider.equals("samsung-us")) {
+                            logMessage("Auth provider is samsung");
+                            Map<String, String> options = new HashMap<>();
+                            options.put("auth_server_url",
+                                    "us-auth2.samsungosp.com");
+                            options.put("api_server_url",
+                                    "us-auth2.samsungosp.com");
+                            mAccountManager.signUp(mAuthProvider, mAuthCode,
+                                    options, onSignUp);
+                        } else {
+                            mAccountManager.signUp(mAuthProvider, mAuthCode,
+                                    onSignUp);
+                        }
+                    } catch (OcException e) {
+                        e.printStackTrace();
+                    }
+                }
+            });
+            dialog.show();
+        }
+    }
+
+    OcResource.OnPostListener onRefreshTokenPost = new OcResource.OnPostListener() {
+        @Override
+        public void onPostCompleted(List<OcHeaderOption> list,
+                OcRepresentation ocRepresentation) {
+            logMessage("RefreshToken Completed.");
+            try {
+                mAccessToken = ocRepresentation.getValue("accesstoken");
+                mRefreshtoken = ocRepresentation.getValue("refreshtoken");
+            } catch (OcException e) {
+                e.printStackTrace();
+            }
+            signIn();
+        }
+
+        @Override
+        public void onPostFailed(Throwable throwable) {
+            logMessage("RefreshToken failed.");
+            Log.d(TAG, "onRefreshTokenPost failed..");
+        }
+    };
+
+    public void refreshToken() {
+
+        if (deviceID == null) {
+            final Dialog dialog = new Dialog(context);
+            dialog.setContentView(R.layout.dialog_entry);
+            dialog.setTitle("Enter Device Id");
+            dialog.setCanceledOnTouchOutside(false);
+            final EditText id = (EditText) dialog
+                    .findViewById(R.id.EditTextEntry);
+
+            Button dialogButton = (Button) dialog
+                    .findViewById(R.id.entryButtonOK);
+            dialogButton.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    dialog.dismiss();
+                    deviceID = id.getText().toString();
+                }
+            });
+            dialog.show();
+        }
+        try {
+            OcResource authResource = OcPlatform.constructResourceObject(
+                    CIServer, "/.well-known/ocf/account/tokenrefresh",
+                    EnumSet.of(OcConnectivityType.CT_ADAPTER_TCP,
+                            OcConnectivityType.CT_IP_USE_V4),
+                    false, Arrays.asList("oic.wk.account"),
+                    Arrays.asList(OcPlatform.DEFAULT_INTERFACE));
+            OcRepresentation rep = new OcRepresentation();
+
+            showToast("RefreshToken in progress..");
+            logMessage("RefreshToken in progress..");
+            rep.setValue("di", deviceID);
+            rep.setValue("granttype", "refresh_token");
+            rep.setValue("refreshtoken", mRefreshtoken);
+            rep.setValue("uid", mUserID);
+            authResource.post(rep, new HashMap<String, String>(),
+                    onRefreshTokenPost);
+        } catch (OcException e) {
+            e.printStackTrace();
+        }
+
+        Log.d(TAG, "No error while executing login");
+    }
+}
diff --git a/service/notification/examples/android/NotiConsumerExample/app/src/main/res/layout/activity_login.xml b/service/notification/examples/android/NotiConsumerExample/app/src/main/res/layout/activity_login.xml
new file mode 100755 (executable)
index 0000000..dfd8e3c
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/loginLayout"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    tools:context=".LoginActivity">
+
+    <WebView
+        android:id="@+id/webView"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="visible" />
+
+</LinearLayout>
\ No newline at end of file
index b924bc2..bea595b 100755 (executable)
@@ -7,8 +7,12 @@
     android:paddingLeft="@dimen/activity_horizontal_margin"\r
     android:paddingRight="@dimen/activity_horizontal_margin"\r
     android:paddingTop="@dimen/activity_vertical_margin"\r
-    tools:context="com.sec.noticonsumerexample.MainActivity">\r
+    tools:context=".MainActivity">\r
 \r
+    <ScrollView\r
+        android:layout_width="match_parent"\r
+        android:layout_height="wrap_content"\r
+        android:fillViewport="true">\r
     <LinearLayout\r
         android:layout_width="match_parent"\r
         android:layout_height="wrap_content"\r
             android:layout_height="wrap_content"\r
             android:paddingLeft="5dp"\r
             android:paddingRight="5dp"\r
+            android:orientation="horizontal"\r
+            android:weightSum="1">\r
+\r
+            <Button\r
+                android:layout_height="wrap_content"\r
+                android:layout_width="150dp"\r
+                android:id="@+id/BtnSubscribe"\r
+                android:text="Subscribe"/>\r
+            <Button\r
+                android:layout_height="wrap_content"\r
+                android:layout_width="150dp"\r
+                android:id="@+id/BtnUnsubscribe"\r
+                android:text="Unsubscribe" />\r
+        </LinearLayout>\r
+        <LinearLayout\r
+            android:layout_width="match_parent"\r
+            android:layout_height="wrap_content"\r
+            android:paddingLeft="5dp"\r
+            android:paddingRight="5dp"\r
+            android:orientation="horizontal"\r
+            android:weightSum="1">\r
+\r
+            <Button\r
+                android:layout_height="wrap_content"\r
+                android:layout_width="100dp"\r
+                android:id="@+id/signup"\r
+                android:text="Sign Up"/>\r
+\r
+            <Button\r
+                android:layout_height="wrap_content"\r
+                android:layout_width="100dp"\r
+                android:id="@+id/signin"\r
+                android:text="Sign In" />\r
+            <Button\r
+                android:layout_height="wrap_content"\r
+                android:layout_width="100dp"\r
+                android:id="@+id/signout"\r
+                android:text="Sign Out" />\r
+        </LinearLayout>\r
+        <LinearLayout\r
+            android:layout_width="match_parent"\r
+            android:layout_height="wrap_content"\r
+            android:paddingLeft="5dp"\r
+            android:paddingRight="5dp"\r
+            android:orientation="horizontal"\r
+            android:weightSum="1">\r
+\r
+            <Button\r
+                android:layout_height="wrap_content"\r
+                android:layout_width="150dp"\r
+                android:id="@+id/BtnEnableRemoteService"\r
+                android:text="Enable Remote Service"/>\r
+\r
+            <Button\r
+                android:layout_height="wrap_content"\r
+                android:layout_width="150dp"\r
+                android:id="@+id/subscribeMQService"\r
+                android:text="Subscribe MQ Service" />\r
+        </LinearLayout>\r
+        <LinearLayout\r
+            android:layout_width="match_parent"\r
+            android:layout_height="wrap_content"\r
+            android:paddingLeft="5dp"\r
+            android:paddingRight="5dp"\r
             android:orientation="vertical" >\r
             <LinearLayout\r
                 android:layout_width="match_parent"\r
                 android:orientation="vertical" >\r
             <Button\r
                 android:layout_gravity="center_vertical|center_horizontal"\r
-                android:layout_height="1dp"\r
-                android:layout_width="match_parent"\r
-                android:id="@+id/BtnEnableRemoteService"\r
-                android:text="Enable Remote Service"/>\r
-            <Button\r
-                android:layout_gravity="center_vertical|center_horizontal"\r
                 android:layout_height="60dp"\r
                 android:layout_width="match_parent"\r
                 android:id="@+id/BtnUpdateTopicList"\r
             android:background="@android:color/darker_gray"/>\r
 \r
     </LinearLayout>\r
-\r
-\r
+    </ScrollView>\r
 </RelativeLayout>\r
diff --git a/service/notification/examples/android/NotiConsumerExample/app/src/main/res/layout/dialog_auth.xml b/service/notification/examples/android/NotiConsumerExample/app/src/main/res/layout/dialog_auth.xml
new file mode 100644 (file)
index 0000000..6e4dcba
--- /dev/null
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent" >
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingLeft="1dp"
+        android:paddingRight="1dp"
+        android:orientation="vertical" >
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingLeft="5dp"
+        android:paddingRight="5dp"
+        android:orientation="horizontal" >
+
+        <Button
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:id="@+id/BtnAuth"
+            android:text="@string/btn_auth"
+            android:onClick="selfDestruct" />
+
+        <EditText
+            android:id="@+id/EditTextAuth"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:windowSoftInputMode="stateHidden"
+            android:hint="Add Auth Provider Name" />
+    </LinearLayout>
+
+    <LinearLayout
+        android:id="@+id/LinearBody"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingLeft="5dp"
+        android:paddingRight="5dp"
+        android:orientation="horizontal" >
+
+        <Button
+            android:layout_height="wrap_content"
+            android:layout_width="wrap_content"
+            android:id="@+id/BtnUrl"
+            android:text="@string/btn_url"
+            android:onClick="selfDestruct" />
+
+        <EditText
+            android:id="@+id/EditTextUrl"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:windowSoftInputMode="stateHidden"
+            android:hint="Add Login Account URL" />
+    </LinearLayout>
+
+    <Button
+        android:layout_gravity="center_vertical|center_horizontal"
+        android:layout_height="wrap_content"
+        android:layout_width="match_parent"
+        android:id="@+id/dialogButtonOK"
+        android:text="@string/btn_ok"
+        />
+    </LinearLayout>
+
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/service/notification/examples/android/NotiConsumerExample/app/src/main/res/layout/dialog_entry.xml b/service/notification/examples/android/NotiConsumerExample/app/src/main/res/layout/dialog_entry.xml
new file mode 100644 (file)
index 0000000..f2a147a
--- /dev/null
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent" >
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingLeft="1dp"
+        android:paddingRight="1dp"
+        android:orientation="vertical" >
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingLeft="5dp"
+            android:paddingRight="5dp"
+            android:orientation="horizontal" >
+
+            <EditText
+                android:id="@+id/EditTextEntry"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:windowSoftInputMode="stateHidden"
+                android:hint="Add Required Details" />
+        </LinearLayout>
+
+
+        <Button
+            android:layout_gravity="center_vertical|center_horizontal"
+            android:layout_height="wrap_content"
+            android:layout_width="match_parent"
+            android:id="@+id/entryButtonOK"
+            android:text="@string/btn_ok"
+            />
+    </LinearLayout>
+
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/service/notification/examples/android/NotiConsumerExample/app/src/main/res/layout/dialog_mq.xml b/service/notification/examples/android/NotiConsumerExample/app/src/main/res/layout/dialog_mq.xml
new file mode 100644 (file)
index 0000000..4c2d9c4
--- /dev/null
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent" >
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingLeft="1dp"
+        android:paddingRight="1dp"
+        android:orientation="vertical" >
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingLeft="5dp"
+            android:paddingRight="5dp"
+            android:orientation="horizontal" >
+
+            <Button
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:id="@+id/BtnAuth"
+                android:text="@string/btn_addr"
+                android:onClick="selfDestruct" />
+
+            <EditText
+                android:id="@+id/EditTextIp"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:windowSoftInputMode="stateHidden"
+                android:hint="Add MQ Server IP Address" />
+        </LinearLayout>
+
+        <LinearLayout
+            android:id="@+id/LinearBody"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingLeft="5dp"
+            android:paddingRight="5dp"
+            android:orientation="horizontal" >
+
+            <Button
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:id="@+id/BtnTopic"
+                android:text="@string/btn_topic"
+                android:onClick="selfDestruct" />
+
+            <EditText
+                android:id="@+id/EditTextMqTopic"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:windowSoftInputMode="stateHidden"
+                android:hint="Add MQ Topic name" />
+        </LinearLayout>
+
+        <Button
+            android:layout_gravity="center_vertical|center_horizontal"
+            android:layout_height="wrap_content"
+            android:layout_width="match_parent"
+            android:id="@+id/mqButtonOK"
+            android:text="@string/btn_ok"
+            />
+    </LinearLayout>
+
+
+</RelativeLayout>
\ No newline at end of file
index 1841f5a..ab0ae3e 100755 (executable)
@@ -1,7 +1,8 @@
 <resources>\r
     <string name="app_name">NotificationConsumerExample</string>\r
-    <string name="btn_title">Title</string>\r
-    <string name="btn_body">Body</string>\r
-    <string name="btn_send">Send Notification</string>\r
-    <string name="btn_create_noti">Create Notification</string>\r
+    <string name="btn_auth">Auth</string>\r
+    <string name="btn_url"> URL</string>\r
+    <string name="btn_ok">Enter Details</string>\r
+    <string name="btn_addr"> Addr. </string>\r
+    <string name="btn_topic">Topic</string>\r
 </resources>\r
index 4d4c8af..fa506be 100644 (file)
@@ -77,8 +77,8 @@ jdk_env['BUILDERS']['Gradle'] = Builder(action = env.get('ANDROID_GRADLE') +
     emitter = ensure_libs)
 jdk_env['BUILD_DIR'] = env.get('BUILD_DIR')
 cmdBuildNotificationProviderApp=jdk_env.Gradle(target="app/apk", 
-    source=["app/src/main/java/com/sec/notiproviderexample/MainActivity.java",
-            "app/src/main/java/com/sec/notiproviderexample/NotiListener.java",
-            "app/src/main/java/com/sec/notiproviderexample/ProviderSample.java"])
-
+    source=["app/src/main/java/org/iotivity/service/ns/sample/provider/MainActivity.java",
+            "app/src/main/java/org/iotivity/service/ns/sample/provider/NotiListener.java",
+            "app/src/main/java/org/iotivity/service/ns/sample/provider/ProviderSample.java"])
+jdk_env.Clean(cmdBuildNotificationProviderApp, '#/service/notification/examples/android/NotiProviderExample/build')
 Depends(cmdBuildNotificationProviderApp, env.get('notificationAAR'))
index e4f0d31..af0dba5 100755 (executable)
@@ -10,10 +10,15 @@ android {
         pickFirst 'lib/x86/libocstack-jni.so'
         pickFirst 'lib/x86_64/libocstack-jni.so'
         pickFirst 'lib/arm64-v8a/libocstack-jni.so'
+        pickFirst 'lib/armeabi/libresource_directory.so'
+        pickFirst 'lib/armeabi-v7a/libresource_directory.so'
+        pickFirst 'lib/x86/libresource_directory.so'
+        pickFirst 'lib/x86_64/libresource_directory.so'
+        pickFirst 'lib/arm64-v8a/libresource_directory.so'
     }
 
     defaultConfig {
-        applicationId "sample.notification.service.iotivity.org.notificationsample"
+        applicationId "sample.notification.service.iotivity.org.notificationprovidersample"
         minSdkVersion 21
         targetSdkVersion 21
         versionCode 1
diff --git a/service/notification/examples/android/NotiProviderExample/app/src/androidTest/java/org/iotivity/service/ns/sample/provider/ConsumerSimulator.java b/service/notification/examples/android/NotiProviderExample/app/src/androidTest/java/org/iotivity/service/ns/sample/provider/ConsumerSimulator.java
new file mode 100644 (file)
index 0000000..008a1e7
--- /dev/null
@@ -0,0 +1,89 @@
+//******************************************************************
+//
+// Copyright 2016 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+package org.iotivity.service.ns.sample.provider;
+
+import android.util.Log;
+
+import org.iotivity.service.ns.common.Message;
+import org.iotivity.service.ns.common.SyncInfo;
+import org.iotivity.service.ns.consumer.ConsumerService;
+import org.iotivity.service.ns.consumer.Provider;
+
+import java.util.concurrent.CountDownLatch;
+
+class ConsumerSimulator implements ConsumerService.OnProviderDiscoveredListener,
+        Provider.OnProviderStateListener, Provider.OnMessageReceivedListener,
+        Provider.OnSyncInfoReceivedListener {
+    private String         TAG = "Consumer Simulator";
+    private Provider       mProvider;
+    private CountDownLatch mLockObject;
+    private Response       mResponse;
+    private String         mExpectCb;
+
+    public void set(CountDownLatch lockObject, Response response, String name) {
+        Log.i(TAG, "Setting lock Simulator: ");
+        mLockObject = lockObject;
+        mResponse = response;
+        mExpectCb = name;
+    }
+
+    @Override
+    public void onProviderDiscovered(Provider provider) {
+        mProvider = provider;
+        try {
+            provider.setListener(this, this, this);
+            if (!provider.isSubscribed()) {
+                provider.subscribe();
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    @Override
+    public void onProviderStateReceived(Provider.ProviderState providerState) {
+    }
+
+    @Override
+    public void onMessageReceived(Message message) {
+        if (mExpectCb == "msg") {
+            mResponse.set(true);
+            mLockObject.countDown();
+        }
+    }
+
+    @Override
+    public void onSyncInfoReceived(SyncInfo syncInfo) {
+        if (mExpectCb == "sync") {
+            mResponse.set(true);
+            mLockObject.countDown();
+        }
+    }
+
+    public void sendSyncInfo(long id, SyncInfo.SyncType type) {
+        try {
+            mProvider.sendSyncInfo(id, type);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}
\ No newline at end of file
diff --git a/service/notification/examples/android/NotiProviderExample/app/src/androidTest/java/org/iotivity/service/ns/sample/provider/ExampleUnitTest.java b/service/notification/examples/android/NotiProviderExample/app/src/androidTest/java/org/iotivity/service/ns/sample/provider/ExampleUnitTest.java
new file mode 100755 (executable)
index 0000000..701929b
--- /dev/null
@@ -0,0 +1,449 @@
+/*
+* Copyright 2016 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.
+*/
+
+package org.iotivity.service.ns.sample.provider;
+
+import java.util.Iterator;
+import java.util.Vector;
+import java.util.concurrent.CountDownLatch;
+
+import android.app.Application;
+import android.content.Context;
+import android.test.ApplicationTestCase;
+import android.util.Log;
+
+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 org.iotivity.service.ns.common.NSException;
+import org.iotivity.service.ns.common.NSErrorCode;
+import org.iotivity.service.ns.common.SyncInfo;
+import org.iotivity.service.ns.common.Topic;
+
+import android.support.test.runner.AndroidJUnit4;
+
+import org.iotivity.service.ns.consumer.ConsumerService;
+import org.iotivity.service.ns.provider.Consumer;
+import org.iotivity.service.ns.provider.ProviderService;
+import org.junit.After;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.Before;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * To work on unit tests, switch the Test Artifact in the Build Variants view.
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleUnitTest extends ApplicationTestCase<Application> {
+    public ExampleUnitTest() {
+        super(Application.class);
+    }
+
+    private static Context                      mContext = null;
+    private static SubscriptionCallbackListener subCb;
+    private static SyncCallbackListener         syncCb;
+    private CountDownLatch                      lockObject;
+    private Response                            response;
+    private static ProviderService              gProviderRes;
+    private static ConsumerService              gConsumerRes;
+    private static ConsumerSimulator            gConsumerSim;
+    private static String                       TAG      = "UnitTest ProviderService";
+
+    public void start(boolean subControllability) {
+        try {
+            gProviderRes.start(subCb, syncCb, subControllability, "ok", false);
+            gConsumerRes.start(gConsumerSim);
+            lockObject.await(4000, TimeUnit.MILLISECONDS);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public org.iotivity.service.ns.common.Message createMessage() {
+        org.iotivity.service.ns.common.Message msg = null;
+        try {
+            msg = gProviderRes.createMessage();
+            msg.setTitle("Title");
+            msg.setSourceName("Source");
+            msg.setContentText("ContentText");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return msg;
+    }
+
+    public org.iotivity.service.ns.common.Message sendMessage(
+            boolean accepted) {
+        lockObject = new CountDownLatch(1);
+        response = new Response();
+        org.iotivity.service.ns.common.Message msg = null;
+        gConsumerSim.set(lockObject, response, "msg");
+        try {
+            subCb.get().acceptSubscription(accepted);
+            CountDownLatch waitLock = new CountDownLatch(1);
+            waitLock.await(400, TimeUnit.MILLISECONDS);
+            msg = createMessage();
+            gProviderRes.sendMessage(msg);
+            lockObject.await(4000, TimeUnit.MILLISECONDS);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return msg;
+    }
+
+    @BeforeClass
+    public static void Initialize() {
+        PlatformConfig platformConfig = new PlatformConfig(mContext,
+                ServiceType.IN_PROC, ModeType.CLIENT_SERVER, "0.0.0.0",
+                0, // Uses randomly available port
+                QualityOfService.LOW);
+
+        OcPlatform.Configure(platformConfig);
+        try {
+            OcPlatform.stopPresence(); // Initialize OcPlatform
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Before
+    public void SetUp() {
+        Log.i(TAG, "SetUp - IN");
+        subCb = new SubscriptionCallbackListener();
+        syncCb = new SyncCallbackListener();
+        gConsumerRes = ConsumerService.getInstance();
+        gProviderRes = ProviderService.getInstance();
+        gConsumerSim = new ConsumerSimulator();
+        lockObject = new CountDownLatch(1);
+        response = new Response();
+        subCb.set(lockObject, response);
+        Log.i(TAG, "SetUp - OUT");
+    }
+
+    @After
+    public void TearDown() {
+        Log.i(TAG, "TearDown - IN");
+        try {
+            gProviderRes.stop();
+            gConsumerRes.stop();
+            lockObject = new CountDownLatch(1);
+            lockObject.await(2000, TimeUnit.MILLISECONDS);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        Log.i(TAG, "TearDown - OUT");
+    }
+
+    @Test
+    public void StartProviderPositiveWithPolicyTrue() {
+        try {
+            gProviderRes.start(subCb, syncCb, true, "ok", false);
+            gProviderRes.stop();
+        } catch (NSException e) {
+            e.printStackTrace();
+            assertEquals(NSErrorCode.OK, e.getErrorCode());
+        }
+    }
+
+    @Test
+    public void StartProviderPositiveWithPolicyFalse() {
+        try {
+            gProviderRes.start(subCb, syncCb, false, "ok", false);
+            gProviderRes.stop();
+        } catch (NSException e) {
+            e.printStackTrace();
+            assertEquals(NSErrorCode.OK, e.getErrorCode());
+        }
+    }
+
+    @Test
+    public void StopProviderPositive() {
+        try {
+            gProviderRes.start(subCb, syncCb, true, "ok", false);
+            gProviderRes.stop();
+        } catch (NSException e) {
+            e.printStackTrace();
+            assertEquals(NSErrorCode.OK, e.getErrorCode());
+        }
+    }
+
+    @Test
+    public void ExpectCallbackWhenReceiveSubscribeRequestWithAccepterProvider() {
+        start(true);
+        assertEquals(true, response.get());
+    }
+
+    @Test
+    public void NeverCallNotifyOnConsumerByAcceptIsFalse() {
+        start(true);
+        assertEquals(true, response.get());
+        sendMessage(false);
+        assertEquals(false, response.get());
+    }
+
+    @Test
+    public void ExpectCallNotifyOnConsumerByAcceptIsTrue() {
+
+        start(true);
+        assertEquals(true, response.get());
+        sendMessage(true);
+        assertEquals(true, response.get());
+    }
+
+    @Test
+    public void ExpectCallbackSyncOnReadToConsumer() {
+        start(true);
+        assertEquals(true, response.get());
+        org.iotivity.service.ns.common.Message msg = sendMessage(true);
+        assertEquals(true, response.get());
+        try {
+            lockObject = new CountDownLatch(1);
+            response = new Response();
+            gConsumerSim.set(lockObject, response, "sync");
+            gProviderRes.sendSyncInfo(msg.getMessageId(),
+                    SyncInfo.SyncType.READ);
+            lockObject.await(4000, TimeUnit.MILLISECONDS);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        assertEquals(true, response.get());
+    }
+
+    @Test
+    public void ExpectCallbackSyncOnReadFromConsumer() {
+
+        start(true);
+        assertEquals(true, response.get());
+        org.iotivity.service.ns.common.Message msg = sendMessage(true);
+        assertEquals(true, response.get());
+        try {
+            lockObject = new CountDownLatch(1);
+            response = new Response();
+            syncCb.set(lockObject, response);
+            gConsumerSim.sendSyncInfo(msg.getMessageId(),
+                    SyncInfo.SyncType.READ);
+            lockObject.await(4000, TimeUnit.MILLISECONDS);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Test
+    public void ExpectEqualAddedTopicsAndRegisteredTopics() {
+        boolean isSame = true;
+        String str[] = { "TOPIC1", "TOPIC2" };
+        try {
+            gProviderRes.start(subCb, syncCb, true, "ok", false);
+            gProviderRes.registerTopic(str[0]);
+            gProviderRes.registerTopic(str[1]);
+            Vector<Topic> list = gProviderRes.getRegisteredTopicList()
+                    .getTopicsList();
+            Iterator<Topic> it = list.iterator();
+            if (list.size() != 2) {
+                isSame = false;
+                Log.i(TAG, "Size is " + list.size());
+            }
+            int count = 0;
+            while (it.hasNext()) {
+                Topic element = it.next();
+                Log.i(TAG, "element is " + element.getTopicName());
+                if (!str[count].equals(element.getTopicName())) {
+                    isSame = false;
+                }
+                count++;
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        assertEquals(true, isSame);
+    }
+
+    @Test
+    public void ExpectEqualUnregisteredTopicsAndRegisteredTopics() {
+        boolean isSame = true;
+        String str[] = { "TOPIC1", "TOPIC2" };
+        try {
+            gProviderRes.start(subCb, syncCb, true, "ok", false);
+            gProviderRes.registerTopic(str[0]);
+            gProviderRes.registerTopic(str[1]);
+            gProviderRes.unregisterTopic(str[0]);
+            Vector<Topic> list = gProviderRes.getRegisteredTopicList()
+                    .getTopicsList();
+            Iterator<Topic> it = list.iterator();
+            if (list.size() != 1) {
+                isSame = false;
+                Log.i(TAG, "Size is " + list.size());
+            }
+            int count = 1;
+            while (it.hasNext()) {
+                Topic element = it.next();
+                Log.i(TAG, "element is " + element.getTopicName());
+                if (!str[count].equals(element.getTopicName())) {
+                    isSame = false;
+                }
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        assertEquals(true, isSame);
+    }
+
+    @Test
+    public void ExpectEqualSetConsumerTopicsAndGetConsumerTopics() {
+        boolean isSame = false;
+        start(true);
+        assertEquals(true, response.get());
+        String str[] = { "TOPIC1", "TOPIC2" };
+        try {
+            gProviderRes.registerTopic(str[0]);
+            gProviderRes.registerTopic(str[1]);
+            subCb.get().setTopic(str[0]);
+
+            Vector<Topic> list = subCb.get().getConsumerTopicList()
+                    .getTopicsList();
+            Iterator<Topic> it = list.iterator();
+            int count = 0;
+            String[] compStr = new String[10];
+            Topic.TopicState[] state = new Topic.TopicState[10];
+            while (it.hasNext()) {
+                Topic element = it.next();
+                Log.i(TAG, "element is " + element.getTopicName());
+                compStr[count] = element.getTopicName();
+                state[count++] = element.getState();
+            }
+            if (compStr[0].compareTo(str[0]) == 0
+                    && compStr[1].compareTo(str[1]) == 0
+                    && state[0] == Topic.TopicState.SUBSCRIBED
+                    && state[1] == Topic.TopicState.UNSUBSCRIBED) {
+                isSame = true;
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        assertEquals(true, isSame);
+    }
+
+    @Test
+    public void ExpectEqualUnSetConsumerTopicsAndGetConsumerTopics() {
+        boolean isSame = false;
+        start(true);
+        assertEquals(true, response.get());
+        String str[] = { "TOPIC1", "TOPIC2" };
+        try {
+            gProviderRes.registerTopic(str[0]);
+            gProviderRes.registerTopic(str[1]);
+            subCb.get().setTopic(str[0]);
+            subCb.get().setTopic(str[1]);
+            subCb.get().unsetTopic(str[0]);
+
+            Vector<Topic> list = subCb.get().getConsumerTopicList()
+                    .getTopicsList();
+            Iterator<Topic> it = list.iterator();
+            int count = 0;
+            String[] compStr = new String[10];
+            Topic.TopicState[] state = new Topic.TopicState[10];
+            while (it.hasNext()) {
+                Topic element = it.next();
+                Log.i(TAG, "element is " + element.getTopicName());
+                compStr[count] = element.getTopicName();
+                state[count++] = element.getState();
+            }
+            if (compStr[0].compareTo(str[0]) == 0
+                    && compStr[1].compareTo(str[1]) == 0
+                    && state[0] == Topic.TopicState.UNSUBSCRIBED
+                    && state[1] == Topic.TopicState.SUBSCRIBED) {
+                isSame = true;
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        assertEquals(true, isSame);
+    }
+
+}
+
+class SubscriptionCallbackListener
+        implements ProviderService.OnConsumerSubscribedListener {
+    private CountDownLatch mLockObject;
+    private Response       mResponse;
+    private Consumer       mConsumer;
+    private static String  TAG = "UnitTest SubscriptionCallbackListener";
+
+    @Override
+    public void onConsumerSubscribed(Consumer consumer) {
+        Log.i(TAG, "onConsumerSubscribed");
+        mConsumer = consumer;
+        if (mResponse != null) {
+            mResponse.set(true);
+            mLockObject.countDown();
+        }
+    }
+
+    public void set(CountDownLatch lockObject, Response response) {
+        mLockObject = lockObject;
+        mResponse = response;
+    }
+
+    public Consumer get() {
+        return mConsumer;
+    }
+}
+
+class SyncCallbackListener
+        implements ProviderService.OnMessageSynchronizedListener {
+    private CountDownLatch mLockObject;
+    private Response       mResponse;
+    private static String  TAG = "UnitTest SyncCallbackListener";
+
+    @Override
+    public void onMessageSynchronized(SyncInfo syncInfo) {
+        Log.i(TAG, "onMessageSynchronized");
+        if (mResponse != null) {
+            mResponse.set(true);
+            mLockObject.countDown();
+        }
+    }
+
+    public void set(CountDownLatch lockObject, Response response) {
+        mLockObject = lockObject;
+        mResponse = response;
+    }
+}
+
+class Response {
+    private boolean state;
+
+    Response() {
+        state = false;
+    }
+
+    public void set(boolean val) {
+        state = val;
+    }
+
+    public boolean get() {
+        return state;
+    }
+}
old mode 100644 (file)
new mode 100755 (executable)
index bc14e47..7134850
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>\r
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"\r
-    package="com.sec.notiproviderexample">\r
+    package="org.iotivity.service.ns.sample.provider">\r
 \r
     <uses-feature android:name="android.hardware.nfc" />\r
     <uses-permission android:name="android.permission.READ_PHONE_STATE" />\r
@@ -29,9 +29,9 @@
                 <category android:name="android.intent.category.LAUNCHER" />\r
             </intent-filter>\r
         </activity>\r
-\r
+        <activity android:name=".LoginActivity" />\r
         <service\r
-            android:name="com.sec.notiproviderexample.NotiListener"\r
+            android:name=".NotiListener"\r
             android:label="@string/app_name"\r
             android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">\r
 \r
diff --git a/service/notification/examples/android/NotiProviderExample/app/src/main/java/com/sec/notiproviderexample/MainActivity.java b/service/notification/examples/android/NotiProviderExample/app/src/main/java/com/sec/notiproviderexample/MainActivity.java
deleted file mode 100755 (executable)
index 5d033fc..0000000
+++ /dev/null
@@ -1,292 +0,0 @@
-/*\r
-//******************************************************************\r
-//\r
-// Copyright 2016 Samsung Electronics All Rights Reserved.\r
-//\r
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
-//\r
-// Licensed under the Apache License, Version 2.0 (the "License");\r
-// you may not use this file except in compliance with the License.\r
-// You may obtain a copy of the License at\r
-//\r
-//      http://www.apache.org/licenses/LICENSE-2.0\r
-//\r
-// Unless required by applicable law or agreed to in writing, software\r
-// distributed under the License is distributed on an "AS IS" BASIS,\r
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-// See the License for the specific language governing permissions and\r
-// limitations under the License.\r
-//\r
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
- */\r
-\r
-package com.sec.notiproviderexample;\r
-\r
-import android.app.Notification;\r
-import android.app.NotificationManager;\r
-import android.content.Intent;\r
-import android.os.Bundle;\r
-import android.os.Handler;\r
-import android.os.Message;\r
-import android.util.Log;\r
-import android.view.View;\r
-import android.widget.Button;\r
-import android.widget.EditText;\r
-import android.widget.RadioButton;\r
-import android.widget.TextView;\r
-import android.widget.Toast;\r
-import android.app.Activity;\r
-\r
-import org.iotivity.service.ns.common.MediaContents;\r
-\r
-import java.text.DateFormat;\r
-import java.util.Date;\r
-\r
-public class MainActivity extends Activity {\r
-\r
-    private final String TAG = "NS_MAIN_ACTIVITY";\r
-    private static final int CONSUMER_SUBSCRIBED = 1;\r
-    private static final int MESSAGE_SYNC = 2;\r
-    private static final int MESSAGE_NOTIFICATION = 3;\r
-\r
-    private Button btnTitle;\r
-    private Button btnBody;\r
-    private Button btnTopic;\r
-    private Button btnSend;\r
-    private Button btnStart;\r
-    private Button btnRegister;\r
-    private Button btnSet;\r
-    private Button btnStop;\r
-    private Button btnLog;\r
-    private EditText editTextTitle;\r
-    private EditText editTextBody;\r
-    private EditText editTextTopic;\r
-    private RadioButton radioProvider;\r
-    private RadioButton radioConsumer;\r
-    private static TextView TvLog;\r
-\r
-    private static int notiId = 100;\r
-    private static int subCnt = 0;\r
-    private boolean isStarted = false;\r
-    private String consumerId;\r
-    private boolean gAcceptor = true;\r
-\r
-    private NotiListener mNotiListener = null;\r
-    private ProviderSample mProviderSample = null;\r
-\r
-    public static Handler mHandler = new Handler() {\r
-        @Override\r
-        public void handleMessage(Message msg) {\r
-            switch (msg.what) {\r
-                case CONSUMER_SUBSCRIBED:\r
-                    String ConsumerId = (String) msg.obj;\r
-                    if(ConsumerId != null)\r
-                        TvLog.append("Consumer Subscibed: " + ConsumerId + "\n");\r
-                    break;\r
-\r
-                case MESSAGE_SYNC:\r
-                    String sync = (String) msg.obj;\r
-                    if(sync != null)\r
-                        TvLog.append("SyncInfo Received :" + sync + "\n");\r
-                    break;\r
-\r
-                default:\r
-                    break;\r
-            }\r
-        }\r
-    };\r
-\r
-    public void showToast(final String toast)\r
-    {\r
-        runOnUiThread(new Runnable() {\r
-            @Override\r
-            public void run() {\r
-                Toast.makeText(getApplicationContext(), toast, Toast.LENGTH_SHORT).show();\r
-            }\r
-        });\r
-    }\r
-\r
-    @Override\r
-    protected void onCreate(Bundle savedInstanceState) {\r
-        super.onCreate(savedInstanceState);\r
-        setContentView(R.layout.activity_main);\r
-\r
-        btnTitle = (Button) findViewById(R.id.BtnTitle);\r
-        btnBody = (Button) findViewById(R.id.BtnBody);\r
-        btnTopic = (Button) findViewById(R.id.BtnTopic);\r
-        btnSend = (Button) findViewById(R.id.BtnCreateNoti);\r
-\r
-        btnStart = (Button) findViewById(R.id.BtnStart);\r
-        btnRegister = (Button) findViewById(R.id.BtnRegister);\r
-        btnSet = (Button) findViewById(R.id.BtnSet);\r
-        btnLog = (Button) findViewById(R.id.BtnLog);\r
-        btnStop = (Button) findViewById(R.id.BtnStop);\r
-\r
-        editTextTitle = (EditText) findViewById(R.id.EditTextTitle);\r
-        editTextBody = (EditText) findViewById(R.id.EditTextBody);\r
-        editTextTopic = (EditText) findViewById(R.id.EditTextTopic);\r
-\r
-        radioProvider = (RadioButton) findViewById(R.id.RadioProvider);\r
-        radioConsumer = (RadioButton) findViewById(R.id.RadioConsumer);\r
-\r
-        TvLog = (TextView) findViewById(R.id.TvLog);\r
-\r
-        btnTitle.setEnabled(false);\r
-        btnBody.setEnabled(false);\r
-        btnTopic.setEnabled(false);\r
-\r
-        btnSend.setOnClickListener(mClickListener);\r
-        btnStart.setOnClickListener(mClickListener);\r
-        btnRegister.setOnClickListener(mClickListener);\r
-        btnSet.setOnClickListener(mClickListener);\r
-        btnLog.setOnClickListener(mClickListener);\r
-        btnStop.setOnClickListener(mClickListener);\r
-        radioProvider.setOnClickListener(mClickListener);\r
-        radioConsumer.setOnClickListener(mClickListener);\r
-\r
-        mProviderSample = new ProviderSample(getApplicationContext());\r
-        mProviderSample.setHandler(mHandler);\r
-\r
-        mNotiListener = new NotiListener(this);\r
-\r
-        Intent intent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");\r
-        startActivity(intent);\r
-    }\r
-\r
-    @Override\r
-    protected void onDestroy() {\r
-        super.onDestroy();\r
-    }\r
-\r
-    public ProviderSample getProviderSample()\r
-    {\r
-        return mProviderSample;\r
-    }\r
-\r
-    Button.OnClickListener mClickListener = new View.OnClickListener() {\r
-        public void onClick(View v) {\r
-            switch (v.getId()) {\r
-                case R.id.RadioProvider: {\r
-                    if (isStarted == false) {\r
-                        gAcceptor = true;\r
-                        showToast("Provider as acceptor is " + gAcceptor);\r
-                    }\r
-                    else\r
-                        showToast("Start ProviderService again to change acceptor as provider");\r
-                }\r
-                break;\r
-\r
-                case R.id.RadioConsumer: {\r
-                    if (isStarted == false) {\r
-                        gAcceptor = false;\r
-                        showToast("Provider as acceptor is "+ gAcceptor);\r
-                    }\r
-                    else\r
-                        showToast("Start ProviderService again to change acceptor as consumer");\r
-                }\r
-                break;\r
-\r
-                case R.id.BtnStart: {\r
-                    if (isStarted == false) {\r
-                        Log.i(TAG, "Start  Provider Service");\r
-                        TvLog.setText("Start Provider Service\n");\r
-                        mProviderSample.Start(gAcceptor);\r
-                        isStarted = true;\r
-                        radioProvider.setEnabled(false);\r
-                        radioConsumer.setEnabled(false);\r
-                    } else {\r
-                        Log.e(TAG, " Provider Service had already started");\r
-                        showToast(" Provider Service had already started");\r
-                    }\r
-                }\r
-                break;\r
-\r
-                case R.id.BtnRegister: {\r
-                    if (isStarted == false) {\r
-                        Log.i(TAG, "Start  Provider Service");\r
-                        TvLog.append("Register Topic : OCF_TOPIC1\n");\r
-                        TvLog.append("Register Topic : OCF_TOPIC2\n");\r
-                        TvLog.append("Register Topic : OCF_TOPIC3\n");\r
-                        TvLog.append("Register Topic : OCF_TOPIC4\n");\r
-                        showToast("Start Provider Service First");\r
-                        break;\r
-                    }\r
-                    mProviderSample.RegisterTopic();\r
-\r
-                }\r
-                break;\r
-\r
-                case R.id.BtnSet: {\r
-                    if (isStarted == false) {\r
-                        Log.i(TAG, "Start Provider Service");\r
-                        TvLog.append("Set Topic : OCF_TOPIC1\n");\r
-                        TvLog.append("Set Topic : OCF_TOPIC2\n");\r
-                        TvLog.append("Set Topic : OCF_TOPIC3\n");\r
-                        TvLog.append("Set Topic : OCF_TOPIC4\n");\r
-                        showToast("Start Provider Service First");\r
-                        break;\r
-                    }\r
-                    if(gAcceptor == false){\r
-                        showToast("Operation Not Permitted: \nStart Provider Service with provider as acceptor");\r
-                        break;\r
-                    }\r
-                    mProviderSample.SetTopic();\r
-\r
-                }\r
-                break;\r
-\r
-                case R.id.BtnCreateNoti: {\r
-\r
-                    String id = Integer.toString(notiId); // generate notificaion ID\r
-                    String title = editTextTitle.getText().toString();\r
-                    String body = editTextBody.getText().toString();\r
-                    String topic  = editTextTopic.getText().toString();\r
-\r
-                    if(isStarted == false)\r
-                    {\r
-                        Log.e(TAG, "Fail to send NSMessage");\r
-                        showToast("Start ProviderService First");\r
-                        break;\r
-                    }\r
-\r
-                    // Build android noti object and send it to Notification service receiver\r
-                    Notification.Builder notiBuilder = new Notification.Builder(getApplicationContext());\r
-                    notiBuilder.setContentTitle(title);\r
-                    notiBuilder.setContentText(body);\r
-                    notiBuilder.setPriority(Notification.PRIORITY_MAX);\r
-                    notiBuilder.setDefaults(Notification.DEFAULT_ALL);\r
-                    notiBuilder.setSmallIcon(R.mipmap.ic_launcher);\r
-                    NotificationManager notiMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);\r
-                    notiMgr.notify(notiId, notiBuilder.build());\r
-\r
-                    Log.i(TAG, "#" + notiId + " notified ..");\r
-                    TvLog.append("Send Notitication(Msg ID: " + notiId + ")\n");\r
-                    notiId++;\r
-                }\r
-                break;\r
-\r
-                case R.id.BtnStop: {\r
-                    if(isStarted == false) {\r
-                        Log.e(TAG, "Fail to stop service");\r
-                        showToast("Already Stopped");\r
-                        break;\r
-                    }\r
-\r
-                    mProviderSample.Stop();\r
-                    isStarted = false;\r
-                    radioProvider.setEnabled(true);\r
-                    radioConsumer.setEnabled(true);\r
-                    showToast("Stopped ProviderService"+ isStarted);\r
-                    TvLog.append("Stop Provider Service\n");\r
-                }\r
-                break;\r
-\r
-                case R.id.BtnLog: {\r
-\r
-                    TvLog.setText("");\r
-                }\r
-                break;  }\r
-            }\r
-    };\r
-}\r
-\r
diff --git a/service/notification/examples/android/NotiProviderExample/app/src/main/java/com/sec/notiproviderexample/ProviderSample.java b/service/notification/examples/android/NotiProviderExample/app/src/main/java/com/sec/notiproviderexample/ProviderSample.java
deleted file mode 100755 (executable)
index 55dcb1d..0000000
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
-//******************************************************************
-//
-// Copyright 2016 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.
-//
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- */
-
-package com.sec.notiproviderexample;
-
-import android.content.Context;
-import android.os.*;
-import android.util.Log;
-import android.widget.Toast;
-
-import org.iotivity.base.ModeType;
-import org.iotivity.base.OcPlatform;
-import org.iotivity.base.OcResourceHandle;
-import org.iotivity.base.PlatformConfig;
-import org.iotivity.base.QualityOfService;
-import org.iotivity.base.ServiceType;
-import org.iotivity.service.ns.common.Message;
-import org.iotivity.service.ns.provider.*;
-import org.iotivity.service.ns.common.*;
-
-
-import java.util.HashMap;
-
-public class ProviderSample
-        implements ProviderService.OnConsumerSubscribedListener, ProviderService.OnMessageSynchronizedListener{
-
-    private static final String TAG = "NS_PROVIDER_PROXY";
-
-    private Context mContext = null;
-    private OcResourceHandle mResourceHandle;   //resource handle
-    private ProviderService ioTNotification = null;
-    private HashMap<String, Integer> msgMap;
-
-    private Handler mHandler = null;
-
-    private static final int CONSUMER_SUBSCRIBED = 1;
-    private static final int MESSAGE_SYNC = 2;
-
-    private static final int SYNC_READ = 0;
-    private static final int SYNC_DISMISS = 1;
-    private static final int SYNC_UNREAD = 2;
-    private boolean gAcceptor;
-    private Consumer gConsumer;
-
-    public ProviderSample(Context context) {
-        Log.i(TAG, "Create providerSample Instance");
-
-        this.msgMap = new HashMap<>();
-        this.mContext = context;
-        ioTNotification =  ProviderService.getInstance();
-    }
-
-    public void setHandler(Handler handler)
-    {
-        this.mHandler = handler;
-    }
-
-    private void configurePlatform() {
-
-        PlatformConfig platformConfig = new PlatformConfig(
-                mContext,
-                ServiceType.IN_PROC,
-                ModeType.CLIENT_SERVER,
-                "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
-                0,         // Uses randomly available port
-                QualityOfService.LOW
-        );
-
-        Log.i(TAG, "Configuring platform.");
-        OcPlatform.Configure(platformConfig);
-        try {
-            OcPlatform.stopPresence(); // Initialize OcPlatform
-        } catch(Exception e) {
-            Log.e(TAG, "Exception: stopping presence when configuration step: " + e);
-        }
-        Log.i(TAG, "Configuration done Successfully");
-    }
-
-    public void Start(boolean policy)
-    {
-        Log.i(TAG, "Start ProviderService -IN");
-        configurePlatform();
-        gAcceptor = policy;
-        try{
-            int result =  ioTNotification.start(this, this, policy, "Info", false);
-            Log.i(TAG, "Notification Start: " + result);
-        }
-        catch(Exception e){
-
-        }
-
-        Log.i(TAG, "Start ProviderService - OUT");
-    }
-
-    public void RegisterTopic()
-    {
-        Log.i(TAG, "Register Topics -IN");
-        try{
-            int result =  ioTNotification.registerTopic("OCF_TOPIC1");
-            Log.i(TAG, " RegisterTopic: " + result);
-            result =  ioTNotification.registerTopic("OCF_TOPIC2");
-            Log.i(TAG, " RegisterTopic: " + result);
-            result =  ioTNotification.registerTopic("OCF_TOPIC3");
-            Log.i(TAG, " RegisterTopic: " + result);
-            result =  ioTNotification.registerTopic("OCF_TOPIC4");
-            Log.i(TAG, " RegisterTopic: " + result);
-        }
-        catch(Exception e){
-
-        }
-
-        Log.i(TAG, "Start ProviderService - OUT");
-    }
-
-    public int SetTopic()
-    {
-        Log.i(TAG, "Set Topic -IN");
-        if(gConsumer == null){
-            return 0;
-        }
-        try{
-            int result =  gConsumer.setTopic("OCF_TOPIC1");
-            Log.i(TAG, " Set Topic : " + result);
-            result =  gConsumer.setTopic("OCF_TOPIC2");
-            Log.i(TAG, " Set Topic : " + result);
-            result =  gConsumer.setTopic("OCF_TOPIC3");
-            Log.i(TAG, " Set Topic : " + result);
-            result =  gConsumer.setTopic("OCF_TOPIC4");
-            Log.i(TAG, " Set Topic : " + result);
-        }
-        catch(Exception e){
-
-        }
-
-        Log.i(TAG, "Start ProviderService - OUT");
-        return 1;
-    }
-
-    public void Stop() {
-        Log.i(TAG, "Stop ProviderService - IN");
-        try {
-            OcPlatform.stopPresence();
-        } catch (Exception e) {
-            Log.e(TAG, "Exception: stopping presence when terminating NS server: " + e);
-        }
-        try{
-            int result =  ioTNotification.stop();
-            Log.i(TAG, "Notification Stop: " + result);
-        }
-        catch(Exception e){
-
-        }
-
-        Log.i(TAG, "Stop ProviderService - OUT");
-    }
-
-
-    public void SendMessage(Message notiMessage) {
-        Log.i(TAG, "SendMessage ProviderService - IN");
-
-        try{
-            int result =  ioTNotification.sendMessage(notiMessage);
-            Log.i(TAG, "Notification Send Message: " + result);
-        }
-        catch(Exception e){
-
-        }
-
-        Log.i(TAG, "SendMessage ProviderService - OUT");
-        mHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                Toast.makeText(mContext, "Notification sent", Toast.LENGTH_SHORT).show();
-            }
-        });
-    }
-
-    public void SendSyncInfo(long messageId, SyncInfo.SyncType syncType) {
-        Log.i(TAG, "SendSyncInfo ProviderService - IN");
-        if(msgMap.containsKey(messageId)) {
-            if(msgMap.get(messageId) == SYNC_UNREAD)
-            {
-                try{
-                    ioTNotification.sendSyncInfo(messageId, syncType);
-                    Log.i(TAG, "Notification Sync " );
-                }
-                catch(Exception e) {
-
-                }
-                Log.i(TAG, "SendSyncInfo ProviderService - OUT");
-                msgMap.put("ID: "+messageId, SYNC_READ);
-            }
-        }
-    }
-
-    public void EnableRemoteService(String servAdd) {
-        Log.i(TAG, "EnableRemoteService ProviderService - IN");
-        try{
-            int result = ioTNotification.enableRemoteService(servAdd);
-            Log.i(TAG, "Notification EnableRemoteService: "+ result );
-        }
-        catch(Exception e) {
-
-        }
-        Log.i(TAG, "EnableRemoteService ProviderService - OUT");
-    }
-
-    public void DisableRemoteService(String servAdd) {
-        Log.i(TAG, "DisableRemoteService ProviderService - IN");
-        try{
-            int result = ioTNotification.disableRemoteService(servAdd);
-            Log.i(TAG, "Notification DisableRemoteService: "+ result );
-        }
-        catch(Exception e) {
-
-        }
-        Log.i(TAG, "DisableRemoteService ProviderService - OUT");
-    }
-
-    public void AcceptSubscription(Consumer consumer, boolean accepted)
-    {
-        Log.i(TAG,"AcceptSubscription ProviderService - IN");
-        try{
-            int result = consumer.acceptSubscription(accepted);
-            Log.i(TAG, "Notification AcceptSubscription: "+result );
-        }
-        catch(Exception e) {
-
-        }
-        Log.i(TAG, "AcceptSubscription ProviderService - OUT");
-    }
-
-    @Override
-    public void onConsumerSubscribed(Consumer consumer) {
-        Log.i(TAG, "onConsumerSubscribed - IN");
-        gConsumer = consumer;
-        AcceptSubscription(consumer, true);
-        android.os.Message msg = mHandler.obtainMessage(CONSUMER_SUBSCRIBED,
-                "Consumer Id: " + consumer.getConsumerId()  );
-        mHandler.sendMessage(msg);
-        Log.i(TAG, "onConsumerSubscribed - OUT");
-    }
-
-    @Override
-    public void onMessageSynchronized(SyncInfo syncInfo) {
-        Log.i(TAG, "Received SyncInfo with messageID: "+syncInfo.getMessageId());
-        android.os.Message msg = mHandler.obtainMessage(MESSAGE_SYNC,
-                "Message Id: " + syncInfo.getMessageId()  );
-        mHandler.sendMessage(msg);
-    }
-
-    public HashMap<String, Integer> getMsgMap() {
-        return msgMap;
-    }
-}
diff --git a/service/notification/examples/android/NotiProviderExample/app/src/main/java/org/iotivity/service/ns/sample/provider/LoginActivity.java b/service/notification/examples/android/NotiProviderExample/app/src/main/java/org/iotivity/service/ns/sample/provider/LoginActivity.java
new file mode 100644 (file)
index 0000000..fd5f8cc
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * ******************************************************************
+ *
+ * Copyright 2016 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.
+ *
+ * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.service.ns.sample.provider;
+
+import android.app.Activity;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.Intent;
+import android.net.UrlQuerySanitizer;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+import android.widget.Button;
+import android.widget.EditText;
+
+/**
+ * This class is for login to the provider. Can be get auth code via web page.
+ */
+public class LoginActivity extends Activity {
+    private static final String TAG           = "OIC_SIMPLE_LOGIN";
+
+    private final Context       context       = this;
+    private WebView             mWebView      = null;
+    private static String       loginAccount  = null;
+    private static String       mAuthProvider = null;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_login);
+
+        final Dialog dialog = new Dialog(context);
+        dialog.setContentView(R.layout.dialog_auth);
+        dialog.setTitle("Login Details");
+        final EditText auth = (EditText) dialog.findViewById(R.id.EditTextAuth);
+        final EditText url = (EditText) dialog.findViewById(R.id.EditTextUrl);
+        if (loginAccount != null && mAuthProvider != null) {
+            url.setText(loginAccount);
+            auth.setText(mAuthProvider);
+        }
+
+        Button dialogButton = (Button) dialog.findViewById(R.id.dialogButtonOK);
+        dialog.setCanceledOnTouchOutside(false);
+        dialogButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                dialog.dismiss();
+                loginAccount = url.getText().toString();
+                mAuthProvider = auth.getText().toString();
+
+                mWebView = (WebView) findViewById(R.id.webView);
+                mWebView.setInitialScale(200);
+                mWebView.getSettings().setJavaScriptEnabled(true);
+                mWebView.getSettings().setBuiltInZoomControls(true);
+                mWebView.setWebViewClient(new WebViewClientClass());
+
+                mWebView.loadUrl(loginAccount);
+            }
+        });
+        dialog.show();
+    }
+
+    public void onDestroy() {
+        super.onDestroy();
+    }
+
+    private class WebViewClientClass extends WebViewClient {
+
+        @Override
+        public void onPageFinished(WebView view, String url) {
+            Log.i(TAG,
+                    "onPageFinished!!! Response received: called url=" + url);
+
+            if (url.contains("code") && url.contains("code_expires_in")) {
+
+                mWebView.setVisibility(View.INVISIBLE);
+
+                // parsing url
+                UrlQuerySanitizer sanitizer = new UrlQuerySanitizer();
+                sanitizer.setAllowUnregisteredParamaters(true);
+                sanitizer.parseUrl(url);
+
+                String mAuthCode = sanitizer.getValue("code");
+                Log.i(TAG, "onPageFinished!!! authCode=" + mAuthCode);
+
+                Intent intent = getIntent();
+                intent.putExtra("authCode", mAuthCode);
+                intent.putExtra("authProvider", mAuthProvider);
+                setResult(RESULT_OK, intent);
+
+                finish();
+            }
+        }
+    }
+}
diff --git a/service/notification/examples/android/NotiProviderExample/app/src/main/java/org/iotivity/service/ns/sample/provider/MainActivity.java b/service/notification/examples/android/NotiProviderExample/app/src/main/java/org/iotivity/service/ns/sample/provider/MainActivity.java
new file mode 100755 (executable)
index 0000000..813d429
--- /dev/null
@@ -0,0 +1,721 @@
+/*
+//******************************************************************
+//
+// Copyright 2016 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.service.ns.sample.provider;
+
+import android.app.Dialog;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.RadioButton;
+import android.widget.TextView;
+import android.widget.Toast;
+import android.app.Activity;
+
+import org.iotivity.base.ErrorCode;
+import org.iotivity.base.OcAccountManager;
+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 java.util.Arrays;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class MainActivity extends Activity
+        implements OcAccountManager.OnPostListener {
+
+    private final String        TAG                 = "NS_MAIN_ACTIVITY";
+    private static final int    CONSUMER_SUBSCRIBED = 1;
+    private static final int    MESSAGE_SYNC        = 2;
+    private final int           REQUEST_LOGIN       = 1;
+    private static final String CI_SERVER_PREFIX    = "coap+tcp://";
+    private final Context       context             = this;
+
+    public static String        deviceID            = null;
+    public static String        CIServer            = null;
+    public static String        RemoteAddress       = null;
+    public static String        MQCloudAddress      = null;
+    public static String        MQCloudTopic        = null;
+
+    private Button              btnTitle;
+    private Button              btnBody;
+    private Button              btnTopic;
+    private Button              btnSend;
+    private Button              btnStart;
+    private Button              btnRegister;
+    private Button              btnSet;
+    private Button              btnStop;
+    private Button              btnLog;
+    private Button              signUp, signIn, signOut;
+    private Button              remoteService, subscribeMQ;
+    private EditText            editTextTitle;
+    private EditText            editTextBody;
+    private EditText            editTextTopic;
+    private RadioButton         radioProvider;
+    private RadioButton         radioConsumer;
+    private static TextView     TvLog;
+
+    private OcAccountManager    mAccountManager;
+    String                      mAuthCode;
+    String                      mAuthProvider;
+    String                      mRefreshtoken;
+    String                      mUserID;
+    String                      mAccessToken;
+
+    private static int          notiId              = 100;
+    private boolean             isStarted           = false;
+    private boolean             gAcceptor           = true;
+    private boolean             gRemoteService      = true;
+
+    private NotiListener        mNotiListener       = null;
+    private ProviderSample      mProviderSample     = null;
+
+    public static Handler       mHandler            = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case CONSUMER_SUBSCRIBED:
+                    String ConsumerId = (String) msg.obj;
+                    if (ConsumerId != null)
+                        TvLog.append("Consumer Subscibed: " + ConsumerId + "\n");
+                    break;
+
+                case MESSAGE_SYNC:
+                    String sync = (String) msg.obj;
+                    if (sync != null)
+                        TvLog.append("SyncInfo Received :" + sync + "\n");
+                    break;
+
+                default:
+                    break;
+            }
+        }
+
+    };
+
+    public void showToast(final String toast) {
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                Toast.makeText(getApplicationContext(), toast,
+                        Toast.LENGTH_SHORT).show();
+            }
+        });
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+
+        btnTitle = (Button) findViewById(R.id.BtnTitle);
+        btnBody = (Button) findViewById(R.id.BtnBody);
+        btnTopic = (Button) findViewById(R.id.BtnTopic);
+        btnSend = (Button) findViewById(R.id.BtnCreateNoti);
+
+        btnStart = (Button) findViewById(R.id.BtnStart);
+        btnRegister = (Button) findViewById(R.id.BtnRegister);
+        btnSet = (Button) findViewById(R.id.BtnSet);
+        btnLog = (Button) findViewById(R.id.BtnLog);
+        btnStop = (Button) findViewById(R.id.BtnStop);
+
+        signUp = (Button) findViewById(R.id.signup);
+        signIn = (Button) findViewById(R.id.signin);
+        signOut = (Button) findViewById(R.id.signout);
+        remoteService = (Button) findViewById(R.id.remoteService);
+        subscribeMQ = (Button) findViewById(R.id.subscribeMQService);
+
+        editTextTitle = (EditText) findViewById(R.id.EditTextTitle);
+        editTextBody = (EditText) findViewById(R.id.EditTextBody);
+        editTextTopic = (EditText) findViewById(R.id.EditTextTopic);
+
+        radioProvider = (RadioButton) findViewById(R.id.RadioProvider);
+        radioConsumer = (RadioButton) findViewById(R.id.RadioConsumer);
+
+        TvLog = (TextView) findViewById(R.id.TvLog);
+
+        btnTitle.setEnabled(false);
+        btnBody.setEnabled(false);
+        btnTopic.setEnabled(false);
+
+        signIn.setEnabled(false);
+        signOut.setEnabled(false);
+        remoteService.setEnabled(false);
+
+        btnSend.setOnClickListener(mClickListener);
+        btnStart.setOnClickListener(mClickListener);
+        btnRegister.setOnClickListener(mClickListener);
+        btnSet.setOnClickListener(mClickListener);
+        btnLog.setOnClickListener(mClickListener);
+        btnStop.setOnClickListener(mClickListener);
+        radioProvider.setOnClickListener(mClickListener);
+        radioConsumer.setOnClickListener(mClickListener);
+
+        signUp.setOnClickListener(mClickListener);
+        signIn.setOnClickListener(mClickListener);
+        signOut.setOnClickListener(mClickListener);
+
+        remoteService.setOnClickListener(mClickListener);
+        subscribeMQ.setOnClickListener(mClickListener);
+
+        mProviderSample = new ProviderSample(getApplicationContext());
+        mProviderSample.setHandler(mHandler);
+
+        mNotiListener = new NotiListener(this);
+        Intent intent = new Intent(
+                "android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
+        startActivity(intent);
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+    }
+
+    public ProviderSample getProviderSample() {
+        return mProviderSample;
+    }
+
+    Button.OnClickListener mClickListener = new View.OnClickListener() {
+        public void onClick(View v) {
+            switch (v.getId()) {
+                case R.id.RadioProvider: {
+                    if (isStarted == false) {
+                        gAcceptor = true;
+                        showToast("Provider as acceptor is " + gAcceptor);
+                    } else
+                        showToast(
+                                "Start ProviderService again to change acceptor as provider");
+                }
+                    break;
+
+                case R.id.RadioConsumer: {
+                    if (isStarted == false) {
+                        gAcceptor = false;
+                        showToast("Provider as acceptor is " + gAcceptor);
+                    } else
+                        showToast(
+                                "Start ProviderService again to change acceptor as consumer");
+                }
+                    break;
+
+                case R.id.BtnStart: {
+                    if (isStarted == false) {
+                        Log.i(TAG, "Start  Provider Service");
+                        TvLog.setText("Start Provider Service\n");
+                        mProviderSample.start(gAcceptor);
+                        isStarted = true;
+                        radioProvider.setEnabled(false);
+                        radioConsumer.setEnabled(false);
+                        // refreshToken();
+
+                    } else {
+                        Log.e(TAG, " Provider Service had already started");
+                        showToast(" Provider Service had already started");
+                    }
+                }
+                    break;
+
+                case R.id.BtnRegister: {
+                    if (isStarted == false) {
+                        Log.i(TAG, "Start  Provider Service");
+                        TvLog.append("Register Topic : OCF_TOPIC1\n");
+                        TvLog.append("Register Topic : OCF_TOPIC2\n");
+                        TvLog.append("Register Topic : OCF_TOPIC3\n");
+                        TvLog.append("Register Topic : OCF_TOPIC4\n");
+                        showToast("Start Provider Service First");
+                        break;
+                    }
+                    mProviderSample.registerTopic();
+
+                }
+                    break;
+
+                case R.id.BtnSet: {
+                    if (isStarted == false) {
+                        Log.i(TAG, "Start Provider Service");
+                        TvLog.append("Set Topic : OCF_TOPIC1\n");
+                        TvLog.append("Set Topic : OCF_TOPIC2\n");
+                        TvLog.append("Set Topic : OCF_TOPIC3\n");
+                        TvLog.append("Set Topic : OCF_TOPIC4\n");
+                        showToast("Start Provider Service First");
+                        break;
+                    }
+                    if (gAcceptor == false) {
+                        showToast(
+                                "Operation Not Permitted: \nStart Provider Service with provider as acceptor");
+                        break;
+                    }
+                    mProviderSample.setTopic();
+
+                }
+                    break;
+
+                case R.id.BtnCreateNoti: {
+
+                    String id = Integer.toString(notiId); // generate
+                                                          // notificaion ID
+                    String title = editTextTitle.getText().toString();
+                    String body = editTextBody.getText().toString();
+                    String topic = editTextTopic.getText().toString();
+
+                    if (isStarted == false) {
+                        Log.e(TAG, "Fail to send NSMessage");
+                        showToast("Start ProviderService First");
+                        break;
+                    }
+
+                    // Build android noti object and send it to Notification
+                    // service receiver
+                    Notification.Builder notiBuilder = new Notification.Builder(
+                            getApplicationContext());
+                    notiBuilder.setContentTitle(title);
+                    notiBuilder.setContentText(body);
+                    notiBuilder.setSubText(topic);
+                    notiBuilder.setPriority(Notification.PRIORITY_MAX);
+                    notiBuilder.setDefaults(Notification.DEFAULT_ALL);
+                    notiBuilder.setSmallIcon(R.mipmap.ic_launcher);
+                    NotificationManager notiMgr = (NotificationManager) getSystemService(
+                            NOTIFICATION_SERVICE);
+                    notiMgr.notify(notiId, notiBuilder.build());
+
+                    Log.i(TAG, "#" + notiId + " notified ..");
+                    TvLog.append("Send Notitication(Msg ID: " + notiId + ")\n");
+                    notiId++;
+                }
+                    break;
+
+                case R.id.BtnStop: {
+                    if (isStarted == false) {
+                        Log.e(TAG, "Fail to stop service");
+                        showToast("Already Stopped");
+                        break;
+                    }
+
+                    mProviderSample.stop();
+                    isStarted = false;
+                    radioProvider.setEnabled(true);
+                    radioConsumer.setEnabled(true);
+                    showToast("Stopped ProviderService" + isStarted);
+                    TvLog.append("Stop Provider Service\n");
+                }
+                    break;
+
+                case R.id.BtnLog: {
+
+                    TvLog.setText("");
+                }
+                    break;
+                case R.id.signup: {
+                    if (isStarted == false) {
+                        Log.e(TAG, "Fail to Sign Up");
+                        showToast("Start ProviderService First");
+                        break;
+                    }
+                    TvLog.append("Initiating SignUp\n");
+                    signUp();
+                }
+                    break;
+                case R.id.signin: {
+                    if (isStarted == false) {
+                        Log.e(TAG, "Fail to Sign In");
+                        showToast("Start ProviderService First");
+                        break;
+                    }
+                    TvLog.append("Initiating SignIn\n");
+                    signIn();
+                }
+                    break;
+                case R.id.signout: {
+                    if (isStarted == false) {
+                        Log.e(TAG, "Fail to Sign out");
+                        showToast("Start ProviderService First");
+                        break;
+                    }
+                    TvLog.append("Initiating SignOut\n");
+                    signOut();
+                }
+                    break;
+                case R.id.remoteService: {
+                    remoteService.setEnabled(false);
+                    if (isStarted == false) {
+                        Log.e(TAG, "Fail to Enable/Disable RemoteService");
+                        showToast("Start ProviderService First");
+                        break;
+                    }
+                    if (gRemoteService) {
+                        TvLog.append("Enable Remote Service\n");
+                        mProviderSample.enableRemoteService(RemoteAddress);
+                        remoteService.setText(R.string.disableRemoteService);
+                        gRemoteService = false;
+                        remoteService.setEnabled(true);
+                        TvLog.append("EnableRemoteService success \n");
+                    } else {
+                        TvLog.append("Disable Remote Service\n");
+                        mProviderSample.disableRemoteService(RemoteAddress);
+                        remoteService.setText(R.string.enableRemoteService);
+                        gRemoteService = true;
+                        remoteService.setEnabled(true);
+                        TvLog.append("DisableRemoteService success\n");
+                    }
+                }
+                    break;
+                case R.id.subscribeMQService: {
+                    if (isStarted == false) {
+                        Log.e(TAG, "Fail to SubscribeMQService");
+                        showToast("Start ProviderService First");
+                        break;
+                    }
+                    final Dialog dialog = new Dialog(context);
+                    dialog.setContentView(R.layout.dialog_mq);
+                    dialog.setTitle("MQ Cloud Service Details");
+
+                    final EditText ip = (EditText) dialog
+                            .findViewById(R.id.EditTextIp);
+                    final EditText mqTopic = (EditText) dialog
+                            .findViewById(R.id.EditTextMqTopic);
+                    if (MQCloudAddress != null && MQCloudTopic != null) {
+                        ip.setText(MQCloudAddress);
+                        mqTopic.setText(MQCloudTopic);
+                    }
+
+                    Button dialogButton = (Button) dialog
+                            .findViewById(R.id.mqButtonOK);
+
+                    dialogButton.setOnClickListener(new View.OnClickListener() {
+                        @Override
+                        public void onClick(View v) {
+                            dialog.dismiss();
+                            MQCloudAddress = ip.getText().toString();
+                            MQCloudTopic = mqTopic.getText().toString();
+                            mProviderSample.subscribeMQService(
+                                    MQCloudAddress, MQCloudTopic);
+                            TvLog.append("SubscribeMQService success\n");
+                        }
+                    });
+                    dialog.show();
+                }
+                    break;
+            }
+        }
+    };
+
+    public void logMessage(final String text) {
+        runOnUiThread(new Runnable() {
+            public void run() {
+                Message msg = new Message();
+                msg.obj = text;
+                TvLog.append(text + "\n");
+            }
+        });
+        Log.i(TAG, text);
+    }
+
+    OcAccountManager.OnPostListener onSignUp  = new OcAccountManager.OnPostListener() {
+        @Override
+        public synchronized void onPostCompleted(List<OcHeaderOption> list,
+                OcRepresentation ocRepresentation) {
+            logMessage("signUp was successful");
+            runOnUiThread(new Runnable() {
+                public void run() {
+                    signIn.setEnabled(true);
+                    signUp.setEnabled(false);
+                }
+            });
+            try {
+                mUserID = ocRepresentation.getValue("uid");
+                mAccessToken = ocRepresentation.getValue("accesstoken");
+                mRefreshtoken = ocRepresentation.getValue("refreshtoken");
+
+                logMessage("\tuserID: " + mUserID);
+                logMessage("\taccessToken: " + mAccessToken);
+                logMessage("\trefreshToken: " + mRefreshtoken);
+
+                if (ocRepresentation.hasAttribute("expiresin")) {
+                    int expiresIn = ocRepresentation.getValue("expiresin");
+                    logMessage("\texpiresIn: " + expiresIn);
+                }
+            } catch (OcException e) {
+                Log.e(TAG, e.toString());
+            }
+        }
+
+        @Override
+        public synchronized void onPostFailed(Throwable throwable) {
+            logMessage("Failed to signUp");
+            if (throwable instanceof OcException) {
+                OcException ocEx = (OcException) throwable;
+                Log.e(TAG, ocEx.toString());
+                ErrorCode errCode = ocEx.getErrorCode();
+                logMessage("Error code: " + errCode);
+            }
+        }
+    };
+
+    OcAccountManager.OnPostListener onSignIn  = new OcAccountManager.OnPostListener() {
+        @Override
+        public synchronized void onPostCompleted(List<OcHeaderOption> list,
+                OcRepresentation ocRepresentation) {
+            logMessage("signIn was successful");
+            runOnUiThread(new Runnable() {
+                public void run() {
+                    signIn.setEnabled(false);
+                    signOut.setEnabled(true);
+                    remoteService.setEnabled(true);
+                }
+            });
+        }
+
+        @Override
+        public synchronized void onPostFailed(Throwable throwable) {
+            logMessage("Failed to signIn");
+            if (throwable instanceof OcException) {
+                OcException ocEx = (OcException) throwable;
+                Log.e(TAG, ocEx.toString());
+                ErrorCode errCode = ocEx.getErrorCode();
+                logMessage("Error code: " + errCode);
+                if (ErrorCode.UNAUTHORIZED_REQ != errCode) {
+                    refreshToken();
+                }
+            }
+        }
+    };
+
+    OcAccountManager.OnPostListener onSignOut = new OcAccountManager.OnPostListener() {
+        @Override
+        public synchronized void onPostCompleted(List<OcHeaderOption> list,
+                OcRepresentation ocRepresentation) {
+            logMessage("signOut was successful");
+            runOnUiThread(new Runnable() {
+                public void run() {
+                    signIn.setEnabled(true);
+                    signOut.setEnabled(false);
+                    remoteService.setEnabled(false);
+                }
+            });
+
+        }
+
+        @Override
+        public synchronized void onPostFailed(Throwable throwable) {
+            logMessage("Failed to signOut");
+            if (throwable instanceof OcException) {
+                OcException ocEx = (OcException) throwable;
+                Log.e(TAG, ocEx.toString());
+                ErrorCode errCode = ocEx.getErrorCode();
+                logMessage("Error code: " + errCode);
+                if (ErrorCode.UNAUTHORIZED_REQ != errCode) {
+                    refreshToken();
+                }
+            }
+        }
+    };
+
+    @Override
+    public void onPostCompleted(List<OcHeaderOption> ocHeaderOptions,
+            OcRepresentation ocRepresentation) {
+
+    }
+
+    @Override
+    public void onPostFailed(Throwable throwable) {
+
+    }
+
+    private void signIn() {
+        try {
+            if (mAccountManager == null) {
+                mAccountManager = OcPlatform.constructAccountManagerObject(
+                        CIServer,
+                        EnumSet.of(OcConnectivityType.CT_ADAPTER_TCP));
+            }
+
+            mAccountManager.signIn(mUserID, mAccessToken, onSignIn);
+        } catch (OcException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void signOut() {
+        try {
+            logMessage("signOut");
+            if (mAccountManager == null) {
+                try {
+                    mAccountManager = OcPlatform.constructAccountManagerObject(
+                            CIServer,
+                            EnumSet.of(OcConnectivityType.CT_ADAPTER_TCP));
+                } catch (OcException e) {
+                    e.printStackTrace();
+                }
+            }
+            mAccountManager.signOut(mAccessToken, onSignOut);
+            signIn.setEnabled(false);
+            signUp.setEnabled(true);
+            remoteService.setEnabled(false);
+            logMessage("signOut Successful");
+        } catch (OcException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void signUp() {
+        Intent intentLogin = new Intent(this, LoginActivity.class);
+        startActivityForResult(intentLogin, REQUEST_LOGIN);
+    }
+
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+        if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_LOGIN) {
+            mAuthCode = data.getStringExtra("authCode");
+            mAuthProvider = data.getStringExtra("authProvider");
+            logMessage("authCode: " + mAuthCode);
+            logMessage("authProvider: " + mAuthProvider);
+
+            final Dialog dialog = new Dialog(context);
+            dialog.setContentView(R.layout.dialog_entry);
+            dialog.setTitle("SignUp Acccount IP Address");
+            final EditText ip = (EditText) dialog
+                    .findViewById(R.id.EditTextEntry);
+            if (RemoteAddress != null) {
+                ip.setText(RemoteAddress);
+            }
+            Button dialogButton = (Button) dialog
+                    .findViewById(R.id.entryButtonOK);
+            dialogButton.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    dialog.dismiss();
+                    RemoteAddress = ip.getText().toString();
+                    CIServer = CI_SERVER_PREFIX + RemoteAddress;
+                    logMessage("server address for signup is: \n" + CIServer);
+                    try {
+                        mAccountManager = OcPlatform
+                                .constructAccountManagerObject(CIServer, EnumSet
+                                        .of(OcConnectivityType.CT_ADAPTER_TCP));
+                        logMessage("Calling signup API");
+
+                        if (mAuthProvider.equals("samsung")
+                                || mAuthProvider.equals("samsung-us"))
+
+                        {
+                            logMessage("Auth provider is samsung");
+                            Map<String, String> options = new HashMap<>();
+                            options.put("auth_server_url",
+                                    "us-auth2.samsungosp.com");
+                            options.put("api_server_url",
+                                    "us-auth2.samsungosp.com");
+                            mAccountManager.signUp(mAuthProvider, mAuthCode,
+                                    options, onSignUp);
+                        } else {
+                            mAccountManager.signUp(mAuthProvider, mAuthCode,
+                                    onSignUp);
+                        }
+                    } catch (OcException e) {
+                        e.printStackTrace();
+                    }
+                }
+            });
+            dialog.show();
+        }
+    }
+
+    OcResource.OnPostListener onRefreshTokenPost = new OcResource.OnPostListener() {
+        @Override
+        public void onPostCompleted(List<OcHeaderOption> list,
+                OcRepresentation ocRepresentation) {
+            logMessage("RefreshToken Completed.");
+            try {
+                mAccessToken = ocRepresentation.getValue("accesstoken");
+                mRefreshtoken = ocRepresentation.getValue("refreshtoken");
+            } catch (OcException e) {
+                e.printStackTrace();
+            }
+            signIn();
+        }
+
+        @Override
+        public void onPostFailed(Throwable throwable) {
+            logMessage("RefreshToken failed.");
+            Log.d(TAG, "onRefreshTokenPost failed.");
+        }
+    };
+
+    public void refreshToken() {
+
+        if (deviceID == null) {
+            final Dialog dialog = new Dialog(context);
+            dialog.setContentView(R.layout.dialog_entry);
+            dialog.setTitle("Enter Device Id");
+            dialog.setCanceledOnTouchOutside(false);
+            final EditText id = (EditText) dialog
+                    .findViewById(R.id.EditTextEntry);
+
+            Button dialogButton = (Button) dialog
+                    .findViewById(R.id.entryButtonOK);
+            dialogButton.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    dialog.dismiss();
+                    deviceID = id.getText().toString();
+                }
+            });
+            dialog.show();
+        }
+        try {
+            OcResource authResource = OcPlatform.constructResourceObject(
+                    CIServer, "/.well-known/ocf/account/tokenrefresh",
+                    EnumSet.of(OcConnectivityType.CT_ADAPTER_TCP,
+                            OcConnectivityType.CT_IP_USE_V4),
+                    false, Arrays.asList("oic.wk.account"),
+                    Arrays.asList(OcPlatform.DEFAULT_INTERFACE));
+            OcRepresentation rep = new OcRepresentation();
+
+            showToast("RefreshToken in progress..");
+            logMessage("RefreshToken in progress..");
+            rep.setValue("di", deviceID);
+            rep.setValue("granttype", "refresh_token");
+            rep.setValue("refreshtoken", mRefreshtoken);
+            rep.setValue("uid", mUserID);
+            authResource.post(rep, new HashMap<String, String>(),
+                    onRefreshTokenPost);
+        } catch (OcException e) {
+            e.printStackTrace();
+        }
+
+        Log.d(TAG, "No error while executing login");
+    }
+}
-/*\r
-//******************************************************************\r
-//\r
-// Copyright 2016 Samsung Electronics All Rights Reserved.\r
-//\r
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
-//\r
-// Licensed under the Apache License, Version 2.0 (the "License");\r
-// you may not use this file except in compliance with the License.\r
-// You may obtain a copy of the License at\r
-//\r
-//      http://www.apache.org/licenses/LICENSE-2.0\r
-//\r
-// Unless required by applicable law or agreed to in writing, software\r
-// distributed under the License is distributed on an "AS IS" BASIS,\r
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-// See the License for the specific language governing permissions and\r
-// limitations under the License.\r
-//\r
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
- */\r
-\r
-package com.sec.notiproviderexample;\r
-\r
-import android.app.Notification;\r
-import android.os.Bundle;\r
-import android.service.notification.NotificationListenerService;\r
-import android.service.notification.StatusBarNotification;\r
-import android.util.Log;\r
-import org.iotivity.service.ns.common.MediaContents;\r
-import org.iotivity.service.ns.common.Message;\r
-import java.util.ArrayList;\r
-\r
-public class NotiListener extends NotificationListenerService {\r
-\r
-    private final String TAG = "NS_JNI_NOTI_LISTENER";\r
-    private static ProviderSample mProviderSample = null;\r
-    private MainActivity mActivity = null;\r
-    ArrayList mBlackSourceList = new ArrayList<String>();\r
-\r
-    public NotiListener() {\r
-\r
-        Log.i(TAG, "Create NotiListener");\r
-    }\r
-\r
-    public NotiListener(MainActivity activity) {\r
-\r
-        Log.i(TAG, "Create NotiListener with MainActivity");\r
-\r
-        this.mActivity = activity;\r
-        this.mProviderSample = mActivity.getProviderSample();\r
-\r
-        setBlackSourceList();\r
-\r
-        if(mProviderSample == null) {\r
-            Log.i(TAG, "Fail to get providerProxy instance");\r
-        }\r
-    }\r
-\r
-    public void setBlackSourceList() {\r
-\r
-        // set blacklist of app package name not to receive notification\r
-        mBlackSourceList.add("android");\r
-        mBlackSourceList.add("com.android.systemui");\r
-    }\r
-\r
-    @Override\r
-    public void onNotificationPosted(StatusBarNotification sbn) {\r
-        super.onNotificationPosted(sbn);\r
-\r
-        Bundle bundle = sbn.getNotification().extras;\r
-        String source = null;\r
-\r
-        // prevent not to send notification\r
-        for(int i = 0; i < mBlackSourceList.size(); ++i)\r
-        {\r
-            if (sbn.getPackageName().equals(mBlackSourceList.get(i)))\r
-            {\r
-                return;\r
-            }\r
-        }\r
-\r
-        // filter exception case : Some notification are generated twice\r
-        if(sbn.getId() > 10000 || sbn.getId() < 0)\r
-            return;\r
-\r
-        // Temporary protocol code to display ICON on consumer app.\r
-        // For example, consumer app shows KAKAOTALK Icon when receiving Notification with SOURCE\r
-        // that is set to KAKAO, otherwise it displays OCF Icon on current sample app.\r
-        if(sbn.getPackageName().equals("com.kakao.talk"))\r
-            source = "KAKAO";\r
-        else\r
-            source = "OCF";\r
-\r
-        Log.i(TAG, "Noti. Package Name : " + sbn.getPackageName());\r
-        Log.i(TAG, "Noti. ID : " + sbn.getId());\r
-\r
-        String id = Integer.toString(sbn.getId());\r
-        String title = bundle.getString(Notification.EXTRA_TITLE, "");\r
-        String body = bundle.getString(Notification.EXTRA_TEXT, "");\r
-\r
-        Log.i(TAG, "onNotificationPosted .. ");\r
-        Log.i(TAG, "source : " + source);\r
-        Log.i(TAG, "Id : " + id);\r
-        Log.i(TAG, "Title : " + title);\r
-        Log.i(TAG, "Body : " + body);\r
-\r
-        Message notiMessage = new Message(title,body,source);\r
-        notiMessage.setTTL(10);\r
-        notiMessage.setTime("12:10");\r
-        MediaContents media = new MediaContents("daasd");\r
-        notiMessage.setMediaContents(media);\r
-        if (mProviderSample != null) {\r
-            mProviderSample.SendMessage(notiMessage);\r
-        } else {\r
-            Log.i(TAG, "providerExample is NULL");\r
-        }\r
-    }\r
-\r
-    @Override\r
-    public void onNotificationRemoved(StatusBarNotification sbn) {\r
-        super.onNotificationRemoved(sbn);\r
-\r
-        Bundle bundle = sbn.getNotification().extras;\r
-\r
-        if (sbn.getPackageName().equals("android"))\r
-            return;\r
-\r
-        Log.i(TAG, "Noti. Package Name : " + sbn.getPackageName());\r
-        Log.i(TAG, "Noti. ID : " + sbn.getId());\r
-\r
-        if(mProviderSample.getMsgMap().containsKey(sbn.getId()))\r
-        {\r
-            if(mProviderSample.getMsgMap().get(sbn.getId()) == 2)\r
-            {\r
-                org.iotivity.service.ns.common.SyncInfo.SyncType type = org.iotivity.service.ns.common.SyncInfo.SyncType.READ;\r
-                mProviderSample.SendSyncInfo(1,type);\r
-            }\r
-        }\r
-    }\r
-}\r
+/*
+//******************************************************************
+//
+// Copyright 2016 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.service.ns.sample.provider;
+
+import android.app.Notification;
+import android.os.Bundle;
+import android.service.notification.NotificationListenerService;
+import android.service.notification.StatusBarNotification;
+import android.util.Log;
+import org.iotivity.service.ns.common.MediaContents;
+import org.iotivity.service.ns.common.Message;
+import java.util.ArrayList;
+
+public class NotiListener extends NotificationListenerService {
+
+    private final String          TAG              = "NS_JNI_NOTI_LISTENER";
+    private static ProviderSample mProviderSample  = null;
+    private MainActivity          mActivity        = null;
+    ArrayList                     mBlackSourceList = new ArrayList<String>();
+
+    public NotiListener() {
+
+        Log.i(TAG, "Create NotiListener");
+    }
+
+    public NotiListener(MainActivity activity) {
+
+        Log.i(TAG, "Create NotiListener with MainActivity");
+
+        this.mActivity = activity;
+        this.mProviderSample = mActivity.getProviderSample();
+
+        setBlackSourceList();
+
+        if (mProviderSample == null) {
+            Log.i(TAG, "Fail to get providerProxy instance");
+        }
+    }
+
+    public void setBlackSourceList() {
+
+        // set blacklist of app package name not to receive notification
+        mBlackSourceList.add("android");
+        mBlackSourceList.add("com.android.systemui");
+    }
+
+    @Override
+    public void onNotificationPosted(StatusBarNotification sbn) {
+        super.onNotificationPosted(sbn);
+        Log.i(TAG, "Notification posted By package" + sbn.getPackageName());
+
+        Bundle bundle = sbn.getNotification().extras;
+        String source = null;
+
+        // prevent not to send notification
+        for (int i = 0; i < mBlackSourceList.size(); ++i) {
+            if (sbn.getPackageName().equals(mBlackSourceList.get(i))) {
+                return;
+            }
+        }
+
+        // filter exception case : Some notification are generated twice
+        if (sbn.getId() > 10000 || sbn.getId() < 0) {
+            return;
+        }
+
+        // Temporary protocol code to display ICON on consumer app.
+        // For example, consumer app shows KAKAOTALK Icon when receiving
+        // Notification with SOURCE
+        // that is set to KAKAO, otherwise it displays OCF Icon on current
+        // sample app.
+        if (sbn.getPackageName().equals("com.kakao.talk")) {
+            source = "KAKAO";
+        }
+        else {
+            source = "OCF";
+        }
+
+        Log.i(TAG, "Noti. Package Name : " + sbn.getPackageName());
+        Log.i(TAG, "Noti. ID : " + sbn.getId());
+
+        String id = Integer.toString(sbn.getId());
+        String title = bundle.getString(Notification.EXTRA_TITLE, "");
+        String body = bundle.getString(Notification.EXTRA_TEXT, "");
+        String topic = bundle.getString(Notification.EXTRA_SUB_TEXT, "");
+
+        Log.i(TAG, "onNotificationPosted .. ");
+        Log.i(TAG, "source : " + source);
+        Log.i(TAG, "Id : " + id);
+        Log.i(TAG, "Title : " + title);
+        Log.i(TAG, "Body : " + body);
+
+        Message notiMessage = mProviderSample.createMessage();
+        if(notiMessage == null)
+        {
+            Log.e(TAG, "CreateMessage Failed");
+            return;
+        }
+        Log.i(TAG, "Message ID : " + notiMessage.getMessageId());
+        Log.i(TAG, "Provider ID : " + notiMessage.getProviderId());
+        notiMessage.setTitle(title);
+        notiMessage.setContentText(body);
+        notiMessage.setTopic(topic);
+        notiMessage.setSourceName(source);
+        notiMessage.setTTL(10);
+        notiMessage.setTime("12:10");
+        MediaContents media = new MediaContents("daasd");
+        notiMessage.setMediaContents(media);
+        if (mProviderSample != null) {
+            mProviderSample.sendMessage(notiMessage);
+        } else {
+            Log.i(TAG, "providerExample is NULL");
+        }
+    }
+
+    @Override
+    public void onNotificationRemoved(StatusBarNotification sbn) {
+        super.onNotificationRemoved(sbn);
+
+        Bundle bundle = sbn.getNotification().extras;
+
+        if (sbn.getPackageName().equals("android")) {
+            return;
+        }
+
+        Log.i(TAG, "Noti. Package Name : " + sbn.getPackageName());
+        Log.i(TAG, "Noti. ID : " + sbn.getId());
+
+        if (mProviderSample.getMsgMap().containsKey(sbn.getId())) {
+            if (mProviderSample.getMsgMap().get(sbn.getId()) == 2) {
+                org.iotivity.service.ns.common.SyncInfo.SyncType type = org.iotivity.service.ns.common.SyncInfo.SyncType.READ;
+                mProviderSample.sendSyncInfo(1, type);
+            }
+        }
+    }
+}
diff --git a/service/notification/examples/android/NotiProviderExample/app/src/main/java/org/iotivity/service/ns/sample/provider/ProviderSample.java b/service/notification/examples/android/NotiProviderExample/app/src/main/java/org/iotivity/service/ns/sample/provider/ProviderSample.java
new file mode 100755 (executable)
index 0000000..b348b2e
--- /dev/null
@@ -0,0 +1,267 @@
+/*
+//******************************************************************
+//
+// Copyright 2016 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.service.ns.sample.provider;
+
+import android.content.Context;
+import android.os.*;
+import android.util.Log;
+import android.widget.Toast;
+
+import org.iotivity.base.ModeType;
+import org.iotivity.base.OcPlatform;
+import org.iotivity.base.OcResourceHandle;
+import org.iotivity.base.PlatformConfig;
+import org.iotivity.base.QualityOfService;
+import org.iotivity.base.ServiceType;
+import org.iotivity.service.ns.common.Message;
+import org.iotivity.service.ns.provider.*;
+import org.iotivity.service.ns.common.*;
+
+import java.util.HashMap;
+
+public class ProviderSample
+        implements ProviderService.OnConsumerSubscribedListener,
+        ProviderService.OnMessageSynchronizedListener {
+
+    private static final String      TAG                 = "NS_PROVIDER_SAMPLE";
+
+    private Context                  mContext            = null;
+    private OcResourceHandle         mResourceHandle;
+    private ProviderService          ioTNotification     = null;
+    private HashMap<String, Integer> msgMap;
+
+    private Handler                  mHandler            = null;
+
+    private static final int         CONSUMER_SUBSCRIBED = 1;
+    private static final int         MESSAGE_SYNC        = 2;
+
+    private static final int         SYNC_READ           = 0;
+    private static final int         SYNC_DISMISS        = 1;
+    private static final int         SYNC_UNREAD         = 2;
+    private boolean                  gAcceptor;
+    private Consumer                 gConsumer;
+
+    public ProviderSample(Context context) {
+        Log.i(TAG, "Create providerSample Instance");
+
+        this.msgMap = new HashMap<>();
+        this.mContext = context;
+        ioTNotification = ProviderService.getInstance();
+    }
+
+    public void setHandler(Handler handler) {
+        this.mHandler = handler;
+    }
+
+    private void configurePlatform() {
+
+        PlatformConfig platformConfig = new PlatformConfig(mContext,
+                ServiceType.IN_PROC, ModeType.CLIENT_SERVER, "0.0.0.0",
+                0, // Uses randomly available port
+                QualityOfService.LOW);
+
+        Log.i(TAG, "Configuring platform.");
+        OcPlatform.Configure(platformConfig);
+        try {
+            OcPlatform.stopPresence(); // Initialize OcPlatform
+        } catch (Exception e) {
+            Log.e(TAG, "Exception: stopping presence when configuration step: "
+                    + e);
+        }
+        Log.i(TAG, "Configuration done Successfully");
+    }
+
+    public void start(boolean policy) {
+        Log.i(TAG, "Start ProviderService -IN");
+        configurePlatform();
+        gAcceptor = policy;
+        try {
+            ioTNotification.start(this, this, policy, "Info", false);
+        } catch (Exception e) {
+            Log.e(TAG, "Exception: start : " + e);
+        }
+        Log.i(TAG, "Start ProviderService - OUT");
+    }
+
+    public void registerTopic() {
+        Log.i(TAG, "Register Topics -IN");
+        try {
+            ioTNotification.registerTopic("OCF_TOPIC1");
+            ioTNotification.registerTopic("OCF_TOPIC2");
+            ioTNotification.registerTopic("OCF_TOPIC3");
+            ioTNotification.registerTopic("OCF_TOPIC4");
+        } catch (Exception e) {
+            Log.e(TAG, "Exception: registerTopic  : "+ e);
+        }
+
+        Log.i(TAG, "Start ProviderService - OUT");
+    }
+
+    public void setTopic() {
+        Log.i(TAG, "Set Topic -IN");
+        if (gConsumer == null) {
+            return;
+        }
+        try {
+            gConsumer.setTopic("OCF_TOPIC1");
+            gConsumer.setTopic("OCF_TOPIC2");
+            gConsumer.setTopic("OCF_TOPIC3");
+            gConsumer.setTopic("OCF_TOPIC4");
+        } catch (Exception e) {
+            Log.e(TAG, "Exception: setTopic : " + e);
+        }
+
+        Log.i(TAG, "setTopic ProviderService - OUT");
+        return;
+    }
+
+    public void stop() {
+        Log.i(TAG, "Stop ProviderService - IN");
+        try {
+            OcPlatform.stopPresence();
+        } catch (Exception e) {
+            Log.e(TAG,"Exception: stopping presence when terminating NS server: "+ e);
+        }
+        try {
+            ioTNotification.stop();
+        } catch (Exception e) {
+            Log.e(TAG, "Exception: stop : " + e);
+        }
+
+        Log.i(TAG, "Stop ProviderService - OUT");
+    }
+
+    public Message createMessage() {
+        Log.i(TAG, "createMessage ProviderService - IN");
+        Message message = null;
+        try {
+            message = ioTNotification.createMessage();
+        } catch (Exception e) {
+            Log.e(TAG, "Exception: createMessage : " + e);
+        }
+        Log.i(TAG, "createMessage ProviderService - OUT");
+        return message;
+    }
+
+    public void sendMessage(Message notiMessage) {
+        Log.i(TAG, "SendMessage ProviderService - IN");
+
+        try {
+            ioTNotification.sendMessage(notiMessage);
+        } catch (Exception e) {
+            Log.e(TAG, "Exception: sendMessage : " + e);
+        }
+
+        Log.i(TAG, "SendMessage ProviderService - OUT");
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                Toast.makeText(mContext, "Notification sent",
+                        Toast.LENGTH_SHORT).show();
+            }
+        });
+    }
+
+    public void sendSyncInfo(long messageId, SyncInfo.SyncType syncType) {
+        Log.i(TAG, "SendSyncInfo ProviderService - IN");
+        if (msgMap.containsKey(messageId)) {
+            if (msgMap.get(messageId) == SYNC_UNREAD) {
+                try {
+                    ioTNotification.sendSyncInfo(messageId, syncType);
+                    Log.i(TAG, "Notification Sync ");
+                } catch (Exception e) {
+                    Log.e(TAG, "Exception: sendSyncInfo : " + e);
+                }
+                Log.i(TAG, "SendSyncInfo ProviderService - OUT");
+                msgMap.put("ID: " + messageId, SYNC_READ);
+            }
+        }
+    }
+
+    public void enableRemoteService(String servAdd) {
+        Log.i(TAG, "EnableRemoteService ProviderService - IN");
+        try {
+            ioTNotification.enableRemoteService(servAdd);
+        } catch (Exception e) {
+            Log.e(TAG, "Exception: enableRemoteService : " + e);
+        }
+        Log.i(TAG, "EnableRemoteService ProviderService - OUT");
+        return;
+    }
+
+    public void disableRemoteService(String servAdd) {
+        Log.i(TAG, "DisableRemoteService ProviderService - IN");
+        try {
+            ioTNotification.disableRemoteService(servAdd);
+        } catch (Exception e) {
+            Log.e(TAG, "Exception: disableRemoteService : " + e);
+        }
+        Log.i(TAG, "DisableRemoteService ProviderService - OUT");
+        return;
+    }
+
+    public void subscribeMQService(String servAdd, String topicName) {
+        Log.i(TAG, "SubscribeMQService ProviderService - IN");
+        try {
+            ioTNotification.subscribeMQService(servAdd, topicName);
+        } catch (Exception e) {
+            Log.e(TAG, "Exception: subscribeMQService : " + e);
+        }
+        Log.i(TAG, "SubscribeMQService ProviderService - OUT");
+        return;
+    }
+
+    public void acceptSubscription(Consumer consumer, boolean accepted) {
+        Log.i(TAG, "AcceptSubscription ProviderService - IN");
+        try {
+            consumer.acceptSubscription(accepted);
+        } catch (Exception e) {
+            Log.e(TAG, "Exception: acceptSubscription : " + e);
+        }
+        Log.i(TAG, "AcceptSubscription ProviderService - OUT");
+    }
+
+    @Override
+    public void onConsumerSubscribed(Consumer consumer) {
+        Log.i(TAG, "onConsumerSubscribed - IN");
+        gConsumer = consumer;
+        acceptSubscription(consumer, true);
+        android.os.Message msg = mHandler.obtainMessage(CONSUMER_SUBSCRIBED,
+                "Consumer Id: " + consumer.getConsumerId());
+        mHandler.sendMessage(msg);
+        Log.i(TAG, "onConsumerSubscribed - OUT");
+    }
+
+    @Override
+    public void onMessageSynchronized(SyncInfo syncInfo) {
+        Log.i(TAG,
+                "Received SyncInfo with messageID: " + syncInfo.getMessageId());
+        android.os.Message msg = mHandler.obtainMessage(MESSAGE_SYNC,
+                "Message Id: " + syncInfo.getMessageId());
+        mHandler.sendMessage(msg);
+    }
+
+    public HashMap<String, Integer> getMsgMap() {
+        return msgMap;
+    }
+}
diff --git a/service/notification/examples/android/NotiProviderExample/app/src/main/res/layout/activity_login.xml b/service/notification/examples/android/NotiProviderExample/app/src/main/res/layout/activity_login.xml
new file mode 100755 (executable)
index 0000000..dfd8e3c
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/loginLayout"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    tools:context=".LoginActivity">
+
+    <WebView
+        android:id="@+id/webView"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="visible" />
+
+</LinearLayout>
\ No newline at end of file
old mode 100644 (file)
new mode 100755 (executable)
index d109ae4..036ab7f
@@ -7,8 +7,12 @@
     android:paddingLeft="@dimen/activity_horizontal_margin"\r
     android:paddingRight="@dimen/activity_horizontal_margin"\r
     android:paddingTop="@dimen/activity_vertical_margin"\r
-    tools:context="com.sec.notificationexample.MainActivity">\r
+    tools:context=".MainActivity">\r
 \r
+    <ScrollView\r
+        android:layout_width="match_parent"\r
+        android:layout_height="wrap_content"\r
+        android:fillViewport="true">\r
     <LinearLayout\r
         android:layout_width="match_parent"\r
         android:layout_height="wrap_content"\r
 \r
             </RadioGroup>\r
         </LinearLayout>\r
+        <LinearLayout\r
+            android:layout_width="match_parent"\r
+            android:layout_height="wrap_content"\r
+            android:paddingLeft="5dp"\r
+            android:paddingRight="5dp"\r
+            android:orientation="horizontal"\r
+            android:weightSum="1">\r
+\r
+            <Button\r
+                android:layout_height="wrap_content"\r
+                android:layout_width="100dp"\r
+                android:id="@+id/signup"\r
+                android:text="Sign Up"/>\r
+\r
+            <Button\r
+                android:layout_height="wrap_content"\r
+                android:layout_width="100dp"\r
+                android:id="@+id/signin"\r
+                android:text="Sign In" />\r
+            <Button\r
+                android:layout_height="wrap_content"\r
+                android:layout_width="100dp"\r
+                android:id="@+id/signout"\r
+                android:text="Sign Out" />\r
+        </LinearLayout>\r
+        <LinearLayout\r
+            android:layout_width="match_parent"\r
+            android:layout_height="wrap_content"\r
+            android:paddingLeft="5dp"\r
+            android:paddingRight="5dp"\r
+            android:orientation="horizontal"\r
+            android:weightSum="1">\r
 \r
+            <Button\r
+                android:layout_height="wrap_content"\r
+                android:layout_width="150dp"\r
+                android:id="@+id/remoteService"\r
+                android:text="Enable Remote Service"/>\r
+\r
+            <Button\r
+                android:layout_height="wrap_content"\r
+                android:layout_width="150dp"\r
+                android:id="@+id/subscribeMQService"\r
+                android:text="Subscribe MQ Service" />\r
+        </LinearLayout>\r
         <LinearLayout\r
             android:layout_width="match_parent"\r
             android:layout_height="wrap_content"\r
         </ScrollView>\r
 \r
     </LinearLayout>\r
-\r
+    </ScrollView>\r
 </RelativeLayout>\r
diff --git a/service/notification/examples/android/NotiProviderExample/app/src/main/res/layout/dialog_auth.xml b/service/notification/examples/android/NotiProviderExample/app/src/main/res/layout/dialog_auth.xml
new file mode 100644 (file)
index 0000000..bd0d7ba
--- /dev/null
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent" >
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingLeft="1dp"
+        android:paddingRight="1dp"
+        android:orientation="vertical" >
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingLeft="5dp"
+            android:paddingRight="5dp"
+            android:orientation="horizontal" >
+
+            <Button
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:id="@+id/BtnAuth"
+                android:text="@string/btn_auth"
+                android:onClick="selfDestruct" />
+
+            <EditText
+                android:id="@+id/EditTextAuth"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:windowSoftInputMode="stateHidden"
+                android:hint="Add Auth Provider Name" />
+        </LinearLayout>
+
+        <LinearLayout
+            android:id="@+id/LinearBody"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingLeft="5dp"
+            android:paddingRight="5dp"
+            android:orientation="horizontal" >
+
+            <Button
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:id="@+id/BtnUrl"
+                android:text="@string/btn_url"
+                android:onClick="selfDestruct" />
+
+            <EditText
+                android:id="@+id/EditTextUrl"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:windowSoftInputMode="stateHidden"
+                android:hint="Add Login Account URL" />
+        </LinearLayout>
+
+        <Button
+            android:layout_gravity="center_vertical|center_horizontal"
+            android:layout_height="wrap_content"
+            android:layout_width="match_parent"
+            android:id="@+id/dialogButtonOK"
+            android:text="@string/btn_ok"
+            />
+    </LinearLayout>
+
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/service/notification/examples/android/NotiProviderExample/app/src/main/res/layout/dialog_entry.xml b/service/notification/examples/android/NotiProviderExample/app/src/main/res/layout/dialog_entry.xml
new file mode 100644 (file)
index 0000000..f2a147a
--- /dev/null
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent" >
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingLeft="1dp"
+        android:paddingRight="1dp"
+        android:orientation="vertical" >
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingLeft="5dp"
+            android:paddingRight="5dp"
+            android:orientation="horizontal" >
+
+            <EditText
+                android:id="@+id/EditTextEntry"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:windowSoftInputMode="stateHidden"
+                android:hint="Add Required Details" />
+        </LinearLayout>
+
+
+        <Button
+            android:layout_gravity="center_vertical|center_horizontal"
+            android:layout_height="wrap_content"
+            android:layout_width="match_parent"
+            android:id="@+id/entryButtonOK"
+            android:text="@string/btn_ok"
+            />
+    </LinearLayout>
+
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/service/notification/examples/android/NotiProviderExample/app/src/main/res/layout/dialog_mq.xml b/service/notification/examples/android/NotiProviderExample/app/src/main/res/layout/dialog_mq.xml
new file mode 100644 (file)
index 0000000..4c2d9c4
--- /dev/null
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent" >
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingLeft="1dp"
+        android:paddingRight="1dp"
+        android:orientation="vertical" >
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingLeft="5dp"
+            android:paddingRight="5dp"
+            android:orientation="horizontal" >
+
+            <Button
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:id="@+id/BtnAuth"
+                android:text="@string/btn_addr"
+                android:onClick="selfDestruct" />
+
+            <EditText
+                android:id="@+id/EditTextIp"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:windowSoftInputMode="stateHidden"
+                android:hint="Add MQ Server IP Address" />
+        </LinearLayout>
+
+        <LinearLayout
+            android:id="@+id/LinearBody"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingLeft="5dp"
+            android:paddingRight="5dp"
+            android:orientation="horizontal" >
+
+            <Button
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:id="@+id/BtnTopic"
+                android:text="@string/btn_topic"
+                android:onClick="selfDestruct" />
+
+            <EditText
+                android:id="@+id/EditTextMqTopic"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:windowSoftInputMode="stateHidden"
+                android:hint="Add MQ Topic name" />
+        </LinearLayout>
+
+        <Button
+            android:layout_gravity="center_vertical|center_horizontal"
+            android:layout_height="wrap_content"
+            android:layout_width="match_parent"
+            android:id="@+id/mqButtonOK"
+            android:text="@string/btn_ok"
+            />
+    </LinearLayout>
+
+
+</RelativeLayout>
\ No newline at end of file
old mode 100644 (file)
new mode 100755 (executable)
index 80b63f8..85be2b4
@@ -8,4 +8,10 @@
     <string name="btn_send">Send Notification</string>\r
     <string name="btn_create_noti">Send Notification</string>\r
     <string name="btn_log">Clear Logs</string>\r
+    <string name="enableRemoteService">Enable Remote Service</string>\r
+    <string name="disableRemoteService">Disable Remote Service</string>\r
+    <string name="btn_auth">Auth</string>\r
+    <string name="btn_url"> URL</string>\r
+    <string name="btn_addr"> Addr. </string>\r
+    <string name="btn_ok">Enter Details</string>\r
 </resources>\r
index 826e60f..4bc3eea 100644 (file)
@@ -23,7 +23,8 @@ notification_sample_env.PrependUnique(LIBS = [
        'octbstack',
        'oc_logger',
        'connectivity_abstraction',
-       'libcoap'
+       'libcoap',
+        'resource_directory'
        ])
 
 if target_os not in ['windows', 'winrt']:
@@ -62,8 +63,21 @@ if env.get('WITH_CLOUD') == True:
 
 if env.get('WITH_TCP') == True:
        notification_sample_env.AppendUnique(CPPDEFINES = ['WITH_TCP'])
-       if env.get('SECURED') == '1':
-               notification_sample_env.AppendUnique(LIBS = ['mbedtls', 'mbedx509', 'mbedcrypto'])
+if env.get('SECURED') == '1':
+       notification_sample_env.AppendUnique(LIBS = ['mbedtls', 'mbedx509', 'mbedcrypto'])
+
+with_mq = env.get('WITH_MQ')
+if 'SUB' in with_mq:
+    notification_sample_env.AppendUnique(CPPDEFINES = ['MQ_SUBSCRIBER', 'WITH_MQ'])
+    print "MQ SUB support"
+
+if 'PUB' in with_mq:
+    notification_sample_env.AppendUnique(CPPDEFINES = ['MQ_PUBLISHER', 'WITH_MQ'])
+    print "MQ PUB support"
+
+if 'BROKER' in with_mq:
+    notification_sample_env.AppendUnique(CPPDEFINES = ['MQ_BROKER', 'WITH_MQ'])
+    print "MQ Broker support"
 
 ####################################################################
 # Source files and Targets
index bef1e20..8c14cd3 100644 (file)
@@ -35,6 +35,7 @@
 #define CLOUD_CONTEXT_VALUE 0x99
 
 char CLOUD_ADDRESS[100];
+char CLOUD_TOPIC[100];
 char CLOUD_AUTH_PROVIDER[100];
 char CLOUD_AUTH_CODE[100];
 char CLOUD_UID[100];
@@ -169,6 +170,9 @@ int main(void)
         printf("4. Select Topics\n");
         printf("5. Cancel select Topics\n");
         printf("0. Exit\n");
+#ifdef WITH_MQ
+        printf("11. Subscribe MQ Service\n");
+#endif
 #ifdef WITH_CLOUD
         printf("21. Enable Remote Service (after login)\n");
         printf("31. Cloud Signup\n");
@@ -250,6 +254,19 @@ int main(void)
                 printf("0. Exit");
                 isExit = true;
                 break;
+#if WITH_MQ
+            case 11:
+                printf("11. Subscribe MQ Service\n");
+
+                printf("Remote Server Address: ");
+                input(CLOUD_ADDRESS);
+
+                printf("Topic[notification]: ");
+                input(CLOUD_TOPIC);
+
+                NSConsumerSubscribeMQService(CLOUD_ADDRESS, CLOUD_TOPIC);
+                break;
+#endif
 #ifdef WITH_CLOUD
             case 21:
                 printf("Enable Remote Service");
index c864669..11c1c36 100644 (file)
@@ -22,7 +22,6 @@
 #include <stdbool.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include <ctype.h>
 
 #include "NSProviderInterface.h"
 #include "NSCommon.h"
@@ -46,6 +45,11 @@ char UID[50] = {'\0',};
 char ACCESS_TOKEN[50] = {'\0',};
 #endif
 
+#ifdef WITH_MQ
+char CLOUD_ADDRESS[100] = "10.113.64.52:5686";
+char CLOUD_TOPIC[100] = "/oic/ps/notification";
+#endif
+
 char mainConsumer[37] = {'\0',};
 
 extern char *strdup(const char *s);
@@ -181,7 +185,8 @@ int main()
         printf("8.  NSProviderUnselectTopic(); \n");
         printf("9.  NSProviderGetConsumerTopics(); \n");
         printf("10. NSProviderGetTopics(); \n");
-        printf("11. NSStopProvider() \n");
+        printf("11. NSProviderSubscribeMQService() \n");
+        printf("0. NSStopProvider() \n");
 #ifdef WITH_CLOUD
         printf("21. NSProviderEnableRemoteService (after login) \n");
         printf("22. NSProviderDisableRemoteService (after login) \n");
@@ -194,7 +199,7 @@ int main()
 
         printf("input : ");
 
-        if(scanf("%d", &num) > 0 && isdigit(num) == 0)
+        if(scanf("%d", &num) > 0)
         {
             if(scanf("%c", &dummy) > 0)
             {
@@ -249,6 +254,7 @@ int main()
                 input(body);
 
                 printf("topic : ");
+
                 input(topic);
 
                 printf("app - mTitle : %s \n", title);
@@ -321,9 +327,20 @@ int main()
                 }
                 break;
 
+#if WITH_MQ
             case 11:
-                NSStopProvider();
+                printf("11. Subscribe MQ Service\n");
+
+                printf("Remote Server Address: ");
+                //input(CLOUD_ADDRESS);
+
+                printf("Topic[notificationtest]: ");
+                //input(CLOUD_TOPIC);
+
+                NSProviderSubscribeMQService(CLOUD_ADDRESS, CLOUD_TOPIC);
                 break;
+#endif
+
 #ifdef WITH_CLOUD
             case 21:
                 printf("Enable Remote Service\n");
index 82cf21a..35200df 100644 (file)
@@ -31,7 +31,7 @@
 #include <octypes.h>
 
 #define NS_UUID_STRING_SIZE 37
-
+//#define WITH_MQ
 /**
  * Result code of notification service
  */
@@ -81,6 +81,8 @@ typedef enum
     NS_MESSAGE_EVENT = 3,
     NS_MESSAGE_INFO = 4,
     NS_MESSAGE_WARNING = 5,
+    NS_MESSAGE_READ = 11,
+    NS_MESSAGE_DELETED = 12
 
 } NSMessageType;
 
index 42c1dcb..a25675f 100644 (file)
@@ -82,7 +82,17 @@ NSResult NSStopConsumer();
  * @param[in] server address combined with IP address and port number using delimiter :
  * @return ::NS_OK or result code of NSResult
  */
-NSResult NSConsumerEnableRemoteService(const char *serverAddress);
+NSResult NSConsumerEnableRemoteService(const char * serverAddress);
+
+#ifdef WITH_MQ
+/**
+ * Request to subscribe to remote MQ address as parameter.
+ * @param[in] server address combined with IP address and port number and MQ broker uri using delimiter :
+ * @param[in] topicName the interest MQ Topic name for subscription.
+ * @return ::NS_OK or result code of NSResult
+ */
+NSResult NSConsumerSubscribeMQService(const char * serverAddress, const char * topicName);
+#endif
 
 /**
  * Request discovery manually
@@ -98,6 +108,13 @@ NSResult NSRescanProvider();
 NSResult NSSubscribe(const char * providerId);
 
 /**
+ * Request to unsubscribe in order not to receive notification message from provider
+ * @param[in]  providerId  the Id of Provider who send the notification message
+ * @return ::NS_OK or result code of NSResult
+ */
+NSResult NSUnsubscribe(const char * providerId);
+
+/**
  * Send sync type to provider in order to synchronize notification status with other consumers
  * when consumer consumes the notification such as READ, DELETE
  * @param[in] providerId Provider id of the Notification message
index 0616233..260c554 100644 (file)
@@ -35,7 +35,6 @@ extern "C"
 #include "NSCommon.h"\r
 #include <stdbool.h>\r
 #include <stdint.h>\r
-\r
 /**\r
  * Invoked when provider receives the subscription request of consumer.\r
  * @param[in] consumer  Consumer who subscribes the notification message resource\r
@@ -99,6 +98,16 @@ NSResult NSProviderEnableRemoteService(char * serverAddress);
  */\r
 NSResult NSProviderDisableRemoteService(char * serverAddress);\r
 \r
+#ifdef WITH_MQ\r
+/**\r
+ * Request to subscribe to remote MQ address as parameter.\r
+ * @param[in] server address combined with IP address and port number and MQ broker uri using delimiter :\r
+ * @param[in] topicName the interest Topic name for subscription.\r
+ * @return ::NS_OK or result code of NSResult\r
+ */\r
+NSResult NSProviderSubscribeMQService(const char * serverAddress, const char * topicName);\r
+#endif\r
+\r
 /**\r
  * Send notification message to all subscribers\r
  * @param[in]  message  Notification message including id, title, contentText\r
index 3cbfbf4..ba95e57 100644 (file)
         ((level) == 0) ? DLOG_DEBUG : \
         ((level) == 1) ? DLOG_INFO : \
         ((level) == 2) ? DLOG_WARN : \
-    ((level) == 3) ? DLOG_ERROR : DLOG_ERROR)
+        ((level) == 3) ? DLOG_ERROR : \
+        ((level) == 4) ? DLOG_ERROR : \
+        ((level) == 5) ? DLOG_INFO : \
+        ((level) == 6) ? DLOG_INFO : \
+        ((level) == 7) ? DLOG_INFO : DLOG_INFO)
 #define NS_LOG_V(level, format, ...) (dlog_print(NS_CONVERT_LEVEL(level), LOG_TAG, (format), __VA_ARGS__))
 #define NS_LOG(level, msg) (dlog_print(NS_CONVERT_LEVEL(level), LOG_TAG, (msg)))
 #else // __TIZEN__
-#define NS_LOG_V(level, format, ...) (OIC_LOG_V((level), __NS_FILE__, (format), __VA_ARGS__))
-#define NS_LOG(level, msg) (OIC_LOG((level), __NS_FILE__, (msg)))
+#define NS_LOG_V(level, format, ...) OIC_LOG_V((level), __NS_FILE__, (format), __VA_ARGS__)
+#define NS_LOG(level, msg) OIC_LOG((level), __NS_FILE__, (msg))
 #endif // __TIZEN__
 #else // TB_LOG
 #if (__PRINTLOG == 1)
         ((level) == 0) ? "DEBUG" : \
         ((level) == 1) ? "INFO" : \
         ((level) == 2) ? "WARNING" : \
-    ((level) == 3) ? "ERROR" : "FATAL")
+        ((level) == 3) ? "ERROR" : \
+        ((level) == 4) ? "FATAL" : \
+        ((level) == 5) ? "DEBUG_LITE" : \
+        ((level) == 6) ? "INFO_LITE" : \
+        ((level) == 7) ? "INFO_PRIVATE" : "INFO_PRIVATE")
 #define NS_LOG_V(level, format, ...) \
     { \
         printf("%s: %s ", NS_CONVERT_LEVEL(level), __NS_FILE__); \
@@ -76,9 +84,9 @@
 #define THREAD_COUNT               5
 
 // NOTIOBJ //
-#define NOTIOBJ_TITLE_KEY          "title"
-#define NOTIOBJ_ID_KEY             "id"
-#define NOTOOBJ_CONTENT_KEY        "contenttext"
+#define NOTIOBJ_TITLE_KEY          "x.org.iotivity.ns.title"
+#define NOTIOBJ_ID_KEY             "x.org.iotivity.ns.id"
+#define NOTOOBJ_CONTENT_KEY        "x.org.iotivity.ns.contenttext"
 
 #define DISCOVERY_TAG              "NS_PROVIDER_DISCOVERY"
 #define SUBSCRIPTION_TAG           "NS_PROVIDER_SUBSCRIPTION"
 #define RESOURCE_TAG               "NS_PROVIDER_RESOURCE"
 #define TOPIC_TAG                  "NS_PROVIDER_TOPIC"
 
-#define NS_ROOT_TYPE               "oic.wk.notification"
-#define NS_COLLECTION_MESSAGE_TYPE "oic.wk.notification.message"
-#define NS_COLLECTION_SYNC_TYPE    "oic.wk.notification.sync"
-#define NS_COLLECTION_TOPIC_TYPE   "oic.wk.notification.topic"
+#define NS_ROOT_TYPE               "x.org.iotivity.notification"
+#define NS_COLLECTION_MESSAGE_TYPE "x.org.iotivity.notification.message"
+#define NS_COLLECTION_SYNC_TYPE    "x.org.iotivity.notification.sync"
+#define NS_COLLECTION_TOPIC_TYPE   "x.org.iotivity.notification.topic"
 
 #define NS_INTERFACE_READ          "oic.if.r"
 #define NS_INTERFACE_READWRITE     "oic.if.rw"
-#define NS_INTERFACE_BASELINE       "oic.if.baseline"
+#define NS_INTERFACE_BASELINE      "oic.if.baseline"
 
 #define NS_ROOT_URI                "/notification"
 #define NS_COLLECTION_MESSAGE_URI  "/notification/message"
 #define NS_QUERY_SEPARATOR         "&;"
 #define NS_KEY_VALUE_DELIMITER     "="
 
-#define NS_QUERY_CONSUMER_ID       "consumerid"
-#define NS_QUERY_PROVIDER_ID       "providerid"
+#define NS_QUERY_CONSUMER_ID       "x.org.iotivity.ns.consumerid"
+#define NS_QUERY_PROVIDER_ID       "x.org.iotivity.ns.providerid"
 #define NS_QUERY_INTERFACE         "if"
 
 #define NS_QUERY_ID_SIZE           10
 
 #define NS_RD_PUBLISH_QUERY        "/oic/rd?rt=oic.wk.rdpub"
 
+#ifdef WITH_MQ
+#define NS_ATTRIBUTE_MQ_MESSAGE   "x.org.iotivity.ns.message"
+#define NS_ATTIRBUTE_MQ_TOPICLIST "x.org.iotivity.ns.topiclist"
+#endif
+
 #define NS_VERIFY_NOT_NULL_V(obj) \
     { \
         if ((obj) == NULL) \
 
 #define VERSION        "1.2.1"
 
-#define NS_ATTRIBUTE_VERSION "version"
-#define NS_ATTRIBUTE_POLICY "subcontrollability"
-#define NS_ATTRIBUTE_MESSAGE "messageuri"
-#define NS_ATTRIBUTE_SYNC "syncuri"
-#define NS_ATTRIBUTE_TOPIC "topicuri"
-#define NS_ATTRIBUTE_MESSAGE_ID "messageid"
-#define NS_ATTRIBUTE_PROVIDER_ID "providerid"
-#define NS_ATTRIBUTE_CONSUMER_ID "consumerid"
-#define NS_ATTRIBUTE_TOPIC_LIST "topiclist"
-#define NS_ATTRIBUTE_TOPIC_NAME "topicname"
-#define NS_ATTRIBUTE_TOPIC_SELECTION "topicstate"
-#define NS_ATTRIBUTE_TITLE "title"
-#define NS_ATTRIBUTE_TEXT "contenttext"
-#define NS_ATTRIBUTE_SOURCE "source"
-#define NS_ATTRIBUTE_STATE "state"
-#define NS_ATTRIBUTE_DEVICE "device"
-#define NS_ATTRIBUTE_TYPE "type"
-#define NS_ATTRIBUTE_DATETIME "datetime"
-#define NS_ATTRIBUTE_TTL "ttl"
-#define NS_ATTRIBUTE_ICON_IMAGE "iconimage"
+#define NS_ATTRIBUTE_VERSION "x.org.iotivity.ns.version"
+#define NS_ATTRIBUTE_POLICY "x.org.iotivity.ns.subcontrollability"
+#define NS_ATTRIBUTE_MESSAGE "x.org.iotivity.ns.messageuri"
+#define NS_ATTRIBUTE_SYNC "x.org.iotivity.ns.syncuri"
+#define NS_ATTRIBUTE_TOPIC "x.org.iotivity.ns.topicuri"
+#define NS_ATTRIBUTE_MESSAGE_ID "x.org.iotivity.ns.messageid"
+#define NS_ATTRIBUTE_PROVIDER_ID "x.org.iotivity.ns.providerid"
+#define NS_ATTRIBUTE_CONSUMER_ID "x.org.iotivity.ns.consumerid"
+#define NS_ATTRIBUTE_TOPIC_LIST "x.org.iotivity.ns.topiclist"
+#define NS_ATTRIBUTE_TOPIC_NAME "x.org.iotivity.ns.topicname"
+#define NS_ATTRIBUTE_TOPIC_SELECTION "x.org.iotivity.ns.topicstate"
+#define NS_ATTRIBUTE_TITLE "x.org.iotivity.ns.title"
+#define NS_ATTRIBUTE_TEXT "x.org.iotivity.ns.contenttext"
+#define NS_ATTRIBUTE_SOURCE "x.org.iotivity.ns.source"
+#define NS_ATTRIBUTE_STATE "x.org.iotivity.ns.state"
+#define NS_ATTRIBUTE_DEVICE "x.org.iotivity.ns.device"
+#define NS_ATTRIBUTE_TYPE "x.org.iotivity.ns.type"
+#define NS_ATTRIBUTE_DATETIME "x.org.iotivity.ns.datetime"
+#define NS_ATTRIBUTE_TTL "x.org.iotivity.ns.ttl"
+#define NS_ATTRIBUTE_ICON_IMAGE "x.org.iotivity.ns.iconimage"
 
 typedef enum eConnectionState
 {
@@ -235,10 +248,15 @@ typedef enum eSchedulerType
     SUBSCRIPTION_SCHEDULER = 2,
     NOTIFICATION_SCHEDULER = 3,
     TOPIC_SCHEDULER = 4,
+
 } NSSchedulerType;
 
 typedef enum eTaskType
 {
+#ifdef WITH_MQ
+    TASK_MQ_REQ_SUBSCRIBE = 20001,
+#endif
+
     TASK_REGISTER_RESOURCE = 1000,
     TASK_PUBLISH_RESOURCE = 1001,
 
@@ -315,6 +333,7 @@ typedef enum eCacheType
 
     NS_CONSUMER_CACHE_PROVIDER = 2000,
     NS_CONSUMER_CACHE_MESSAGE = 2001,
+
 } NSCacheType;
 
 typedef enum eResourceType
@@ -322,12 +341,14 @@ typedef enum eResourceType
     NS_RESOURCE_MESSAGE = 1000,
     NS_RESOURCE_SYNC = 1001,
     NS_RESOURCE_TOPIC = 1002,
+
 } NSResourceType;
 
 typedef enum eInterfaceType
 {
     NS_INTERFACE_TYPE_READ = 1,
     NS_INTERFACE_TYPE_READWRITE = 2,
+
 } NSInterfaceType;
 
 #endif /* _NS_CONSTANTS_H_ */
index 6da4371..39126bc 100644 (file)
@@ -35,6 +35,7 @@ typedef struct _nsTask
     NSTaskType taskType;\r
     void * taskData;\r
     struct _nsTask * nextTask;\r
+\r
 } NSTask;\r
 \r
 typedef struct\r
@@ -52,6 +53,7 @@ typedef struct _NSCacheElement
 {\r
     NSCacheData * data;\r
     struct _NSCacheElement * next;\r
+\r
 } NSCacheElement;\r
 \r
 typedef struct\r
@@ -59,6 +61,7 @@ typedef struct
     NSCacheType cacheType;\r
     NSCacheElement * head;\r
     NSCacheElement * tail;\r
+\r
 } NSCacheList;\r
 \r
 typedef struct\r
@@ -69,6 +72,7 @@ typedef struct
     int remote_syncObId; //sync observer ID subscribed through remote server\r
     int remote_messageObId; //message observer ID subscribed through remote server\r
     bool isWhite; // access state -> True: allowed / False: blocked\r
+\r
 } NSCacheSubData;\r
 \r
 typedef struct\r
@@ -76,6 +80,7 @@ typedef struct
     char * id;\r
     int messageType; // noti = 1, read = 2, dismiss = 3\r
     NSMessage * nsMessage;\r
+\r
 } NSCacheMsgData;\r
 \r
 typedef struct\r
@@ -103,6 +108,7 @@ typedef struct
 \r
     //optional\r
     char * topic_uri;\r
+\r
 } NSNotificationResource;\r
 \r
 typedef struct\r
@@ -121,6 +127,7 @@ typedef struct
     char * sourceName;\r
     char * topicName;\r
     NSMediaContents * mediaContents;\r
+\r
 } NSMessageResource;\r
 \r
 typedef struct\r
@@ -129,6 +136,7 @@ typedef struct
     uint64_t messageId;\r
     char providerId[NS_UUID_STRING_SIZE];\r
     char * state;\r
+\r
 } NSSyncResource;\r
 \r
 typedef struct\r
@@ -137,6 +145,7 @@ typedef struct
     char providerId[NS_UUID_STRING_SIZE];\r
     char consumerId[NS_UUID_STRING_SIZE];\r
     NSTopicList ** TopicList;\r
+\r
 } NSTopicResource;\r
 \r
 typedef struct\r
@@ -144,6 +153,23 @@ typedef struct
     char providerId[NS_UUID_STRING_SIZE];\r
     char * providerName;\r
     char * userInfo;\r
+\r
 } NSProviderInfo;\r
 \r
+#ifdef WITH_MQ\r
+typedef struct\r
+{\r
+    char * serverAddr;\r
+    char * topicName;\r
+\r
+} NSMQTopicAddress;\r
+\r
+typedef struct\r
+{\r
+    char * serverUri;\r
+    OCDevAddr * devAddr;\r
+\r
+} NSMQServerInfo;\r
+#endif\r
+\r
 #endif /* _NS_STRUCTS_H_ */\r
index 14ca14b..8efb307 100755 (executable)
@@ -29,13 +29,16 @@ OCEntityHandlerRequest *NSCopyOCEntityHandlerRequest(OCEntityHandlerRequest *ent
 
     if (copyOfRequest)
     {
-        // Do shallow copy
         memcpy(copyOfRequest, entityHandlerRequest, sizeof(OCEntityHandlerRequest));
+        copyOfRequest->payload = NULL;
+        copyOfRequest->query = NULL;
+        copyOfRequest->numRcvdVendorSpecificHeaderOptions = 0;
+        copyOfRequest->rcvdVendorSpecificHeaderOptions = NULL;
 
-        if (copyOfRequest->query)
+        if (entityHandlerRequest->query)
         {
             copyOfRequest->query = OICStrdup(entityHandlerRequest->query);
-            if(!copyOfRequest->query)
+            if (!copyOfRequest->query)
             {
                 NS_LOG(ERROR, "Copy failed due to allocation failure");
                 OICFree(copyOfRequest);
@@ -48,10 +51,6 @@ OCEntityHandlerRequest *NSCopyOCEntityHandlerRequest(OCEntityHandlerRequest *ent
             copyOfRequest->payload = (OCPayload *)
                     (OCRepPayloadClone ((OCRepPayload*) entityHandlerRequest->payload));
         }
-
-        // Ignore vendor specific header options for example
-        copyOfRequest->numRcvdVendorSpecificHeaderOptions = 0;
-        copyOfRequest->rcvdVendorSpecificHeaderOptions = NULL;
     }
 
     if (copyOfRequest)
@@ -107,7 +106,7 @@ NSMessage * NSDuplicateMessage(NSMessage * copyMsg)
 {
     NSMessage * newMsg = NULL;
 
-    if(copyMsg == NULL)
+    if (copyMsg == NULL)
     {
         NS_LOG(ERROR, "Copy Msg is NULL");
         return NULL;
@@ -119,7 +118,7 @@ NSMessage * NSDuplicateMessage(NSMessage * copyMsg)
     newMsg->messageId = copyMsg->messageId;
     OICStrcpy(newMsg->providerId, UUID_STRING_SIZE, copyMsg->providerId);
 
-    if(copyMsg->dateTime)
+    if (copyMsg->dateTime)
     {
         newMsg->dateTime = OICStrdup(copyMsg->dateTime);
     }
@@ -175,7 +174,7 @@ NSSyncInfo* NSDuplicateSync(NSSyncInfo * copyMsg)
 {
     NSSyncInfo * newMsg = NULL;
 
-    if(!copyMsg)
+    if (!copyMsg)
     {
         NS_LOG(ERROR, "Copy Msg is NULL");
         return NULL;
@@ -183,7 +182,7 @@ NSSyncInfo* NSDuplicateSync(NSSyncInfo * copyMsg)
 
     newMsg = (NSSyncInfo *)OICMalloc(sizeof(NSSyncInfo));
 
-    if(!newMsg)
+    if (!newMsg)
     {
         NS_LOG(ERROR, "newMsg is NULL");
         return NULL;
@@ -215,7 +214,7 @@ NSConsumer* NSDuplicateConsumer(NSConsumer * copyMsg)
 {
     NSConsumer * newMsg = NULL;
 
-    if(copyMsg == NULL)
+    if (copyMsg == NULL)
     {
         NS_LOG(ERROR, "Copy Msg is NULL");
         return NULL;
@@ -223,7 +222,7 @@ NSConsumer* NSDuplicateConsumer(NSConsumer * copyMsg)
 
     newMsg = (NSConsumer *)OICMalloc(sizeof(NSConsumer));
 
-    if(!newMsg)
+    if (!newMsg)
     {
         NS_LOG(ERROR, "newMsg is NULL");
         return NULL;
@@ -239,7 +238,7 @@ NSConsumer* NSDuplicateConsumer(NSConsumer * copyMsg)
 void NSDuplicateSetPropertyString(OCRepPayload** msgPayload, const char * name,
         const char * copyString)
 {
-    if(copyString)
+    if (copyString)
     {
         OCRepPayloadSetPropString(*msgPayload, name, copyString);
     }
@@ -248,7 +247,7 @@ void NSDuplicateSetPropertyString(OCRepPayload** msgPayload, const char * name,
 void NSDuplicateSetPropertyInt(OCRepPayload** msgPayload, const char * name,
         int64_t value)
 {
-    if(value)
+    if (value)
     {
         OCRepPayloadSetPropInt(*msgPayload, name, value);
     }
@@ -260,11 +259,13 @@ NSSyncInfo * NSGetSyncInfo(OCPayload * payload)
     char * providerId = NULL;
     int64_t state = 0;
 
-    if(!payload)
+    if (!payload)
     {
         return NULL;
     }
+
     NSSyncInfo * retSync = (NSSyncInfo *)OICMalloc(sizeof(NSSyncInfo));
+
     if (!retSync)
     {
         return NULL;
@@ -272,8 +273,8 @@ NSSyncInfo * NSGetSyncInfo(OCPayload * payload)
 
     retSync->messageId = 0;
     retSync->state = NS_SYNC_READ;
-
     OCRepPayload * repPayload = (OCRepPayload *)payload;
+
     if (!OCRepPayloadGetPropInt(repPayload, NS_ATTRIBUTE_MESSAGE_ID,
             (int64_t *)&retSync->messageId))
     {
@@ -297,7 +298,7 @@ NSSyncInfo * NSGetSyncInfo(OCPayload * payload)
     OICStrcpy(retSync->providerId, UUID_STRING_SIZE, providerId);
     OICFree(providerId);
 
-    NS_LOG_V(DEBUG, "Provider ID : %s", retSync->providerId);
+    NS_LOG_V(INFO_PRIVATE, "Provider ID : %s", retSync->providerId);
     NS_LOG_V(DEBUG, "Sync ID : %lld", (long long int)retSync->messageId);
     NS_LOG_V(DEBUG, "Sync State : %d", (int) retSync->state);
 
@@ -329,7 +330,7 @@ char * NSGetValueFromQuery(char *query, char * compareKey)
 
     NS_LOG_V(INFO, "NS Query Params = %s", query);
 
-    if(!query || query[0] == '\0' || !strlen(query))
+    if (!query || query[0] == '\0' || !strlen(query))
     {
         NS_LOG(ERROR, "query is null or \\0 or size is 0");
         return NULL;
@@ -369,7 +370,7 @@ char * NSGetValueFromQuery(char *query, char * compareKey)
 
 NSResult NSFreeMalloc(char ** obj)
 {
-    if(*obj)
+    if (*obj)
     {
         OICFree(*obj);
         *obj = NULL;
@@ -381,20 +382,20 @@ NSResult NSFreeMalloc(char ** obj)
 
 NSMediaContents * NSDuplicateMediaContents(NSMediaContents * copyObj)
 {
-    if(!copyObj)
+    if (!copyObj)
     {
         return NULL;
     }
 
     NSMediaContents * newObj = (NSMediaContents *)OICMalloc(sizeof(NSMediaContents));
 
-    if(!newObj)
+    if (!newObj)
     {
         NS_LOG(ERROR, "contents newObj is NULL");
         return NULL;
     }
 
-    if(copyObj->iconImage)
+    if (copyObj->iconImage)
     {
         newObj->iconImage = OICStrdup(copyObj->iconImage);
     }
@@ -404,7 +405,7 @@ NSMediaContents * NSDuplicateMediaContents(NSMediaContents * copyObj)
 
 NSResult NSFreeMediaContents(NSMediaContents * obj)
 {
-    if(!obj)
+    if (!obj)
     {
         return NS_FAIL;
     }
@@ -419,7 +420,7 @@ NSMessage * NSInitializeMessage()
 {
     NSMessage * msg = (NSMessage *)OICMalloc(sizeof(NSMessage));
 
-    if(!msg)
+    if (!msg)
     {
         NS_LOG(ERROR, "Msg is NULL");
         return NULL;
@@ -449,7 +450,8 @@ OCRepPayloadValue* NSPayloadFindValue(const OCRepPayload* payload, const char* n
     }
 
     OCRepPayloadValue* val = payload->values;
-    while(val)
+
+    while (val)
     {
         if (0 == strcmp(val->name, name))
         {
@@ -465,7 +467,7 @@ NSTopicList * NSInitializeTopicList()
 {
     NSTopicList * topicList = (NSTopicList *)OICMalloc(sizeof(NSTopicList));
 
-    if(!topicList)
+    if (!topicList)
     {
         NS_LOG(ERROR, "topicList is NULL");
         return NULL;
@@ -478,16 +480,142 @@ NSTopicList * NSInitializeTopicList()
     return topicList;
 }
 
-NSResult NSFreeTopicList(NSTopicList * topicList)
+OCDevAddr * NSChangeAddress(const char * inputaddress)
 {
-    if (!topicList)
+    NS_VERIFY_NOT_NULL(inputaddress, NULL);
+
+    char * address = (char *)inputaddress;
+    char * schema = strstr(inputaddress, "//");
+    if (schema)
     {
-        return NS_ERROR;
+        address = schema + 2;
+    }
+    size_t prefixLen = schema - inputaddress;
+    if (prefixLen <= 0)
+    {
+        NS_LOG(ERROR, "Invalid Input address.");
+        return NULL;
     }
 
-    //TODO:Free Topic List
+    OCTransportFlags flags = OC_DEFAULT_FLAGS;
+    OCTransportAdapter adapter = OC_ADAPTER_IP;
+    if (strstr(inputaddress, "coap+tcp://"))
+    {
+        NS_LOG(DEBUG, "address : TCP");
+        adapter = OC_ADAPTER_TCP;
+    }
+    else if (strstr(inputaddress, "coaps://"))
+    {
+        NS_LOG(DEBUG, "address : UDP + SECURED");
+        flags |= OC_FLAG_SECURE;
+    }
+    else if (strstr(inputaddress, "coaps+tcp://"))
+    {
+        NS_LOG(DEBUG, "address : TCP + SECURED");
+        flags |= OC_FLAG_SECURE;
+        adapter = OC_ADAPTER_TCP;
+    }
+    else if (strstr(inputaddress, "coap://"))
+    {
+        NS_LOG(DEBUG, "address : UDP");
+    }
+    else
+    {
+        NS_LOG(ERROR, "Invalid CoAP Schema.");
+        return NULL;
+    }
 
+    OCDevAddr * retAddr = NULL;
+    retAddr = (OCDevAddr *) OICMalloc(sizeof(OCDevAddr));
+    NS_VERIFY_NOT_NULL(retAddr, NULL);
 
-    return NS_OK;
+    char * start = address;
+    char * end = address;
+    if (address[0] == '[')
+    {
+        flags |= OC_IP_USE_V6;
+        end = strchr(++address, ']');
+        if (!end || end <= start)
+        {
+            NS_LOG(ERROR, "Invalid Input Address - IPv6.");
+            NSOICFree(retAddr);
+            return NULL;
+        }
+        memset(retAddr->addr, 0, (size_t)MAX_ADDR_STR_SIZE);
+        OICStrcpy(retAddr->addr, (size_t)(end-start), address);
+    }
+    else
+    {
+        flags |= OC_IP_USE_V4;
+        end = strchr(address, ':');
+        if (!end || end <= start)
+        {
+            NS_LOG(ERROR, "Invalid Input Address - IPv4.");
+            NSOICFree(retAddr);
+            return NULL;
+        }
+        char * end2 = strchr(end + 1, ':');
+        if (end2)
+        {
+            NS_LOG(ERROR, "Invalid Input Address - IPv4.");
+            NSOICFree(retAddr);
+            return NULL;
+        }
+        memset(retAddr->addr, 0, (size_t)MAX_ADDR_STR_SIZE);
+        OICStrcpy(retAddr->addr, (size_t)(end-start)+1, address);
+    }
+
+    retAddr->adapter = adapter;
+    retAddr->flags = flags;
+
+    address = end + 1;
+    int tmp = 0;
+    if (flags & OC_IP_USE_V6)
+    {
+        address++;
+    }
+    uint16_t port = address[tmp++] - '0';
+
+    while(true)
+    {
+        if (address[tmp] == '\0' || address[tmp] > '9' || address[tmp] < '0')
+        {
+            break;
+        }
+        if (tmp >= 5 || (port >= 6553 && (address[tmp] -'0') >= 6))
+        {
+            NS_LOG_V(ERROR, "Invalid Input Address - Port. %d", tmp+1);
+            NSOICFree(retAddr);
+            return NULL;
+        }
+        port *= 10;
+        port += address[tmp++] - '0';
+    }
+
+    retAddr->port = port;
+
+    NS_LOG(DEBUG, "Change Address for TCP request");
+    NS_LOG_V(INFO_PRIVATE, "Origin : %s", inputaddress);
+    NS_LOG_V(INFO_PRIVATE, "Changed Addr : %s", retAddr->addr);
+    NS_LOG_V(INFO_PRIVATE, "Changed Port : %d", retAddr->port);
+
+    return retAddr;
+}
+
+bool NSOCResultToSuccess(OCStackResult ret)
+{
+    switch (ret)
+    {
+        case OC_STACK_OK:
+        case OC_STACK_RESOURCE_CREATED:
+        case OC_STACK_RESOURCE_DELETED:
+        case OC_STACK_PRESENCE_STOPPED:
+        case OC_STACK_CONTINUE:
+        case OC_STACK_RESOURCE_CHANGED:
+            return true;
+        default:
+            NS_LOG_V(DEBUG, "OCStackResult : %d", (int)ret);
+            return false;
+    }
 }
 
index b6bfd79..a48ac14 100755 (executable)
@@ -63,4 +63,7 @@ NSMediaContents * NSDuplicateMediaContents(NSMediaContents * copyObj);
 \r
 OCRepPayloadValue* NSPayloadFindValue(const OCRepPayload* payload, const char* name);\r
 \r
+OCDevAddr * NSChangeAddress(const char * address);\r
+bool NSOCResultToSuccess(OCStackResult ret);\r
+\r
 #endif /* _NS_UTIL__H_ */\r
index 7bf8986..d5ba096 100644 (file)
 
 #include <pthread.h>
 
+static bool NSIsExtraValue(const char * name);
+static void NSCopyPayloadValueArray(OCRepPayloadValue* dest, OCRepPayloadValue* source);
+static OCRepPayloadValue * NSCopyPayloadValue(OCRepPayloadValue * value);
+
 pthread_mutex_t ** NSGetStackMutex()
 {
     static pthread_mutex_t * g_stackMutext = NULL;
@@ -134,9 +138,20 @@ typedef struct
 
 void * NSProviderChangedFunc(void * obj)
 {
+    NS_LOG_V(DEBUG, "%s IN", __func__);
     NSProviderChangedData * data = (NSProviderChangedData *) obj;
-    (*(NSGetProviderChangedCb()))(data->provider, data->state);
+    NSProviderStateCallback cb = *(NSGetProviderChangedCb());
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(cb, NULL,
+    {
+        NSRemoveProvider(data->provider);
+        NSOICFree(data);
+    });
+    NS_LOG(DEBUG, "Callback to user");
+    cb(data->provider, data->state);
+    NS_LOG(DEBUG, "Callback is Returned");
+
     NSOICFree(data);
+    NS_LOG_V(DEBUG, "%s OUT", __func__);
     return NULL;
 }
 
@@ -247,6 +262,131 @@ NSTask * NSMakeTask(NSTaskType type, void * data)
     return retTask;
 }
 
+static NSMessage * NSCreateMessage_internal(uint64_t id, const char * providerId)
+{
+    NSMessage * retMsg = (NSMessage *)OICMalloc(sizeof(NSMessage));
+    NS_VERIFY_NOT_NULL(retMsg, NULL);
+
+    retMsg->messageId = id;
+    OICStrcpy(retMsg->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, providerId);
+    retMsg->title = NULL;
+    retMsg->contentText = NULL;
+    retMsg->sourceName = NULL;
+    retMsg->topic = NULL;
+    retMsg->type = NS_MESSAGE_INFO;
+    retMsg->dateTime = NULL;
+    retMsg->ttl = 0;
+    retMsg->mediaContents = NULL;
+    retMsg->extraInfo = NULL;
+
+    return retMsg;
+}
+
+static OCRepPayload * NSGetExtraInfo(OCRepPayload * payload)
+{
+    NS_LOG(DEBUG, "get extra info");
+    OCRepPayload * extraInfo = OCRepPayloadCreate();
+    NS_VERIFY_NOT_NULL(extraInfo, NULL);
+    OCRepPayload * origin = OCRepPayloadClone(payload);
+
+    bool isFirstExtra = true;
+    OCRepPayloadValue * headValue = NULL;
+    OCRepPayloadValue * curValue = NULL;
+    OCRepPayloadValue * value = origin->values;
+    while(value)
+    {
+        if (NSIsExtraValue(value->name))
+        {
+            curValue = NSCopyPayloadValue(value);
+            NS_LOG_V(DEBUG, " key : %s", curValue->name);
+            if (isFirstExtra)
+            {
+                headValue = curValue;
+                extraInfo->values = headValue;
+                isFirstExtra = false;
+            }
+            else
+            {
+                headValue->next = curValue;
+                headValue = curValue;
+            }
+            curValue = NULL;
+        }
+        value = value->next;
+    }
+    OCRepPayloadDestroy(origin);
+
+
+    if (!isFirstExtra && extraInfo->values)
+    {
+        return extraInfo;
+    }
+    else
+    {
+        OCRepPayloadDestroy(extraInfo);
+        return NULL;
+    }
+}
+
+NSMessage * NSGetMessage(OCRepPayload * payload)
+{
+    NS_LOG(DEBUG, "get msg id");
+    uint64_t id = 0;
+    bool getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, (int64_t *)&id);
+    NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
+
+    NS_LOG(DEBUG, "get provider id");
+    char * pId = NULL;
+    getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, &pId);
+    NS_LOG_V (INFO_PRIVATE, "provider id: %s", pId);
+    NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
+
+    NS_LOG(DEBUG, "create NSMessage");
+    NSMessage * retMsg = NSCreateMessage_internal(id, pId);
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(retMsg, NULL, NSOICFree(pId));
+    NSOICFree(pId);
+
+    NS_LOG(DEBUG, "get msg optional field");
+    OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_TITLE, &retMsg->title);
+    OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_TEXT, &retMsg->contentText);
+    OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_SOURCE, &retMsg->sourceName);
+    OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_TOPIC_NAME, &retMsg->topic);
+
+    OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_TYPE, (int64_t *)&retMsg->type);
+    OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_DATETIME, &retMsg->dateTime);
+    OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_TTL, (int64_t *)&retMsg->ttl);
+
+    char * icon = NULL;
+    OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_ICON_IMAGE, &icon);
+
+    if (icon && strlen(icon))
+    {
+        NSMediaContents * contents = (NSMediaContents *)OICMalloc(sizeof(NSMediaContents));
+        if (contents)
+        {
+            contents->iconImage = icon;
+            retMsg->mediaContents = contents;
+        }
+        else
+        {
+            NSOICFree(icon);
+        }
+    }
+
+    retMsg->extraInfo = NSGetExtraInfo(payload);
+
+    NS_LOG_V(DEBUG, "Msg ID      : %lld", (long long int)retMsg->messageId);
+    NS_LOG_V(DEBUG, "Msg Title   : %s", retMsg->title);
+    NS_LOG_V(DEBUG, "Msg Content : %s", retMsg->contentText);
+    NS_LOG_V(DEBUG, "Msg Source  : %s", retMsg->sourceName);
+    NS_LOG_V(DEBUG, "Msg Topic   : %s", retMsg->topic);
+    NS_LOG_V(DEBUG, "Msg Type    : %d", retMsg->type);
+    NS_LOG_V(DEBUG, "Msg Date    : %s", retMsg->dateTime);
+    NS_LOG_V(DEBUG, "Msg ttl     : %lld", (long long int)retMsg->ttl);
+
+    return retMsg;
+}
+
 NSMessage * NSCopyMessage(NSMessage * msg)
 {
     NS_VERIFY_NOT_NULL(msg, NULL);
@@ -318,6 +458,108 @@ void NSRemoveMessage(NSMessage * msg)
     NSOICFree(msg);
 }
 
+void NSGetProviderPostClean(
+        char * pId, char * mUri, char * sUri, char * tUri, NSProviderConnectionInfo * connection)
+{
+    NSOICFree(pId);
+    NSOICFree(mUri);
+    NSOICFree(sUri);
+    NSOICFree(tUri);
+    NSRemoveConnections(connection);
+}
+
+NSProvider_internal * NSGetProvider(OCClientResponse * clientResponse)
+{
+    NS_LOG(DEBUG, "create NSProvider");
+    NS_VERIFY_NOT_NULL(clientResponse->payload, NULL);
+
+    OCRepPayloadPropType accepterType = OCREP_PROP_BOOL;
+
+    OCRepPayload * payload = (OCRepPayload *)clientResponse->payload;
+    OCRepPayloadValue * value = payload->values;
+    while (value)
+    {
+        NS_LOG_V(DEBUG, "Payload Key : %s", value->name);
+        NS_LOG_V(DEBUG, "Payload Type : %d", (int) value->type);
+        if (!strcmp(value->name, NS_ATTRIBUTE_POLICY))
+        {
+            accepterType = value->type;
+        }
+        value = value->next;
+    }
+
+    char * providerId = NULL;
+    char * messageUri = NULL;
+    char * syncUri = NULL;
+    char * topicUri = NULL;
+    bool bAccepter = 0;
+    int64_t iAccepter = 0;
+    NSProviderConnectionInfo * connection = NULL;
+
+    NS_LOG(DEBUG, "get information of accepter");
+    bool getResult = false;
+    if (accepterType == OCREP_PROP_BOOL)
+    {
+        getResult = OCRepPayloadGetPropBool(payload, NS_ATTRIBUTE_POLICY, & bAccepter);
+    }
+    else if (accepterType == OCREP_PROP_INT)
+    {
+        getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_POLICY, & iAccepter);
+    }
+    NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
+
+    NS_LOG(DEBUG, "get provider ID");
+    getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, & providerId);
+    NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
+
+    NS_LOG(DEBUG, "get message URI");
+    getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_MESSAGE, & messageUri);
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(getResult == true ? (void *) 1 : NULL, NULL,
+            NSGetProviderPostClean(providerId, messageUri, syncUri, topicUri, connection));
+
+    NS_LOG(DEBUG, "get sync URI");
+    getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_SYNC, & syncUri);
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(getResult == true ? (void *) 1 : NULL, NULL,
+            NSGetProviderPostClean(providerId, messageUri, syncUri, topicUri, connection));
+
+    NS_LOG(DEBUG, "get topic URI");
+    getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_TOPIC, & topicUri);
+
+    NS_LOG(DEBUG, "get provider connection information");
+    NS_VERIFY_NOT_NULL(clientResponse->addr, NULL);
+    connection = NSCreateProviderConnections(clientResponse->addr);
+    NS_VERIFY_NOT_NULL(connection, NULL);
+
+    NSProvider_internal * newProvider
+        = (NSProvider_internal *)OICMalloc(sizeof(NSProvider_internal));
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newProvider, NULL,
+          NSGetProviderPostClean(providerId, messageUri, syncUri, topicUri, connection));
+
+    OICStrcpy(newProvider->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, providerId);
+    NSOICFree(providerId);
+    newProvider->messageUri = messageUri;
+    newProvider->syncUri = syncUri;
+    newProvider->topicUri = NULL;
+    if (topicUri && strlen(topicUri) > 0)
+    {
+        newProvider->topicUri = topicUri;
+    }
+    if (accepterType == OCREP_PROP_BOOL)
+    {
+        newProvider->accessPolicy = (NSSelector)bAccepter;
+    }
+    else if (accepterType == OCREP_PROP_INT)
+    {
+        newProvider->accessPolicy = (NSSelector)iAccepter;
+    }
+
+    newProvider->connection = connection;
+    newProvider->topicLL = NULL;
+    newProvider->state = NS_DISCOVERED;
+
+    return newProvider;
+}
+
 void NSRemoveConnections(NSProviderConnectionInfo * connections)
 {
     NS_VERIFY_NOT_NULL_V(connections);
@@ -578,19 +820,115 @@ OCStackResult NSInvokeRequest(OCDoHandle * handle,
     return ret;
 }
 
-bool NSOCResultToSuccess(OCStackResult ret)
+bool NSIsExtraValue(const char * name)
+{
+    if (!strcmp(name, NS_ATTRIBUTE_MESSAGE_ID) ||
+        !strcmp(name, NS_ATTRIBUTE_PROVIDER_ID) ||
+        !strcmp(name, NS_ATTRIBUTE_TITLE) ||
+        !strcmp(name, NS_ATTRIBUTE_TEXT) ||
+        !strcmp(name, NS_ATTRIBUTE_SOURCE) ||
+        !strcmp(name, NS_ATTRIBUTE_TOPIC_NAME) ||
+        !strcmp(name, NS_ATTRIBUTE_TYPE) ||
+        !strcmp(name, NS_ATTRIBUTE_DATETIME) ||
+        !strcmp(name, NS_ATTRIBUTE_TTL) ||
+        !strcmp(name, NS_ATTRIBUTE_ICON_IMAGE))
+    {
+        return false;
+    }
+
+    return true;
+}
+
+
+void NSCopyPayloadValueArray(OCRepPayloadValue* dest, OCRepPayloadValue* source)
 {
-    switch (ret)
+    NS_VERIFY_NOT_NULL_V(source);
+
+    size_t dimTotal = calcDimTotal(source->arr.dimensions);
+    switch(source->arr.type)
     {
-        case OC_STACK_OK:
-        case OC_STACK_RESOURCE_CREATED:
-        case OC_STACK_RESOURCE_DELETED:
-        case OC_STACK_PRESENCE_STOPPED:
-        case OC_STACK_CONTINUE:
-        case OC_STACK_RESOURCE_CHANGED:
-            return true;
+        case OCREP_PROP_INT:
+            dest->arr.iArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
+            NS_VERIFY_NOT_NULL_V(dest->arr.iArray);
+            memcpy(dest->arr.iArray, source->arr.iArray, dimTotal * sizeof(int64_t));
+            break;
+        case OCREP_PROP_DOUBLE:
+            dest->arr.dArray = (double*)OICMalloc(dimTotal * sizeof(double));
+            NS_VERIFY_NOT_NULL_V(dest->arr.dArray);
+            memcpy(dest->arr.dArray, source->arr.dArray, dimTotal * sizeof(double));
+            break;
+        case OCREP_PROP_BOOL:
+            dest->arr.bArray = (bool*)OICMalloc(dimTotal * sizeof(bool));
+            NS_VERIFY_NOT_NULL_V(dest->arr.bArray);
+            memcpy(dest->arr.bArray, source->arr.bArray, dimTotal * sizeof(bool));
+            break;
+        case OCREP_PROP_STRING:
+            dest->arr.strArray = (char**)OICMalloc(dimTotal * sizeof(char*));
+            NS_VERIFY_NOT_NULL_V(dest->arr.strArray);
+            for(size_t i = 0; i < dimTotal; ++i)
+            {
+                dest->arr.strArray[i] = OICStrdup(source->arr.strArray[i]);
+            }
+            break;
+        case OCREP_PROP_OBJECT:
+            dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
+            NS_VERIFY_NOT_NULL_V(dest->arr.objArray);
+            for(size_t i = 0; i < dimTotal; ++i)
+            {
+                dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]);
+            }
+            break;
+        case OCREP_PROP_ARRAY:
+            dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
+            NS_VERIFY_NOT_NULL_V(dest->arr.objArray);
+            for(size_t i = 0; i < dimTotal; ++i)
+            {
+                dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]);
+            }
+            break;
+        case OCREP_PROP_BYTE_STRING:
+            dest->arr.ocByteStrArray = (OCByteString*)OICMalloc(dimTotal * sizeof(OCByteString));
+            NS_VERIFY_NOT_NULL_V(dest->arr.ocByteStrArray);
+            for (size_t i = 0; i < dimTotal; ++i)
+            {
+                OCByteStringCopy(&dest->arr.ocByteStrArray[i], &source->arr.ocByteStrArray[i]);
+                NS_VERIFY_NOT_NULL_V(dest->arr.ocByteStrArray[i].bytes);
+            }
+            break;
         default:
-            NS_LOG_V(DEBUG, "OCStackResult : %d", (int)ret);
-            return false;
+            break;
     }
 }
+
+OCRepPayloadValue * NSCopyPayloadValue(OCRepPayloadValue * value)
+{
+    OCRepPayloadValue * retValue = (OCRepPayloadValue *)OICMalloc(sizeof(OCRepPayloadValue));
+    NS_VERIFY_NOT_NULL(retValue, NULL);
+
+    * retValue = * value;
+    retValue->next = NULL;
+    retValue->name = OICStrdup(value->name);
+
+    switch(value->type)
+    {
+        case OCREP_PROP_STRING:
+            retValue->str = OICStrdup(value->str);
+            break;
+        case OCREP_PROP_BYTE_STRING:
+            retValue->ocByteStr.bytes = (uint8_t * )OICMalloc(value->ocByteStr.len * sizeof(uint8_t));
+            NS_VERIFY_NOT_NULL(retValue->ocByteStr.bytes, NULL);
+            retValue->ocByteStr.len = value->ocByteStr.len;
+            memcpy(retValue->ocByteStr.bytes, value->ocByteStr.bytes, retValue->ocByteStr.len);
+            break;
+        case OCREP_PROP_OBJECT:
+            retValue->obj = OCRepPayloadClone(value->obj);
+            break;
+        case OCREP_PROP_ARRAY:
+            NSCopyPayloadValueArray(retValue, value);
+            break;
+        default:
+            break;
+    }
+
+    return retValue;
+}
index 121766d..2100b22 100644 (file)
@@ -33,12 +33,12 @@ extern "C" {
 #include "ocstack.h"
 
 #define NS_QOS OC_HIGH_QOS
-#define NS_RESOURCE_TYPE "oic.wk.notification"
+#define NS_RESOURCE_TYPE "x.org.iotivity.notification"
 #define NS_RESOURCE_URI "/notification"
 #define NS_INTERFACE_BASELINE "oic.if.baseline"
 #define NS_RESOURCE_QUERY "/oic/res"
 
-#define NS_DISCOVER_QUERY "/oic/res?rt=oic.wk.notification"
+#define NS_DISCOVER_QUERY "/oic/res?rt=x.org.iotivity.notification"
 #define NS_DEVICE_ID_LENGTH 37
 
 typedef enum
@@ -114,12 +114,16 @@ void NSSetConsumerId(char * cId);
 char * NSMakeRequestUriWithConsumerId(const char * uri);
 
 NSTask * NSMakeTask(NSTaskType, void *);
-
 NSResult NSConsumerPushEvent(NSTask *);
 
+NSMessage * NSGetMessage(OCRepPayload * payload);
 NSMessage * NSCopyMessage(NSMessage *);
 void NSRemoveMessage(NSMessage *);
 
+void NSGetProviderPostClean(
+        char * pId, char * mUri, char * sUri, char * tUri, NSProviderConnectionInfo * connection);
+
+NSProvider_internal * NSGetProvider(OCClientResponse * clientResponse);
 NSProviderConnectionInfo * NSCreateProviderConnections(OCDevAddr *);
 NSProviderConnectionInfo * NSCopyProviderConnections(NSProviderConnectionInfo *);
 void NSRemoveConnections(NSProviderConnectionInfo *);
index 4d4b62a..3039346 100644 (file)
 
 #define NS_SYNC_URI "/notification/sync"
 
-NSMessage * NSCreateMessage_internal(uint64_t msgId, const char * providerId);
 NSSyncInfo * NSCreateSyncInfo_consumer(uint64_t msgId, const char * providerId, NSSyncType state);
 
-NSMessage * NSGetMessage(OCClientResponse * clientResponse);
 NSSyncInfo * NSGetSyncInfoc(OCClientResponse * clientResponse);
 NSTopicLL * NSGetTopicLL(OCClientResponse * clientResponse);
 
@@ -84,7 +82,7 @@ NSResult NSConsumerSubscribeProvider(NSProvider * provider)
             }
         }
 
-        NS_LOG_V(DEBUG, "subscribe to %s:%d", connections->addr->addr, connections->addr->port);
+        NS_LOG_V(INFO_PRIVATE, "subscribe to %s:%d", connections->addr->addr, connections->addr->port);
 
         NS_LOG(DEBUG, "get subscribe message query");
         char * query = NULL;
@@ -184,7 +182,7 @@ OCStackApplicationResult NSConsumerMessageListener(
     NS_VERIFY_STACK_SUCCESS(NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);
 
     NS_LOG(DEBUG, "build NSMessage");
-    NSMessage * newNoti = NSGetMessage(clientResponse);
+    NSMessage * newNoti = NSGetMessage((OCRepPayload *) clientResponse->payload);
     NS_VERIFY_NOT_NULL(newNoti, OC_STACK_KEEP_TRANSACTION);
 
     NSTaskType type = TASK_CONSUMER_RECV_MESSAGE;
@@ -219,226 +217,6 @@ void NSGetMessagePostClean(char * pId, OCDevAddr * addr)
     NSOICFree(addr);
 }
 
-bool NSIsExtraValue(const char * name)
-{
-    if (!strcmp(name, NS_ATTRIBUTE_MESSAGE_ID) ||
-        !strcmp(name, NS_ATTRIBUTE_PROVIDER_ID) ||
-        !strcmp(name, NS_ATTRIBUTE_TITLE) ||
-        !strcmp(name, NS_ATTRIBUTE_TEXT) ||
-        !strcmp(name, NS_ATTRIBUTE_SOURCE) ||
-        !strcmp(name, NS_ATTRIBUTE_TOPIC_NAME) ||
-        !strcmp(name, NS_ATTRIBUTE_TYPE) ||
-        !strcmp(name, NS_ATTRIBUTE_DATETIME) ||
-        !strcmp(name, NS_ATTRIBUTE_TTL) ||
-        !strcmp(name, NS_ATTRIBUTE_ICON_IMAGE))
-    {
-        return false;
-    }
-
-    return true;
-}
-
-void NSCopyPayloadValueArray(OCRepPayloadValue* dest, OCRepPayloadValue* source)
-{
-    NS_VERIFY_NOT_NULL_V(source);
-
-    size_t dimTotal = calcDimTotal(source->arr.dimensions);
-    switch(source->arr.type)
-    {
-        case OCREP_PROP_INT:
-            dest->arr.iArray = (int64_t*)OICMalloc(dimTotal * sizeof(int64_t));
-            NS_VERIFY_NOT_NULL_V(dest->arr.iArray);
-            memcpy(dest->arr.iArray, source->arr.iArray, dimTotal * sizeof(int64_t));
-            break;
-        case OCREP_PROP_DOUBLE:
-            dest->arr.dArray = (double*)OICMalloc(dimTotal * sizeof(double));
-            NS_VERIFY_NOT_NULL_V(dest->arr.dArray);
-            memcpy(dest->arr.dArray, source->arr.dArray, dimTotal * sizeof(double));
-            break;
-        case OCREP_PROP_BOOL:
-            dest->arr.bArray = (bool*)OICMalloc(dimTotal * sizeof(bool));
-            NS_VERIFY_NOT_NULL_V(dest->arr.bArray);
-            memcpy(dest->arr.bArray, source->arr.bArray, dimTotal * sizeof(bool));
-            break;
-        case OCREP_PROP_STRING:
-            dest->arr.strArray = (char**)OICMalloc(dimTotal * sizeof(char*));
-            NS_VERIFY_NOT_NULL_V(dest->arr.strArray);
-            for(size_t i = 0; i < dimTotal; ++i)
-            {
-                dest->arr.strArray[i] = OICStrdup(source->arr.strArray[i]);
-            }
-            break;
-        case OCREP_PROP_OBJECT:
-            dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
-            NS_VERIFY_NOT_NULL_V(dest->arr.objArray);
-            for(size_t i = 0; i < dimTotal; ++i)
-            {
-                dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]);
-            }
-            break;
-        case OCREP_PROP_ARRAY:
-            dest->arr.objArray = (OCRepPayload**)OICMalloc(dimTotal * sizeof(OCRepPayload*));
-            NS_VERIFY_NOT_NULL_V(dest->arr.objArray);
-            for(size_t i = 0; i < dimTotal; ++i)
-            {
-                dest->arr.objArray[i] = OCRepPayloadClone(source->arr.objArray[i]);
-            }
-            break;
-        case OCREP_PROP_BYTE_STRING:
-            dest->arr.ocByteStrArray = (OCByteString*)OICMalloc(dimTotal * sizeof(OCByteString));
-            NS_VERIFY_NOT_NULL_V(dest->arr.ocByteStrArray);
-            for (size_t i = 0; i < dimTotal; ++i)
-            {
-                OCByteStringCopy(&dest->arr.ocByteStrArray[i], &source->arr.ocByteStrArray[i]);
-                NS_VERIFY_NOT_NULL_V(dest->arr.ocByteStrArray[i].bytes);
-            }
-            break;
-        default:
-            break;
-    }
-}
-
-OCRepPayloadValue * NSCopyPayloadValue(OCRepPayloadValue * value)
-{
-    OCRepPayloadValue * retValue = (OCRepPayloadValue *)OICMalloc(sizeof(OCRepPayloadValue));
-    NS_VERIFY_NOT_NULL(retValue, NULL);
-
-    * retValue = * value;
-    retValue->next = NULL;
-    retValue->name = OICStrdup(value->name);
-
-    switch(value->type)
-    {
-        case OCREP_PROP_STRING:
-            retValue->str = OICStrdup(value->str);
-            break;
-        case OCREP_PROP_BYTE_STRING:
-            retValue->ocByteStr.bytes = (uint8_t * )OICMalloc(value->ocByteStr.len * sizeof(uint8_t));
-            NS_VERIFY_NOT_NULL(retValue->ocByteStr.bytes, NULL);
-            retValue->ocByteStr.len = value->ocByteStr.len;
-            memcpy(retValue->ocByteStr.bytes, value->ocByteStr.bytes, retValue->ocByteStr.len);
-            break;
-        case OCREP_PROP_OBJECT:
-            retValue->obj = OCRepPayloadClone(value->obj);
-            break;
-        case OCREP_PROP_ARRAY:
-            NSCopyPayloadValueArray(retValue, value);
-            break;
-        default:
-            break;
-    }
-
-    return retValue;
-}
-
-OCRepPayload * NSGetExtraInfo(OCRepPayload * payload)
-{
-    NS_LOG(DEBUG, "get extra info");
-    OCRepPayload * extraInfo = OCRepPayloadCreate();
-    NS_VERIFY_NOT_NULL(extraInfo, NULL);
-    OCRepPayload * origin = OCRepPayloadClone(payload);
-
-    bool isFirstExtra = true;
-    OCRepPayloadValue * headValue = NULL;
-    OCRepPayloadValue * curValue = NULL;
-    OCRepPayloadValue * value = origin->values;
-    while(value)
-    {
-        if (NSIsExtraValue(value->name))
-        {
-            curValue = NSCopyPayloadValue(value);
-            NS_LOG_V(DEBUG, " key : %s", curValue->name);
-            if (isFirstExtra)
-            {
-                headValue = curValue;
-                extraInfo->values = headValue;
-                isFirstExtra = false;
-            }
-            else
-            {
-                headValue->next = curValue;
-                headValue = curValue;
-            }
-            curValue = NULL;
-        }
-        value = value->next;
-    }
-    OCRepPayloadDestroy(origin);
-
-
-    if (!isFirstExtra && extraInfo->values)
-    {
-        return extraInfo;
-    }
-    else
-    {
-        OCRepPayloadDestroy(extraInfo);
-        return NULL;
-    }
-}
-
-NSMessage * NSGetMessage(OCClientResponse * clientResponse)
-{
-    NS_VERIFY_NOT_NULL(clientResponse->payload, NULL);
-    OCRepPayload * payload = (OCRepPayload *)clientResponse->payload;
-
-    NS_LOG(DEBUG, "get msg id");
-    uint64_t id = NULL;
-    bool getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, (int64_t *)&id);
-    NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
-
-    NS_LOG(DEBUG, "get provider id");
-    char * pId = NULL;
-    getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, &pId);
-    NS_LOG_V (DEBUG, "provider id: %s", pId);
-    NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
-
-    NS_LOG(DEBUG, "create NSMessage");
-    NSMessage * retMsg = NSCreateMessage_internal(id, pId);
-    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(retMsg, NULL, NSOICFree(pId));
-    NSOICFree(pId);
-
-    NS_LOG(DEBUG, "get msg optional field");
-    OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_TITLE, &retMsg->title);
-    OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_TEXT, &retMsg->contentText);
-    OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_SOURCE, &retMsg->sourceName);
-    OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_TOPIC_NAME, &retMsg->topic);
-
-    OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_TYPE, (int64_t *)&retMsg->type);
-    OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_DATETIME, &retMsg->dateTime);
-    OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_TTL, (int64_t *)&retMsg->ttl);
-
-    char * icon = NULL;
-    OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_ICON_IMAGE, &icon);
-
-    if (icon && strlen(icon))
-    {
-        NSMediaContents * contents = (NSMediaContents *)OICMalloc(sizeof(NSMediaContents));
-        if (contents)
-        {
-            contents->iconImage = icon;
-            retMsg->mediaContents = contents;
-        }
-        else
-        {
-            NSOICFree(icon);
-        }
-    }
-
-    retMsg->extraInfo = NSGetExtraInfo(payload);
-
-    NS_LOG_V(DEBUG, "Msg ID      : %lld", (long long int)retMsg->messageId);
-    NS_LOG_V(DEBUG, "Msg Title   : %s", retMsg->title);
-    NS_LOG_V(DEBUG, "Msg Content : %s", retMsg->contentText);
-    NS_LOG_V(DEBUG, "Msg Source  : %s", retMsg->sourceName);
-    NS_LOG_V(DEBUG, "Msg Topic   : %s", retMsg->topic);
-    NS_LOG_V(DEBUG, "Msg Type    : %d", retMsg->type);
-    NS_LOG_V(DEBUG, "Msg Date    : %s", retMsg->dateTime);
-    NS_LOG_V(DEBUG, "Msg ttl     : %lld", (long long int)retMsg->ttl);
-
-    return retMsg;
-}
-
 NSSyncInfo * NSGetSyncInfoc(OCClientResponse * clientResponse)
 {
     NS_VERIFY_NOT_NULL(clientResponse->payload, NULL);
@@ -446,7 +224,7 @@ NSSyncInfo * NSGetSyncInfoc(OCClientResponse * clientResponse)
     OCRepPayload * payload = (OCRepPayload *)clientResponse->payload;
 
     NS_LOG(DEBUG, "get msg id");
-    uint64_t id = NULL;
+    uint64_t id = 0;
     bool getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, (int64_t *)&id);
     NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
 
@@ -468,31 +246,11 @@ NSSyncInfo * NSGetSyncInfoc(OCClientResponse * clientResponse)
 
     NS_LOG_V(DEBUG, "Sync ID : %lld", (long long int)retSync->messageId);
     NS_LOG_V(DEBUG, "Sync State : %d", (int) retSync->state);
-    NS_LOG_V(DEBUG, "Sync Provider ID : %s", retSync->providerId);
+    NS_LOG_V(INFO_PRIVATE, "Sync Provider ID : %s", retSync->providerId);
 
     return retSync;
 }
 
-NSMessage * NSCreateMessage_internal(uint64_t id, const char * providerId)
-{
-    NSMessage * retMsg = (NSMessage *)OICMalloc(sizeof(NSMessage));
-    NS_VERIFY_NOT_NULL(retMsg, NULL);
-
-    retMsg->messageId = id;
-    OICStrcpy(retMsg->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, providerId);
-    retMsg->title = NULL;
-    retMsg->contentText = NULL;
-    retMsg->sourceName = NULL;
-    retMsg->topic = NULL;
-    retMsg->type = NS_MESSAGE_INFO;
-    retMsg->dateTime = NULL;
-    retMsg->ttl = 0;
-    retMsg->mediaContents = NULL;
-    retMsg->extraInfo = NULL;
-
-    return retMsg;
-}
-
 NSSyncInfo * NSCreateSyncInfo_consumer(uint64_t msgId, const char * providerId, NSSyncType state)
 {
     NS_VERIFY_NOT_NULL(providerId, NULL);
@@ -540,11 +298,11 @@ OCStackResult NSSendSyncInfo(NSSyncInfo * syncInfo, OCDevAddr * addr)
 
 char * NSGetCloudUri(const char * providerId, char * uri)
 {
-    size_t uriLen = NS_DEVICE_ID_LENGTH + 1 + strlen(uri) + 1 + 3;
+    size_t uriLen = NS_DEVICE_ID_LENGTH + 1 + strlen(uri) + 1 + 10;
     char * retUri = (char *)OICMalloc(uriLen);
     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(retUri, NULL, NSOICFree(uri));
 
-    snprintf(retUri, uriLen, "/di/%s%s", providerId, uri);
+    snprintf(retUri, uriLen, "/oic/route/%s%s", providerId, uri);
     NSOICFree(uri);
     NS_LOG_V(DEBUG, "Cloud uri : %s", retUri);
 
@@ -598,12 +356,12 @@ void NSConsumerCommunicationTaskProcessing(NSTask * task)
         {
             if (connections->isSubscribing == false)
             {
-                NS_LOG_V(DEBUG, "unsubscribed to %s:%d",
+                NS_LOG_V(INFO_PRIVATE, "unsubscribed to %s:%d",
                      connections->addr->addr, connections->addr->port);
                 connections = connections->next;
                 continue;
             }
-            NS_LOG_V(DEBUG, "cancel subscribe to %s:%d",
+            NS_LOG_V(INFO_PRIVATE, "cancel subscribe to %s:%d",
                      connections->addr->addr, connections->addr->port);
             OCCancel(connections->messageHandle, NS_QOS, NULL, 0);
             OCCancel(connections->syncHandle, NS_QOS, NULL, 0);
@@ -705,7 +463,7 @@ void NSConsumerCommunicationTaskProcessing(NSTask * task)
         }
 
         OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_CONSUMER_ID, *NSGetConsumerId());
-        NS_LOG_V(DEBUG, "NS_ATTRIBUTE_CONSUMER_ID: %s", *NSGetConsumerId());
+        NS_LOG_V(INFO_PRIVATE, "NS_ATTRIBUTE_CONSUMER_ID: %s", *NSGetConsumerId());
 
         iter = topicLL;
         int iterSize = 0;
@@ -885,7 +643,7 @@ OCStackApplicationResult NSIntrospectTopic(
     NS_VERIFY_STACK_SUCCESS(NSOCResultToSuccess(clientResponse->result),
                             OC_STACK_KEEP_TRANSACTION)
 
-    NS_LOG_V(DEBUG, "GET response income : %s:%d",
+    NS_LOG_V(INFO_PRIVATE, "GET response income : %s:%d",
             clientResponse->devAddr.addr, clientResponse->devAddr.port);
     NS_LOG_V(DEBUG, "GET response result : %d",
             clientResponse->result);
index 86ce82d..28c137e 100644 (file)
 
 #include <string.h>
 #include "NSCommon.h"
+#include "NSUtil.h"
 #include "NSConsumerCommon.h"
 #include "NSConstants.h"
 #include "ocpayload.h"
 #include "oic_malloc.h"
 #include "oic_string.h"
 
-#define NS_DISCOVER_QUERY "/oic/res?rt=oic.wk.notification"
-#define NS_PRESENCE_SUBSCRIBE_QUERY_TCP "/oic/ad?rt=oic.wk.notification"
-
-NSProvider_internal * NSGetProvider(OCClientResponse * clientResponse);
-
-OCDevAddr * NSChangeAddress(const char * address);
+#define NS_DISCOVER_QUERY "/oic/res?rt=x.org.iotivity.notification"
+#define NS_PRESENCE_SUBSCRIBE_QUERY_TCP "/oic/ad?rt=x.org.iotivity.notification"
 
 OCStackApplicationResult NSConsumerPresenceListener(
         void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
@@ -46,7 +43,7 @@ OCStackApplicationResult NSConsumerPresenceListener(
     NS_VERIFY_STACK_SUCCESS(
             NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);
 
-    NS_LOG_V(DEBUG, "Presence income : %s:%d",
+    NS_LOG_V(INFO_PRIVATE, "Presence income : %s:%d",
             clientResponse->devAddr.addr, clientResponse->devAddr.port);
     NS_LOG_V(DEBUG, "Presence result : %d",
             clientResponse->result);
@@ -96,7 +93,7 @@ OCStackApplicationResult NSProviderDiscoverListener(
     NS_VERIFY_NOT_NULL(clientResponse->payload, OC_STACK_KEEP_TRANSACTION);
     NS_VERIFY_STACK_SUCCESS(NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);
 
-    NS_LOG_V(DEBUG, "Discover income : %s:%d",
+    NS_LOG_V(INFO_PRIVATE, "Discover income : %s:%d",
             clientResponse->devAddr.addr, clientResponse->devAddr.port);
     NS_LOG_V(DEBUG, "Discover result : %d",
             clientResponse->result);
@@ -110,32 +107,38 @@ OCStackApplicationResult NSProviderDiscoverListener(
         return OC_STACK_DELETE_TRANSACTION;
     }
 
-    OCResourcePayload * resource = ((OCDiscoveryPayload *)clientResponse->payload)->resources;
-    NS_LOG_V(DEBUG, "Discovered resource uri : %s",
-                        resource->uri);
-    while (resource)
+    OCDiscoveryPayload * discoveryPayload = (OCDiscoveryPayload *)clientResponse->payload;
+
+    while (discoveryPayload)
     {
-        NS_VERIFY_NOT_NULL(resource->uri, OC_STACK_KEEP_TRANSACTION);
-        if (strstr(resource->uri, NS_RESOURCE_URI))
+        OCResourcePayload * resource = discoveryPayload->resources;
+        while (resource)
         {
-            OCConnectivityType type = CT_DEFAULT;
-            if (clientResponse->addr->adapter == OC_ADAPTER_TCP)
+            NS_LOG_V(DEBUG, "Discovered resource uri : %s", resource->uri);
+            NS_VERIFY_NOT_NULL(resource->uri, OC_STACK_KEEP_TRANSACTION);
+            if (strstr(resource->uri, NS_RESOURCE_URI))
             {
-                type = CT_ADAPTER_TCP;
+                NS_LOG_V(DEBUG, "Request GET to provider : %s", resource->uri);
+                OCConnectivityType type = CT_DEFAULT;
+                if (clientResponse->addr->adapter == OC_ADAPTER_TCP)
+                {
+                    type = CT_ADAPTER_TCP;
+                }
+
+                OCDevAddr * addr = clientResponse->addr;
+                if (resource->secure)
+                {
+                    addr->port = resource->port;
+                    addr->flags |= OC_FLAG_SECURE;
+                }
+
+                NSInvokeRequest(NULL, OC_REST_GET, addr,
+                        resource->uri, NULL, NSIntrospectProvider, ctx,
+                        NULL, type);
             }
-
-            OCDevAddr * addr = clientResponse->addr;
-            if (resource->secure)
-            {
-                addr->port = resource->port;
-                addr->flags |= OC_FLAG_SECURE;
-            }
-
-            NSInvokeRequest(NULL, OC_REST_GET, addr,
-                    resource->uri, NULL, NSIntrospectProvider, ctx,
-                    NULL, type);
+            resource = resource->next;
         }
-        resource = resource->next;
+        discoveryPayload = discoveryPayload->next;
     }
 
     return OC_STACK_KEEP_TRANSACTION;
@@ -149,7 +152,7 @@ OCStackApplicationResult NSIntrospectProvider(
     NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
     NS_VERIFY_STACK_SUCCESS(NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);
 
-    NS_LOG_V(DEBUG, "GET response income : %s:%d",
+    NS_LOG_V(INFO_PRIVATE, "GET response income : %s:%d",
             clientResponse->devAddr.addr, clientResponse->devAddr.port);
     NS_LOG_V(DEBUG, "GET response result : %d",
             clientResponse->result);
@@ -181,154 +184,6 @@ OCStackApplicationResult NSIntrospectProvider(
     return OC_STACK_KEEP_TRANSACTION;
 }
 
-void NSGetProviderPostClean(
-        char * pId, char * mUri, char * sUri, char * tUri, NSProviderConnectionInfo * connection)
-{
-    NSOICFree(pId);
-    NSOICFree(mUri);
-    NSOICFree(sUri);
-    NSOICFree(tUri);
-    NSRemoveConnections(connection);
-}
-
-NSProvider_internal * NSGetProvider(OCClientResponse * clientResponse)
-{
-    NS_LOG(DEBUG, "create NSProvider");
-    NS_VERIFY_NOT_NULL(clientResponse->payload, NULL);
-
-    OCRepPayloadPropType accepterType = OCREP_PROP_BOOL;
-
-    OCRepPayload * payload = (OCRepPayload *)clientResponse->payload;
-    OCRepPayloadValue * value = payload->values;
-    while (value)
-    {
-        NS_LOG_V(DEBUG, "Payload Key : %s", value->name);
-        NS_LOG_V(DEBUG, "Payload Type : %d", (int) value->type);
-        if (!strcmp(value->name, NS_ATTRIBUTE_POLICY))
-        {
-            accepterType = value->type;
-        }
-        value = value->next;
-    }
-
-    char * providerId = NULL;
-    char * messageUri = NULL;
-    char * syncUri = NULL;
-    char * topicUri = NULL;
-    bool bAccepter = 0;
-    int64_t iAccepter = 0;
-    NSProviderConnectionInfo * connection = NULL;
-
-    NS_LOG(DEBUG, "get information of accepter");
-    bool getResult = false;
-    if (accepterType == OCREP_PROP_BOOL)
-    {
-        getResult = OCRepPayloadGetPropBool(payload, NS_ATTRIBUTE_POLICY, & bAccepter);
-    }
-    else if (accepterType == OCREP_PROP_INT)
-    {
-        getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_POLICY, & iAccepter);
-    }
-    NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
-
-    NS_LOG(DEBUG, "get provider ID");
-    getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, & providerId);
-    NS_VERIFY_NOT_NULL(getResult == true ? (void *) 1 : NULL, NULL);
-
-    NS_LOG(DEBUG, "get message URI");
-    getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_MESSAGE, & messageUri);
-    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(getResult == true ? (void *) 1 : NULL, NULL,
-            NSGetProviderPostClean(providerId, messageUri, syncUri, topicUri, connection));
-
-    NS_LOG(DEBUG, "get sync URI");
-    getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_SYNC, & syncUri);
-    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(getResult == true ? (void *) 1 : NULL, NULL,
-            NSGetProviderPostClean(providerId, messageUri, syncUri, topicUri, connection));
-
-    NS_LOG(DEBUG, "get topic URI");
-    getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_TOPIC, & topicUri);
-
-    NS_LOG(DEBUG, "get provider connection information");
-    NS_VERIFY_NOT_NULL(clientResponse->addr, NULL);
-    connection = NSCreateProviderConnections(clientResponse->addr);
-    NS_VERIFY_NOT_NULL(connection, NULL);
-
-    NSProvider_internal * newProvider
-        = (NSProvider_internal *)OICMalloc(sizeof(NSProvider_internal));
-    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(newProvider, NULL,
-          NSGetProviderPostClean(providerId, messageUri, syncUri, topicUri, connection));
-
-    OICStrcpy(newProvider->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, providerId);
-    NSOICFree(providerId);
-    newProvider->messageUri = messageUri;
-    newProvider->syncUri = syncUri;
-    newProvider->topicUri = NULL;
-    if (topicUri && strlen(topicUri) > 0)
-    {
-        newProvider->topicUri = topicUri;
-    }
-    if (accepterType == OCREP_PROP_BOOL)
-    {
-        newProvider->accessPolicy = (NSSelector)bAccepter;
-    }
-    else if (accepterType == OCREP_PROP_INT)
-    {
-        newProvider->accessPolicy = (NSSelector)iAccepter;
-    }
-
-    newProvider->connection = connection;
-    newProvider->topicLL = NULL;
-    newProvider->state = NS_DISCOVERED;
-
-    return newProvider;
-}
-
-OCDevAddr * NSChangeAddress(const char * address)
-{
-    NS_VERIFY_NOT_NULL(address, NULL);
-    OCDevAddr * retAddr = NULL;
-
-    int index = 0;
-    while(address[index] != '\0')
-    {
-        if (address[index] == ':')
-        {
-            break;
-        }
-        index++;
-    }
-
-    if (address[index] == '\0')
-    {
-        return NULL;
-    }
-
-    int tmp = index + 1;
-    uint16_t port = address[tmp++] - '0';
-
-    while(address[tmp] != '\0')
-    {
-        port *= 10;
-        port += address[tmp++] - '0';
-    }
-
-    retAddr = (OCDevAddr *) OICMalloc(sizeof(OCDevAddr));
-    NS_VERIFY_NOT_NULL(retAddr, NULL);
-
-    retAddr->adapter = OC_ADAPTER_TCP;
-    OICStrcpy(retAddr->addr, index + 1, address);
-    retAddr->addr[index] = '\0';
-    retAddr->port = port;
-    retAddr->flags = OC_IP_USE_V6;
-
-    NS_LOG(DEBUG, "Change Address for TCP request");
-    NS_LOG_V(DEBUG, "Origin : %s", address);
-    NS_LOG_V(DEBUG, "Changed Addr : %s", retAddr->addr);
-    NS_LOG_V(DEBUG, "Changed Port : %d", retAddr->port);
-
-    return retAddr;
-}
-
 void NSConsumerHandleRequestDiscover(OCDevAddr * address, NSConsumerDiscoverType rType)
 {
     OCConnectivityType type = CT_ADAPTER_IP;
@@ -355,7 +210,7 @@ void NSConsumerHandleRequestDiscover(OCDevAddr * address, NSConsumerDiscoverType
         }
         else
         {
-            NS_LOG_V(DEBUG, "Request discover But Adapter is not IP : %d", address->adapter);
+            NS_LOG_V(INFO_PRIVATE, "Request discover But Adapter is not IP : %d", address->adapter);
         }
     }
     else
index db95e81..f52b20d 100644 (file)
@@ -27,6 +27,7 @@
 #include "NSConsumerCommon.h"
 #include "NSConstants.h"
 #include "NSConsumerScheduler.h"
+#include "NSUtil.h"
 #include "oic_malloc.h"
 #include "oic_string.h"
 
@@ -67,25 +68,42 @@ NSResult NSStopConsumer()
     return NS_OK;
 }
 
-NSResult NSConsumerEnableRemoteService(const char *serverAddress)
+#ifdef WITH_MQ
+NSResult NSConsumerSubscribeMQService(const char * serverAddress, const char * topicName)
 {
     NS_VERIFY_NOT_NULL(serverAddress, NS_ERROR);
+    NS_VERIFY_NOT_NULL(topicName, NS_ERROR);
     bool isStartedConsumer = NSIsStartedConsumer();
     NS_VERIFY_NOT_NULL(isStartedConsumer == true ? (void *) 1 : NULL, NS_ERROR);
 
-    char * queryAddr = NULL;
-    if (strstr(serverAddress, "coap+tcp://"))
-    {
-        queryAddr = OICStrdup(serverAddress+11);
-    }
-    else if (strstr(serverAddress, "coap://"))
-    {
-        queryAddr = OICStrdup(serverAddress+7);
-    }
-    else
-    {
-        queryAddr = OICStrdup(serverAddress);
-    }
+    char * queryAddr = NSGetQueryAddress(serverAddress);
+    NS_VERIFY_NOT_NULL(queryAddr, NS_ERROR);
+
+    NSMQTopicAddress * topicAddr = (NSMQTopicAddress *)OICMalloc(sizeof(NSMQTopicAddress));
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(queryAddr, NS_ERROR, NSOICFree(queryAddr));
+
+    topicAddr->serverAddr = queryAddr;
+    topicAddr->topicName = OICStrdup(topicName);
+
+    NSTask * subMQTask = NSMakeTask(TASK_MQ_REQ_SUBSCRIBE, (void *)topicAddr);
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(subMQTask, NS_ERROR,
+                  {
+                      NSOICFree(topicAddr->serverAddr);
+                      NSOICFree(topicAddr->topicName)
+                      NSOICFree(topicAddr);
+                  });
+
+    return NSConsumerPushEvent(subMQTask);
+}
+#endif
+
+NSResult NSConsumerEnableRemoteService(const char * serverAddress)
+{
+    NS_VERIFY_NOT_NULL(serverAddress, NS_ERROR);
+    bool isStartedConsumer = NSIsStartedConsumer();
+    NS_VERIFY_NOT_NULL(isStartedConsumer == true ? (void *) 1 : NULL, NS_ERROR);
+
+    char * queryAddr = OICStrdup(serverAddress);
     NS_VERIFY_NOT_NULL(queryAddr, NS_ERROR);
 
     NSTask * discoverTask = NSMakeTask(TASK_CONSUMER_REQ_DISCOVER, (void *)queryAddr);
@@ -186,7 +204,7 @@ NSTopicLL * NSConsumerGetTopicList(const char * providerId)
     bool isStartedConsumer = NSIsStartedConsumer();
     NS_VERIFY_NOT_NULL(isStartedConsumer == true ? (void *) 1 : NULL, NULL);
 
-    NS_LOG_V(DEBUG, "NSProvider ID: %s", providerId);
+    NS_LOG_V(INFO_PRIVATE, "NSProvider ID: %s", providerId);
     NSProvider_internal * prov_internal = NSConsumerFindNSProvider(providerId);
     NS_VERIFY_NOT_NULL(prov_internal, NULL);
 
index 3156979..40a4192 100644 (file)
@@ -235,7 +235,7 @@ void NSConsumerHandleProviderDiscovered(NSProvider_internal * provider)
             isSubscribing |= infos->isSubscribing;
             if (infos->addr->adapter == newAdapter && infos->isSubscribing == true)
             {
-                NS_LOG_V(DEBUG, "This provider already discovered : %s:%d",
+                NS_LOG_V(INFO_PRIVATE, "This provider already discovered : %s:%d",
                          infos->addr->addr, infos->addr->port);
                 NS_LOG_V(DEBUG, "Subscription : %d", infos->isSubscribing);
                 return;
@@ -289,7 +289,7 @@ void NSConsumerHandleProviderDeleted(NSProvider_internal * provider)
     NSResult ret = NSConsumerStorageDelete(providerCache, provider->providerId);
     NS_VERIFY_NOT_NULL_V(ret == NS_OK ? (void *)1 : NULL);
 
-    NS_LOG_V(DEBUG, "Stopped Provider : %s", provider->providerId);
+    NS_LOG_V(INFO_PRIVATE, "Stopped Provider : %s", provider->providerId);
     NSProvider * prov = NSCopyProvider(provider);
     NSProviderChanged(prov, NS_STOPPED);
     NSRemoveProvider(prov);
@@ -323,7 +323,7 @@ void NSConsumerHandleRecvProviderChanged(NSMessage * msg)
 {
     NS_VERIFY_NOT_NULL_V(msg);
 
-    NS_LOG_V(DEBUG, "confirmed by : %s", msg->providerId);
+    NS_LOG_V(INFO_PRIVATE, "confirmed by : %s", msg->providerId);
 
     NSCacheList * ProviderCache = *(NSGetProviderCacheList());
 
diff --git a/service/notification/src/consumer/NSConsumerMQPlugin.c b/service/notification/src/consumer/NSConsumerMQPlugin.c
new file mode 100644 (file)
index 0000000..b59fc46
--- /dev/null
@@ -0,0 +1,207 @@
+//******************************************************************
+//
+// Copyright 2016 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifdef WITH_MQ
+#include "NSConstants.h"
+#include "NSConsumerCommon.h"
+#include "NSConsumerMQPlugin.h"
+#include "NSUtil.h"
+
+#include "oic_malloc.h"
+#include "oic_string.h"
+#include "ocpayload.h"
+
+void NSHandleMQSubscription(NSMQTopicAddress * address);
+
+OCStackApplicationResult NSConsumerIntrospectMQTopic(
+        void * ctx, OCDoHandle handle, OCClientResponse * clientResponse);
+
+OCStackApplicationResult NSConsumerMQListener(
+        void * ctx, OCDoHandle handle, OCClientResponse * clientResponse);
+
+void NSConsumerMQTaskProcessing(NSTask * task)
+{
+    NS_VERIFY_NOT_NULL_V(task);
+
+    NS_LOG_V(DEBUG, "Receive Event : %d", (int) task->taskType);
+
+    switch (task->taskType)
+    {
+        case TASK_MQ_REQ_SUBSCRIBE:
+        {
+            NSMQTopicAddress * mqTopic = task->taskData;
+            NSHandleMQSubscription(mqTopic);
+            NSOICFree(mqTopic);
+            break;
+        }
+        default:
+        {
+            NS_LOG(ERROR, "Unknown type of task");
+            break;
+        }
+    }
+
+    NSOICFree(task);
+}
+
+void NSHandleMQSubscription(NSMQTopicAddress * topicAddr)
+{
+    char * serverUri = topicAddr->serverAddr;
+    char * topicName = topicAddr->topicName;
+
+    OCDevAddr * addr = NSChangeAddress(serverUri);
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(addr,
+                    {
+                        NSOICFree(topicAddr->serverAddr);
+                        NSOICFree(topicAddr->topicName);
+                    });
+
+    char requestUri[100] = "coap+tcp://";
+    OICStrcat(requestUri, strlen(requestUri)+strlen(serverUri)+1, serverUri);
+    OICStrcat(requestUri, strlen(requestUri)+ strlen("/oic/ps") + 1, "/oic/ps");
+    NS_LOG_V(DEBUG, "requestUri = %s", requestUri);
+
+    OCStackResult ret = NSInvokeRequest(NULL, OC_REST_GET, addr, requestUri, NULL,
+                      NSConsumerIntrospectMQTopic, topicName, OICFree, CT_DEFAULT);
+    NS_VERIFY_NOT_NULL_WITH_POST_CLEANING_V(NSOCResultToSuccess(ret) == true ? (void *)1 : NULL,
+                   {
+                       NSOICFree(serverUri);
+                       NSOICFree(topicName);
+                   });
+
+    NSOICFree(serverUri);
+}
+
+OCStackApplicationResult NSConsumerIntrospectMQTopic(
+        void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
+{
+    (void) handle;
+
+    if (!NSIsStartedConsumer())
+    {
+        return OC_STACK_DELETE_TRANSACTION;
+    }
+
+    NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
+    NS_VERIFY_STACK_SUCCESS(NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);
+    NS_VERIFY_NOT_NULL(clientResponse->payload, OC_STACK_KEEP_TRANSACTION);
+
+    NS_LOG(DEBUG, "income get response of MQ broker");
+    NS_LOG_V(INFO_PRIVATE, "MQ GET response income : %s:%d",
+            clientResponse->devAddr.addr, clientResponse->devAddr.port);
+    NS_LOG_V(DEBUG, "MQ GET response result : %d",
+            clientResponse->result);
+    NS_LOG_V(DEBUG, "MQ GET response sequenceNum : %d",
+            clientResponse->sequenceNumber);
+    NS_LOG_V(DEBUG, "MQ GET response resource uri : %s",
+            clientResponse->resourceUri);
+    NS_LOG_V(DEBUG, "MQ GET response Transport Type : %d",
+                    clientResponse->devAddr.adapter);
+
+    char ** topicList = NULL;
+    size_t dimensions[MAX_REP_ARRAY_DEPTH] = {0};
+    OCRepPayloadGetStringArray((OCRepPayload *) clientResponse->payload,
+                               NS_ATTIRBUTE_MQ_TOPICLIST, & topicList, dimensions);
+
+    char * interestTopicName = (char *) ctx;
+    for (size_t i = 0; i < dimensions[0]; ++i)
+    {
+        NS_LOG_V(DEBUG, "found MQ topic : %s", topicList[i]);
+        if (!strcmp(topicList[i], interestTopicName))
+        {
+            NS_LOG(DEBUG, "subscribe to MQ notification");
+
+            OCStackResult ret = NSInvokeRequest(NULL,
+                                  OC_REST_OBSERVE, clientResponse->addr, topicList[i], NULL,
+                                  NSConsumerMQListener, NULL, NULL, CT_DEFAULT);
+
+            if (!NSOCResultToSuccess(ret))
+            {
+                NS_LOG(DEBUG, "fail to subscribe to MQ notification");
+                continue;
+            }
+        }
+    }
+
+
+    return OC_STACK_KEEP_TRANSACTION;
+}
+
+OCStackApplicationResult NSConsumerMQListener(
+        void * ctx, OCDoHandle handle, OCClientResponse * clientResponse)
+{
+    (void) ctx;
+    (void) handle;
+
+    if (!NSIsStartedConsumer())
+    {
+        return OC_STACK_DELETE_TRANSACTION;
+    }
+
+    NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);
+    NS_VERIFY_STACK_SUCCESS(NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);
+    NS_VERIFY_NOT_NULL(clientResponse->payload, OC_STACK_KEEP_TRANSACTION);
+
+    NS_LOG(DEBUG, "income observe response of MQ notification");
+    NS_LOG_V(INFO_PRIVATE, "MQ OBS response income : %s:%d",
+            clientResponse->devAddr.addr, clientResponse->devAddr.port);
+    NS_LOG_V(DEBUG, "MQ OBS response result : %d",
+            clientResponse->result);
+    NS_LOG_V(DEBUG, "MQ OBS response sequenceNum : %d",
+            clientResponse->sequenceNumber);
+    NS_LOG_V(DEBUG, "MQ OBS response resource uri : %s",
+            clientResponse->resourceUri);
+    NS_LOG_V(DEBUG, "MQ OBS response Transport Type : %d",
+                    clientResponse->devAddr.adapter);
+
+    NSMessage * newMsg = NSGetMessage((OCRepPayload *)clientResponse->payload);
+    NS_VERIFY_NOT_NULL(newMsg, OC_STACK_KEEP_TRANSACTION);
+
+    NSTask * task = NULL;
+
+    if (newMsg->type == NS_MESSAGE_READ || newMsg->type == NS_MESSAGE_DELETED)
+    {
+        NSSyncInfo * syncInfo = (NSSyncInfo *)OICMalloc(sizeof(NSSyncInfo));
+        NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(syncInfo,
+                              OC_STACK_KEEP_TRANSACTION, NSRemoveMessage(newMsg));
+
+        syncInfo->messageId = newMsg->messageId;
+        syncInfo->state = (newMsg->type == NS_MESSAGE_READ) ? NS_SYNC_READ : NS_SYNC_DELETED;
+        OICStrcpy(syncInfo->providerId, sizeof(char) * NS_DEVICE_ID_LENGTH, newMsg->providerId);
+
+        NSRemoveMessage(newMsg);
+
+        NS_LOG(DEBUG, "build NSTask for MQ message sync");
+        task = NSMakeTask(TASK_RECV_SYNCINFO, (void *) syncInfo);
+        NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(task, OC_STACK_KEEP_TRANSACTION, NSOICFree(syncInfo));
+    }
+    else
+    {
+        NS_LOG(DEBUG, "build NSTask for MQ message receive");
+        task = NSMakeTask(TASK_CONSUMER_RECV_MESSAGE, (void *) newMsg);
+        NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(task, OC_STACK_KEEP_TRANSACTION,
+                              NSRemoveMessage(newMsg));
+    }
+
+    NSConsumerPushEvent(task);
+
+    return OC_STACK_KEEP_TRANSACTION;
+}
+#endif
diff --git a/service/notification/src/consumer/NSConsumerMQPlugin.h b/service/notification/src/consumer/NSConsumerMQPlugin.h
new file mode 100644 (file)
index 0000000..5c8aa93
--- /dev/null
@@ -0,0 +1,39 @@
+//******************************************************************
+//
+// Copyright 2016 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 _NS_CONSUMER_MQPLUGIN_H_
+#define _NS_CONSUMER_MQPLUGIN_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#ifdef WITH_MQ
+#include "NSCommon.h"
+#include "NSStructs.h"
+
+void NSConsumerMQTaskProcessing(NSTask *);
+#endif
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+#endif // _NS_CONSUMER_MQPLUGIN_H_
index a5a63e5..366ef8c 100644 (file)
@@ -242,12 +242,13 @@ NSResult NSConsumerCacheWriteProvider(NSCacheList * list, NSCacheElement * newOb
     NSCacheElement * obj = (NSCacheElement *) OICMalloc(sizeof(NSCacheElement));
     NS_VERIFY_NOT_NULL_WITH_POST_CLEANING(obj, NS_ERROR, pthread_mutex_unlock(mutex));
 
-    NS_LOG_V(DEBUG, "New Object address : %s:%d", newProvObj->connection->addr->addr, newProvObj->connection->addr->port);
+    NS_LOG_V(INFO_PRIVATE, "New Object address : %s:%d", newProvObj->connection->addr->addr, newProvObj->connection->addr->port);
     obj->data = (void *) NSCopyProvider_internal(newProvObj);
 
     if (!obj->data)
     {
         NS_LOG (ERROR, "Failed to CopyProvider");
+        NSOICFree(obj);
         pthread_mutex_unlock(mutex);
 
         return NS_ERROR;
index 8e9e1e5..d48d897 100644 (file)
@@ -30,7 +30,7 @@
 #include "NSConsumerDiscovery.h"
 #include "NSConsumerNetworkEventListener.h"
 
-#define NS_PRESENCE_SUBSCRIBE_QUERY "/oic/ad?rt=oic.wk.notification"
+#define NS_PRESENCE_SUBSCRIBE_QUERY "/oic/ad?rt=x.org.iotivity.notification"
 
 void NSConnectionStateListener(const CAEndpoint_t * info, bool isConnected);
 
@@ -71,7 +71,7 @@ NSResult NSConsumerListenerInit()
 
 void NSConsumerListenerTermiate()
 {
-    CARegisterNetworkMonitorHandler(NULL, NULL);
+    CAUnregisterNetworkMonitorHandler(NSAdapterStateListener, NSConnectionStateListener);
     OCCancel(*getPresenceHandle(), NS_QOS, NULL, 0);
 }
 
@@ -80,7 +80,7 @@ void NSConnectionStateListener(const CAEndpoint_t * info, bool connected)
     NS_VERIFY_NOT_NULL_V(info);
 
     NS_LOG_V(DEBUG, "adapter : %d", info->adapter);
-    NS_LOG_V(DEBUG, "remote_address : %s:%d", info->addr, info->port);
+    NS_LOG_V(INFO_PRIVATE, "remote_address : %s:%d", info->addr, info->port);
     NS_LOG_V(DEBUG, "isConnect : %d", connected);
 
     NSTaskType type = TASK_EVENT_CONNECTED;
index d7552e4..2e13b59 100644 (file)
 #include "NSConsumerNetworkEventListener.h"
 #include "NSConsumerSystem.h"
 
+#ifdef WITH_MQ
+#include "NSConsumerMQPlugin.h"
+#endif
+
 void * NSConsumerMsgHandleThreadFunc(void * handle);
 
 void * NSConsumerMsgPushThreadFunc(void * data);
@@ -78,7 +82,7 @@ NSResult NSConsumerMessageHandlerInit()
     NS_VERIFY_NOT_NULL(consumerUuid, NS_ERROR);
 
     NSSetConsumerId(consumerUuid);
-    NS_LOG_V(DEBUG, "Consumer ID : %s", *NSGetConsumerId());
+    NS_LOG_V(INFO_PRIVATE, "Consumer ID : %s", *NSGetConsumerId());
 
     NS_LOG(DEBUG, "listener init");
     NSResult ret = NSConsumerListenerInit();
@@ -328,6 +332,13 @@ void NSConsumerTaskProcessing(NSTask * task)
             NSConsumerInternalTaskProcessing(task);
             break;
         }
+#ifdef WITH_MQ
+        case TASK_MQ_REQ_SUBSCRIBE:
+        {
+            NSConsumerMQTaskProcessing(task);
+            break;
+        }
+#endif
         default:
         {
             NS_LOG(ERROR, "Unknown type of task");
index e079f8c..e702bab 100644 (file)
@@ -93,12 +93,13 @@ void * NSCallbackResponseSchedule(void * ptr)
                     char * copyQuery = OICStrdup(request->query);\r
                     char * consumerId = NSGetValueFromQuery(copyQuery, NS_QUERY_CONSUMER_ID);\r
 \r
-                    if(consumerId)\r
+                    if (consumerId)\r
                     {\r
                         OICStrcpy(consumer->consumerId, UUID_STRING_SIZE, consumerId);\r
                         NSSubscribeRequestCb(consumer);\r
                     }\r
-                    OICFree(copyQuery);\r
+\r
+                    NSOICFree(copyQuery);\r
                     NSFreeConsumer(consumer);\r
                     NSFreeOCEntityHandlerRequest(request);\r
 \r
@@ -116,7 +117,7 @@ void * NSCallbackResponseSchedule(void * ptr)
                     NS_LOG(DEBUG, "No Task Type");\r
                     break;\r
             }\r
-            OICFree(node);\r
+            NSOICFree(node);\r
         }\r
 \r
         pthread_mutex_unlock(&NSMutex[CALLBACK_RESPONSE_SCHEDULER]);\r
index 81b5903..9452103 100644 (file)
@@ -79,7 +79,7 @@ void * NSDiscoverySchedule(void * ptr)
                     NS_LOG(DEBUG, "CASE TASK_REGISTER_RESOURCE : ");\r
                     NSRegisterResource();\r
                     break;\r
-#if(defined WITH_CLOUD && defined RD_CLIENT)\r
+#if (defined WITH_CLOUD)\r
                 case TASK_PUBLISH_RESOURCE:\r
                     NS_LOG(DEBUG, "CASE TASK_PUBLISH_PESOURCE : ");\r
                     NSPublishResourceToCloud((char*)node->taskData);\r
@@ -89,7 +89,7 @@ void * NSDiscoverySchedule(void * ptr)
                     break;\r
             }\r
 \r
-            OICFree(node);\r
+            NSOICFree(node);\r
         }\r
 \r
         pthread_mutex_unlock(&NSMutex[DISCOVERY_SCHEDULER]);\r
index 84c3809..02697ab 100644 (file)
@@ -92,10 +92,11 @@ NSResult NSStartProvider(NSProviderConfig config)
 #ifdef SECURED
         NS_LOG(DEBUG, "Built with SECURED");
 
-        if(!config.resourceSecurity)
+        if (!config.resourceSecurity)
         {
             NS_LOG(DEBUG, "Resource Security Off");
         }
+
         NSSetResourceSecurity(config.resourceSecurity);
 #endif
 
@@ -121,13 +122,15 @@ NSResult NSStopProvider()
     NS_LOG(DEBUG, "NSStopProvider - IN");
     pthread_mutex_lock(&nsInitMutex);
 
-    if(initProvider)
+    if (initProvider)
     {
+        CAUnregisterNetworkMonitorHandler((CAAdapterStateChangedCB)NSProviderAdapterStateListener,
+                (CAConnectionStateChangedCB)NSProviderConnectionStateListener);
         NSPushQueue(DISCOVERY_SCHEDULER, TASK_STOP_PRESENCE, NULL);
-        NSDeinitProviderInfo();
-        NSUnRegisterResource();
         NSRegisterSubscribeRequestCb((NSSubscribeRequestCallback)NULL);
         NSRegisterSyncCb((NSProviderSyncInfoCallback)NULL);
+        NSUnRegisterResource();
+        NSDeinitProviderInfo();
         NSStopScheduler();
         NSDeinitailize();
 
@@ -141,17 +144,18 @@ NSResult NSStopProvider()
 
 NSResult NSProviderEnableRemoteService(char *serverAddress)
 {
-#if(defined WITH_CLOUD && defined RD_CLIENT)
+#if (defined WITH_CLOUD)
     NS_LOG(DEBUG, "NSProviderEnableRemoteService - IN");
     pthread_mutex_lock(&nsInitMutex);
 
-    if(!initProvider || !serverAddress)
+    if (!initProvider || !serverAddress)
     {
         NS_LOG(DEBUG, "Provider service has not been started yet");
         pthread_mutex_unlock(&nsInitMutex);
         return NS_FAIL;
     }
-    NS_LOG_V(DEBUG, "Remote server address: %s", serverAddress);
+
+    NS_LOG_V(INFO_PRIVATE, "Remote server address: %s", serverAddress);
     NS_LOG(DEBUG, "Request to publish resource");
     NSPushQueue(DISCOVERY_SCHEDULER, TASK_PUBLISH_RESOURCE, serverAddress);
 
@@ -161,22 +165,24 @@ NSResult NSProviderEnableRemoteService(char *serverAddress)
 #else
     (void) serverAddress;
 #endif
-    NS_LOG_V(DEBUG, "Not logged in remote server: %s", serverAddress);
+    NS_LOG_V(INFO_PRIVATE, "Not logged in remote server: %s", serverAddress);
     return NS_FAIL;
 }
 
 NSResult NSProviderDisableRemoteService(char *serverAddress)
 {
-#if(defined WITH_CLOUD && defined RD_CLIENT)
+#if (defined WITH_CLOUD)
     NS_LOG(DEBUG, "NSProviderDisableRemoteService - IN");
     pthread_mutex_lock(&nsInitMutex);
 
-    if(!initProvider || !serverAddress)
+    if (!initProvider || !serverAddress)
     {
         NS_LOG(DEBUG, "Provider service has not been started yet");
+        pthread_mutex_unlock(&nsInitMutex);
         return NS_FAIL;
     }
-    NS_LOG_V(DEBUG, "Remote server address: %s", serverAddress);
+
+    NS_LOG_V(INFO_PRIVATE, "Remote server address: %s", serverAddress);
 
     NS_LOG(DEBUG, "Delete remote server info");
     NSDeleteRemoteServerAddress(serverAddress);
@@ -187,10 +193,46 @@ NSResult NSProviderDisableRemoteService(char *serverAddress)
 #else
     (void) serverAddress;
 #endif
-    NS_LOG_V(DEBUG, "Not logged in remote server : %s", serverAddress);
+    NS_LOG_V(INFO_PRIVATE, "Not logged in remote server : %s", serverAddress);
     return NS_FAIL;
 }
 
+#ifdef WITH_MQ
+NSResult NSProviderSubscribeMQService(const char * serverAddress, const char * topicName)
+{
+    NS_LOG(DEBUG, "NSProviderSubscribeMQService - IN");
+    pthread_mutex_lock(&nsInitMutex);
+
+    if (!initProvider || !serverAddress || !topicName)
+    {
+        NS_LOG(DEBUG, "Provider service has not been started yet or set the server "
+                "address and topicName");
+        pthread_mutex_unlock(&nsInitMutex);
+        return NS_FAIL;
+    }
+
+    NSMQTopicAddress * topicAddr = (NSMQTopicAddress *)OICMalloc(sizeof(NSMQTopicAddress));
+
+    if (!topicAddr)
+    {
+        NS_LOG(DEBUG, "fail to memory allocate");
+        pthread_mutex_unlock(&nsInitMutex);
+        return NS_FAIL;
+    }
+
+    topicAddr->serverAddr = NSGetQueryAddress(serverAddress);
+    topicAddr->topicName = OICStrdup(topicName);
+
+    NS_LOG_V(DEBUG, "input Topic Name : %s", topicAddr->topicName);
+
+    NSPushQueue(SUBSCRIPTION_SCHEDULER, TASK_MQ_REQ_SUBSCRIBE, (void *) topicAddr);
+
+    pthread_mutex_unlock(&nsInitMutex);
+    NS_LOG(DEBUG, "NSProviderSubscribeMQService - OUT");
+    return NS_OK;
+}
+#endif
+
 NSResult NSSendMessage(NSMessage * msg)
 {
     NS_LOG(DEBUG, "NSSendNotification - IN");
@@ -223,6 +265,7 @@ NSResult NSProviderSendSyncInfo(uint64_t messageId, NSSyncType type)
     if (!initProvider || !syncInfo)
     {
         NS_LOG(ERROR, "Provider is not started");
+        NSOICFree(syncInfo);
         pthread_mutex_unlock(&nsInitMutex);
         return NS_FAIL;
     }
@@ -250,7 +293,7 @@ NSResult NSAcceptSubscription(const char * consumerId, bool accepted)
     }
 
     char * newConsumerId = OICStrdup(consumerId);
-    if(accepted)
+    if (accepted)
     {
         NS_LOG(DEBUG, "accepted is true - ALLOW");
         NSPushQueue(SUBSCRIPTION_SCHEDULER, TASK_SEND_ALLOW, newConsumerId);
@@ -300,7 +343,7 @@ NSTopicLL * NSProviderGetConsumerTopics(const char * consumerId)
 
     NSPushQueue(TOPIC_SCHEDULER, TAST_GET_CONSUMER_TOPICS, &topicSync);
     pthread_cond_wait(topicSync.condition, &nsInitMutex);
-    OICFree(topicSync.consumerId);
+    NSOICFree(topicSync.consumerId);
 
     pthread_mutex_unlock(&nsInitMutex);
     NS_LOG(DEBUG, "NSProviderGetConsumerTopics - OUT");
@@ -384,12 +427,12 @@ NSResult NSProviderUnregisterTopic(const char * topicName)
 
     NSPushQueue(TOPIC_SCHEDULER, TASK_UNREGISTER_TOPIC, &topicSyncResult);
     pthread_cond_wait(topicSyncResult.condition, &nsInitMutex);
-    if(topicSyncResult.result != NS_OK)
+    if (topicSyncResult.result != NS_OK)
     {
         pthread_mutex_unlock(&nsInitMutex);
         return NS_FAIL;
     }
-    OICFree(topicSyncResult.topicData);
+    NSOICFree(topicSyncResult.topicData);
 
     pthread_mutex_unlock(&nsInitMutex);
     NS_LOG(DEBUG, "NSProviderDeleteTopics - OUT");
@@ -404,12 +447,14 @@ NSResult NSProviderSetConsumerTopic(const char * consumerId, const char * topicN
     NSCacheTopicSubData * topicSubData =
             (NSCacheTopicSubData *) OICMalloc(sizeof(NSCacheTopicSubData));
 
-    if(!initProvider || !consumerId || consumerId[0] == '\0' || !topicName || topicName[0] == '\0'
+    if (!initProvider || !consumerId || consumerId[0] == '\0' || !topicName || topicName[0] == '\0'
             || !NSGetPolicy() || !topicSubData)
     {
         NS_LOG(DEBUG, "provider is not started or "
                 "consumer id should be set for topic subscription or "
                 "Configuration must set to true.");
+        NSOICFree(topicSubData);
+        topicSubData = NULL;
         pthread_mutex_unlock(&nsInitMutex);
         return NS_FAIL;
     }
@@ -439,12 +484,14 @@ NSResult NSProviderUnsetConsumerTopic(const char * consumerId, const char * topi
     NSCacheTopicSubData * topicSubData =
             (NSCacheTopicSubData *) OICMalloc(sizeof(NSCacheTopicSubData));
 
-    if(!initProvider || !consumerId || consumerId[0] == '\0' || !topicName || topicName[0] == '\0'
+    if (!initProvider || !consumerId || consumerId[0] == '\0' || !topicName || topicName[0] == '\0'
             || !NSGetPolicy() || !topicSubData)
     {
         NS_LOG(DEBUG, "provider is not started or "
                 "consumer id should be set for topic subscription or "
                 "Configuration must set to true.");
+        NSOICFree(topicSubData);
+        topicSubData = NULL;
         pthread_mutex_unlock(&nsInitMutex);
         return NS_FAIL;
     }
index f8f9858..ea371cc 100644 (file)
@@ -56,11 +56,11 @@ OCEntityHandlerResult NSEntityHandlerNotificationCb(OCEntityHandlerFlag flag,
                     && strcmp(reqInterface, NS_INTERFACE_READ) != 0)\r
             {\r
                 NS_LOG(ERROR, "Invalid interface");\r
-                OICFree(copyQuery);\r
+                NSOICFree(copyQuery);\r
                 return ehResult;\r
             }\r
 \r
-            OICFree(copyQuery);\r
+            NSOICFree(copyQuery);\r
             NSPushQueue(SUBSCRIPTION_SCHEDULER, TASK_SEND_POLICY,\r
                     NSCopyOCEntityHandlerRequest(entityHandlerRequest));\r
 \r
@@ -104,7 +104,7 @@ OCEntityHandlerResult NSEntityHandlerMessageCb(OCEntityHandlerFlag flag,
 \r
             char * copyQuery = OICStrdup(entityHandlerRequest->query);\r
             reqInterface = OICStrdup(NSGetValueFromQuery(copyQuery, NS_QUERY_INTERFACE));\r
-            OICFree(copyQuery);\r
+            NSOICFree(copyQuery);\r
 \r
             if (reqInterface && strcmp(reqInterface, NS_INTERFACE_BASELINE) != 0\r
                     && strcmp(reqInterface, NS_INTERFACE_READ) != 0)\r
@@ -136,7 +136,7 @@ OCEntityHandlerResult NSEntityHandlerMessageCb(OCEntityHandlerFlag flag,
                     NSCopyOCEntityHandlerRequest(entityHandlerRequest));\r
             ehResult = OC_EH_OK;\r
         }\r
-        else if(ocObAction == OC_OBSERVE_DEREGISTER)\r
+        else if (ocObAction == OC_OBSERVE_DEREGISTER)\r
         {\r
             NS_LOG(DEBUG, "NSEntityHandlerMessageCb - OC_OBSERVE_DEREGISTER");\r
             NS_LOG_V(DEBUG, "NSEntityHandlerMessageCb\n - "\r
@@ -149,7 +149,7 @@ OCEntityHandlerResult NSEntityHandlerMessageCb(OCEntityHandlerFlag flag,
 \r
     ehResult = NSProviderSendResponse(entityHandlerRequest, payload, reqInterface, ehResult,\r
             NS_INTERFACE_TYPE_READ, NS_RESOURCE_MESSAGE);\r
-    OICFree(reqInterface);\r
+    NSOICFree(reqInterface);\r
     NS_LOG(DEBUG, "NSEntityHandlerMessageCb - OUT");\r
     return ehResult;\r
 }\r
@@ -179,7 +179,7 @@ OCEntityHandlerResult NSEntityHandlerSyncCb(OCEntityHandlerFlag flag,
 \r
             char * copyQuery = OICStrdup(entityHandlerRequest->query);\r
             reqInterface = OICStrdup(NSGetValueFromQuery(copyQuery, NS_QUERY_INTERFACE));\r
-            OICFree(copyQuery);\r
+            NSOICFree(copyQuery);\r
 \r
             if (reqInterface && strcmp(reqInterface, NS_INTERFACE_BASELINE) != 0\r
                     && strcmp(reqInterface, NS_INTERFACE_READWRITE) != 0)\r
@@ -198,7 +198,7 @@ OCEntityHandlerResult NSEntityHandlerSyncCb(OCEntityHandlerFlag flag,
 \r
             NS_LOG(DEBUG, "NSEntityHandlerSyncCb - OC_REST_POST");\r
 \r
-            if(NSProviderIsSyncAttributes((OCRepPayload *)entityHandlerRequest->payload))\r
+            if (NSProviderIsSyncAttributes((OCRepPayload *)entityHandlerRequest->payload))\r
             {\r
                 NSPushQueue(NOTIFICATION_SCHEDULER, TASK_RECV_READ,\r
                                     NSGetSyncInfo(entityHandlerRequest->payload));\r
@@ -228,7 +228,7 @@ OCEntityHandlerResult NSEntityHandlerSyncCb(OCEntityHandlerFlag flag,
             NSPushQueue(SUBSCRIPTION_SCHEDULER, TASK_SYNC_SUBSCRIPTION,\r
                     NSCopyOCEntityHandlerRequest(entityHandlerRequest));\r
         }\r
-        else if(ocObAction == OC_OBSERVE_DEREGISTER)\r
+        else if (ocObAction == OC_OBSERVE_DEREGISTER)\r
         {\r
             NS_LOG(DEBUG, "NSEntityHandlerSyncCb - OC_OBSERVE_DEREGISTER");\r
             NS_LOG_V(DEBUG, "NSEntityHandlerSyncCb\n - "\r
@@ -242,7 +242,7 @@ OCEntityHandlerResult NSEntityHandlerSyncCb(OCEntityHandlerFlag flag,
 \r
     ehResult = NSProviderSendResponse(entityHandlerRequest, payload, reqInterface, ehResult,\r
             NS_INTERFACE_TYPE_READ, NS_RESOURCE_MESSAGE);\r
-    OICFree(reqInterface);\r
+    NSOICFree(reqInterface);\r
 \r
     return ehResult;\r
 }\r
@@ -273,7 +273,7 @@ OCEntityHandlerResult NSEntityHandlerTopicCb(OCEntityHandlerFlag flag,
 \r
             char * copyReq = OICStrdup(entityHandlerRequest->query);\r
             reqInterface = OICStrdup(NSGetValueFromQuery(copyReq, NS_QUERY_INTERFACE));\r
-            OICFree(copyReq);\r
+            NSOICFree(copyReq);\r
 \r
             if (reqInterface && strcmp(reqInterface, NS_INTERFACE_BASELINE) != 0\r
                     && strcmp(reqInterface, NS_INTERFACE_READWRITE) != 0)\r
@@ -291,12 +291,12 @@ OCEntityHandlerResult NSEntityHandlerTopicCb(OCEntityHandlerFlag flag,
         else if (OC_REST_POST == entityHandlerRequest->method)\r
         {\r
             // Receive interesting topic list from consumers\r
-            // Send topic notice message(id = TOPIC) to the consumer \r
+            // Send topic notice message(id = TOPIC) to the consumer\r
             // which requests to post.\r
             NS_LOG(DEBUG, "NSEntityHandlerTopicCb - OC_REST_POST");\r
             // Accepter is provider. our service is not support sendtopiclist from OC_REST_POST\r
             // Accepter is consumer. our service is support sendtopiclist from OC_REST_POST\r
-            if(NSGetPolicy() == false &&\r
+            if (NSGetPolicy() == false &&\r
                     NSProviderIsTopicAttributes(OCRepPayloadClone((OCRepPayload *)\r
                             entityHandlerRequest->payload)))\r
             {\r
@@ -316,10 +316,167 @@ OCEntityHandlerResult NSEntityHandlerTopicCb(OCEntityHandlerFlag flag,
     NS_LOG(DEBUG, "NSEntityHandlerTopicCb - OUT");\r
     ehResult = NSProviderSendResponse(entityHandlerRequest, payload, reqInterface, ehResult,\r
             NS_INTERFACE_TYPE_READWRITE, NS_RESOURCE_TOPIC);\r
-    OICFree(reqInterface);\r
+    NSOICFree(reqInterface);\r
     return ehResult;\r
 }\r
 \r
+#ifdef WITH_MQ\r
+OCStackApplicationResult NSProviderMQListener(void * ctx, OCDoHandle handle,\r
+        OCClientResponse * clientResponse)\r
+{\r
+    (void) ctx;\r
+    (void) handle;\r
+\r
+    NS_LOG_V(DEBUG, "clientResponse->sequenceNumber = %d", clientResponse->sequenceNumber);\r
+\r
+    if (clientResponse->sequenceNumber == OC_OBSERVE_REGISTER)\r
+    {\r
+        NS_LOG(DEBUG, "MQ OC_OBSERVE_RIGSTER");\r
+        NSSetMQServerInfo(clientResponse->resourceUri, &(clientResponse->devAddr));\r
+    }\r
+\r
+    NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);\r
+    NS_VERIFY_STACK_SUCCESS(NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);\r
+    NS_VERIFY_NOT_NULL(clientResponse->payload, OC_STACK_KEEP_TRANSACTION);\r
+\r
+    NS_LOG(DEBUG, "income observe response of MQ notification");\r
+    NS_LOG_V(INFO_PRIVATE, "MQ OBS response income : %s:%d",\r
+            clientResponse->devAddr.addr, clientResponse->devAddr.port);\r
+    NS_LOG_V(DEBUG, "MQ OBS response result : %d",\r
+            clientResponse->result);\r
+    NS_LOG_V(DEBUG, "MQ OBS response sequenceNum : %d",\r
+            clientResponse->sequenceNumber);\r
+    NS_LOG_V(DEBUG, "MQ OBS response resource uri : %s",\r
+            clientResponse->resourceUri);\r
+    NS_LOG_V(DEBUG, "MQ OBS response Transport Type : %d",\r
+                    clientResponse->devAddr.adapter);\r
+\r
+    OCRepPayload * payload = (OCRepPayload *)clientResponse->payload;\r
+    NS_VERIFY_NOT_NULL(payload, OC_STACK_KEEP_TRANSACTION);\r
+\r
+    NSMessageType type = -1;\r
+    bool getResult = OCRepPayloadGetPropInt(payload, NS_ATTRIBUTE_TYPE, (int64_t *) &type);\r
+    NS_LOG_V (DEBUG, "message sync type : %d", (int) type);\r
+\r
+    if (!getResult && (type == NS_MESSAGE_READ || type == NS_MESSAGE_DELETED))\r
+    {\r
+        char * pId = NULL;\r
+        getResult = OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, &pId);\r
+        NS_LOG_V (INFO_PRIVATE, "provider id: %s", pId);\r
+\r
+        if (getResult && strcmp(pId, NSGetProviderInfo()->providerId) == 0)\r
+        {\r
+            NSSyncInfo * syncInfo = (NSSyncInfo *)OICMalloc(sizeof(NSSyncInfo));\r
+            syncInfo->state = (type == NS_MESSAGE_READ) ? NS_SYNC_READ : NS_SYNC_DELETED;\r
+            OICStrcpy(syncInfo->providerId, NS_UUID_STRING_SIZE, pId);\r
+            NSOICFree(pId);\r
+            NSPushQueue(NOTIFICATION_SCHEDULER, TASK_RECV_READ, (void*) syncInfo);\r
+        }\r
+    }\r
+\r
+    return OC_STACK_KEEP_TRANSACTION;\r
+}\r
+\r
+OCStackApplicationResult NSProviderGetMQResponseCB(void * ctx, OCDoHandle handle,\r
+        OCClientResponse * clientResponse)\r
+{\r
+    NS_LOG(DEBUG, "NSProviderGetMQResponseCB - IN");\r
+\r
+    (void) handle;\r
+\r
+    NS_VERIFY_NOT_NULL(clientResponse, OC_STACK_KEEP_TRANSACTION);\r
+    NS_VERIFY_STACK_SUCCESS(NSOCResultToSuccess(clientResponse->result), OC_STACK_KEEP_TRANSACTION);\r
+    NS_VERIFY_NOT_NULL(clientResponse->payload, OC_STACK_KEEP_TRANSACTION);\r
+\r
+    NS_LOG(DEBUG, "income get response of MQ broker");\r
+    NS_LOG_V(INFO_PRIVATE, "MQ GET response income : %s:%d",\r
+            clientResponse->devAddr.addr, clientResponse->devAddr.port);\r
+    NS_LOG_V(DEBUG, "MQ GET response result : %d",\r
+            clientResponse->result);\r
+    NS_LOG_V(DEBUG, "MQ GET response sequenceNum : %d",\r
+            clientResponse->sequenceNumber);\r
+    NS_LOG_V(DEBUG, "MQ GET response resource uri : %s",\r
+            clientResponse->resourceUri);\r
+    NS_LOG_V(DEBUG, "MQ GET response Transport Type : %d",\r
+                    clientResponse->devAddr.adapter);\r
+\r
+    char ** topicList = NULL;\r
+    size_t dimensions[MAX_REP_ARRAY_DEPTH] = {0};\r
+    OCRepPayloadGetStringArray((OCRepPayload *) clientResponse->payload,\r
+                               NS_ATTIRBUTE_MQ_TOPICLIST, & topicList, dimensions);\r
+\r
+    char * interestTopicName = (char *) ctx;\r
+\r
+    NS_LOG_V(DEBUG, "interestTopicName = %s", interestTopicName);\r
+    for (size_t i = 0; i < dimensions[0]; ++i)\r
+    {\r
+        NS_LOG_V(DEBUG, "found MQ topic : %s", topicList[i]);\r
+        if (!strcmp(topicList[i], interestTopicName))\r
+        {\r
+            NS_LOG(DEBUG, "subscribe to MQ notification");\r
+\r
+            OCCallbackData cbdata = { NULL, NULL, NULL };\r
+            cbdata.cb = NSProviderMQListener;\r
+            cbdata.context = NULL;\r
+            cbdata.cd = NULL;\r
+\r
+            OCStackResult ret = OCDoResource(NULL, OC_REST_OBSERVE, topicList[i],\r
+                    clientResponse->addr, NULL, CT_DEFAULT, OC_HIGH_QOS, &cbdata, NULL, 0);\r
+\r
+            if (!NSOCResultToSuccess(ret))\r
+            {\r
+                NS_LOG(DEBUG, "fail to subscribe to MQ notification");\r
+                continue;\r
+            }\r
+        }\r
+    }\r
+\r
+    NS_LOG(DEBUG, "NSProviderGetMQResponseCB - OUT");\r
+    return OC_STACK_KEEP_TRANSACTION;\r
+}\r
+\r
+OCStackApplicationResult NSProviderPublishMQResponseCB(void *ctx, OCDoHandle handle,\r
+        OCClientResponse *clientResponse)\r
+{\r
+    (void) ctx;\r
+    (void) handle;\r
+    NS_LOG(DEBUG, "Publish Topic callback received");\r
+\r
+    OCStackApplicationResult res = OC_STACK_ERROR;\r
+\r
+    NS_LOG_V(DEBUG, "Publish Topic response received code: (%d)", clientResponse->result);\r
+\r
+    if (clientResponse->payload != NULL &&\r
+        clientResponse->payload->type == PAYLOAD_TYPE_REPRESENTATION)\r
+    {\r
+        NS_LOG(DEBUG, "PAYLOAD_TYPE_REPRESENTATION received");\r
+\r
+        OCRepPayloadValue *val = ((OCRepPayload *)clientResponse->payload)->values;\r
+        while (val)\r
+        {\r
+            if( val->type == OCREP_PROP_INT)\r
+            {\r
+                NS_LOG_V(DEBUG, "Key: %s, Value: %lld, int", val->name, val->i);\r
+            }\r
+            else if( val->type == OCREP_PROP_STRING)\r
+            {\r
+                NS_LOG_V(DEBUG, "Key: %s, Value: %s, string", val->name, val->str);\r
+            }\r
+            else\r
+            {\r
+                NS_LOG_V(DEBUG, "Un supported val Type.(0x%d)", val->type);\r
+            }\r
+\r
+            val = val->next;\r
+        }\r
+\r
+        res = OC_STACK_KEEP_TRANSACTION;\r
+    }\r
+\r
+    return res;\r
+}\r
+#endif\r
+\r
 void NSProviderConnectionStateListener(const CAEndpoint_t * info, bool connected)\r
 {\r
     NS_LOG(DEBUG, "NSProviderConnectionStateListener - IN");\r
@@ -334,9 +491,9 @@ void NSProviderConnectionStateListener(const CAEndpoint_t * info, bool connected
         // Start Presence\r
         NSPushQueue(DISCOVERY_SCHEDULER, TASK_START_PRESENCE, NULL);\r
 \r
-        if(info->adapter == CA_ADAPTER_TCP)\r
+        if (info->adapter == CA_ADAPTER_TCP)\r
         {\r
-            NS_LOG_V(DEBUG, "TCP Connected remote address: %s:%d", info->addr, info->port);\r
+            NS_LOG_V(INFO_PRIVATE, "TCP Connected remote address: %s:%d", info->addr, info->port);\r
         }\r
     }\r
     else\r
@@ -346,9 +503,9 @@ void NSProviderConnectionStateListener(const CAEndpoint_t * info, bool connected
         // Set Connection State\r
         NSSetProviderConnectionState(DISCONNECTED);\r
 \r
-        if(info->adapter == CA_ADAPTER_TCP)\r
+        if (info->adapter == CA_ADAPTER_TCP)\r
         {\r
-            NS_LOG_V(DEBUG, "TCP Disconnected remote address: %s:%d", info->addr, info->port);\r
+            NS_LOG_V(INFO_PRIVATE, "TCP Disconnected remote address: %s:%d", info->addr, info->port);\r
         }\r
     }\r
 \r
@@ -398,14 +555,15 @@ bool NSProviderCompareSyncAttributes(const char * name)
 bool NSProviderIsSyncAttributes(OCRepPayload * payload)\r
 {\r
     NS_LOG(DEBUG, "get extra info");\r
-\r
     OCRepPayloadValue * curr = payload->values;\r
-    while(curr)\r
+\r
+    while (curr)\r
     {\r
         if (!NSProviderCompareSyncAttributes(curr->name))\r
         {\r
             return false;\r
         }\r
+\r
         curr = curr->next;\r
     }\r
 \r
@@ -437,12 +595,13 @@ bool NSProviderCompareSubTopicAttributes(const char * name)
 bool NSProviderIsTopicAttributes(OCRepPayload * payload)\r
 {\r
     NS_LOG(DEBUG, "get extra info");\r
-\r
     OCRepPayloadValue * curr = payload->values;\r
-    while(curr)\r
+\r
+    while (curr)\r
     {\r
         if (!NSProviderCompareTopicAttributes(curr->name))\r
         {\r
+            OCRepPayloadDestroy(payload);\r
             return false;\r
         }\r
 \r
@@ -456,6 +615,7 @@ bool NSProviderIsTopicAttributes(OCRepPayload * payload)
 \r
             if (!dimensionSize)\r
             {\r
+                OCRepPayloadDestroy(payload);\r
                 return false;\r
             }\r
 \r
@@ -465,15 +625,17 @@ bool NSProviderIsTopicAttributes(OCRepPayload * payload)
             for (int i = 0; i < (int) dimensionSize; i++)\r
             {\r
                 OCRepPayloadValue * subCurr = topicListPayload[i]->values;\r
-                while(subCurr)\r
+\r
+                while (subCurr)\r
                 {\r
                     if (!NSProviderCompareSubTopicAttributes(subCurr->name))\r
                     {\r
                         for(int j = i; j < (int) dimensionSize; ++j)\r
                         {\r
-                            OCRepPayloadDestroy(topicListPayload[i]);\r
+                            OCRepPayloadDestroy(topicListPayload[j]);\r
                         }\r
 \r
+                        NSOICFree(topicListPayload);\r
                         OCRepPayloadDestroy(payload);\r
                         return false;\r
                     }\r
@@ -481,6 +643,7 @@ bool NSProviderIsTopicAttributes(OCRepPayload * payload)
                 }\r
                 OCRepPayloadDestroy(topicListPayload[i]);\r
             }\r
+            NSOICFree(topicListPayload);\r
         }\r
         curr = curr->next;\r
     }\r
index e8b8617..0e0d791 100644 (file)
@@ -51,4 +51,12 @@ void NSProviderConnectionStateListener(const CAEndpoint_t * info, bool isConnect
 \r
 void NSProviderAdapterStateListener(CATransportAdapter_t adapter, bool enabled);\r
 \r
+#ifdef WITH_MQ\r
+OCStackApplicationResult NSProviderGetMQResponseCB(void * ctx, OCDoHandle handle,\r
+        OCClientResponse * clientResponse);\r
+\r
+OCStackApplicationResult NSProviderPublishMQResponseCB(void *ctx, OCDoHandle handle,\r
+        OCClientResponse *clientResponse);\r
+#endif\r
+\r
 #endif /* _NS_PROVIDER_LISTENER__H_ */\r
index 490fa62..9e4dd69 100644 (file)
@@ -26,9 +26,9 @@
         if (it) \\r
         { \\r
             NS_LOG(DEBUG, "already registered for topic name"); \\r
-            OICFree(topicData->topicName); \\r
-            OICFree(topicData); \\r
-            OICFree(newObj); \\r
+            NSOICFree(topicData->topicName); \\r
+            NSOICFree(topicData); \\r
+            NSOICFree(newObj); \\r
             pthread_mutex_unlock(&NSCacheMutex); \\r
             return NS_FAIL; \\r
         } \\r
@@ -38,6 +38,7 @@ NSCacheList * NSProviderStorageCreate()
 {\r
     pthread_mutex_lock(&NSCacheMutex);\r
     NSCacheList * newList = (NSCacheList *) OICMalloc(sizeof(NSCacheList));\r
+\r
     if (!newList)\r
     {\r
         pthread_mutex_unlock(&NSCacheMutex);\r
@@ -62,7 +63,7 @@ NSCacheElement * NSProviderStorageRead(NSCacheList * list, const char * findId)
     NSCacheElement * next = NULL;\r
     NSCacheType type = list->cacheType;\r
 \r
-    NS_LOG_V(DEBUG, "Find ID - %s", findId);\r
+    NS_LOG_V(INFO_PRIVATE, "Find ID - %s", findId);\r
 \r
     while (iter)\r
     {\r
@@ -107,7 +108,7 @@ NSResult NSCacheUpdateSubScriptionState(NSCacheList * list, char * id, bool stat
         {\r
             NS_LOG(DEBUG, "Update Data - IN");\r
 \r
-            NS_LOG_V(DEBUG, "currData_ID = %s", itData->id);\r
+            NS_LOG_V(INFO_PRIVATE, "currData_ID = %s", itData->id);\r
             NS_LOG_V(DEBUG, "currData_MsgObID = %d", itData->messageObId);\r
             NS_LOG_V(DEBUG, "currData_SyncObID = %d", itData->syncObId);\r
             NS_LOG_V(DEBUG, "currData_Cloud_MsgObID = %d", itData->remote_messageObId);\r
@@ -163,14 +164,14 @@ NSResult NSProviderStorageWrite(NSCacheList * list, NSCacheElement * newObj)
             {\r
                 NS_LOG(DEBUG, "Update Data - IN");\r
 \r
-                NS_LOG_V(DEBUG, "currData_ID = %s", itData->id);\r
+                NS_LOG_V(INFO_PRIVATE, "currData_ID = %s", itData->id);\r
                 NS_LOG_V(DEBUG, "currData_MsgObID = %d", itData->messageObId);\r
                 NS_LOG_V(DEBUG, "currData_SyncObID = %d", itData->syncObId);\r
                 NS_LOG_V(DEBUG, "currData_Cloud_MsgObID = %d", itData->remote_messageObId);\r
                 NS_LOG_V(DEBUG, "currData_Cloud_SyncObID = %d", itData->remote_syncObId);\r
                 NS_LOG_V(DEBUG, "currData_IsWhite = %d", itData->isWhite);\r
 \r
-                NS_LOG_V(DEBUG, "subData_ID = %s", subData->id);\r
+                NS_LOG_V(INFO_PRIVATE, "subData_ID = %s", subData->id);\r
                 NS_LOG_V(DEBUG, "subData_MsgObID = %d", subData->messageObId);\r
                 NS_LOG_V(DEBUG, "subData_SyncObID = %d", subData->syncObId);\r
                 NS_LOG_V(DEBUG, "subData_Cloud_MsgObID = %d", subData->remote_messageObId);\r
@@ -199,15 +200,15 @@ NSResult NSProviderStorageWrite(NSCacheList * list, NSCacheElement * newObj)
                 }\r
 \r
                 NS_LOG(DEBUG, "Update Data - OUT");\r
-                OICFree(subData);\r
-                OICFree(newObj);\r
+                NSOICFree(subData);\r
+                NSOICFree(newObj);\r
                 pthread_mutex_unlock(&NSCacheMutex);\r
                 return NS_OK;\r
             }\r
         }\r
 \r
     }\r
-    else if(type == NS_PROVIDER_CACHE_REGISTER_TOPIC)\r
+    else if (type == NS_PROVIDER_CACHE_REGISTER_TOPIC)\r
     {\r
         NS_LOG(DEBUG, "Type is REGITSTER TOPIC");\r
 \r
@@ -216,7 +217,7 @@ NSResult NSProviderStorageWrite(NSCacheList * list, NSCacheElement * newObj)
 \r
         NS_PROVIDER_DELETE_REGISTERED_TOPIC_DATA(it, topicData, newObj);\r
     }\r
-    else if(type == NS_PROVIDER_CACHE_CONSUMER_TOPIC_NAME)\r
+    else if (type == NS_PROVIDER_CACHE_CONSUMER_TOPIC_NAME)\r
     {\r
         NS_LOG(DEBUG, "Type is REGITSTER TOPIC");\r
 \r
@@ -225,7 +226,7 @@ NSResult NSProviderStorageWrite(NSCacheList * list, NSCacheElement * newObj)
 \r
         NS_PROVIDER_DELETE_REGISTERED_TOPIC_DATA(it, topicData, newObj);\r
     }\r
-    else if(type == NS_PROVIDER_CACHE_CONSUMER_TOPIC_CID)\r
+    else if (type == NS_PROVIDER_CACHE_CONSUMER_TOPIC_CID)\r
     {\r
         NS_LOG(DEBUG, "Type is REGITSTER TOPIC");\r
 \r
@@ -259,11 +260,11 @@ NSResult NSProviderStorageDestroy(NSCacheList * list)
     {\r
         next = (NSCacheElement *) iter->next;\r
         NSProviderDeleteCacheData(type, iter->data);\r
-        OICFree(iter);\r
+        NSOICFree(iter);\r
         iter = next;\r
     }\r
 \r
-    OICFree(list);\r
+    NSOICFree(list);\r
     return NS_OK;\r
 }\r
 \r
@@ -287,13 +288,13 @@ bool NSProviderCompareIdCacheData(NSCacheType type, void * data, const char * id
         return false;\r
     }\r
 \r
-    NS_LOG_V(DEBUG, "Data(compData) = [%s]", id);\r
+    NS_LOG_V(INFO_PRIVATE, "Data(compData) = [%s]", id);\r
 \r
     if (type == NS_PROVIDER_CACHE_SUBSCRIBER)\r
     {\r
         NSCacheSubData * subData = (NSCacheSubData *) data;\r
 \r
-        NS_LOG_V(DEBUG, "Data(subData) = [%s]", subData->id);\r
+        NS_LOG_V(INFO_PRIVATE, "Data(subData) = [%s]", subData->id);\r
 \r
         if (strcmp(subData->id, id) == 0)\r
         {\r
@@ -308,7 +309,7 @@ bool NSProviderCompareIdCacheData(NSCacheType type, void * data, const char * id
     {\r
         NSCacheSubData * subData = (NSCacheSubData *) data;\r
 \r
-        NS_LOG_V(DEBUG, "Data(subData) = [%s]", subData->id);\r
+        NS_LOG_V(INFO_PRIVATE, "Data(subData) = [%s]", subData->id);\r
 \r
         OCObservationId currID = *id;\r
 \r
@@ -355,7 +356,7 @@ bool NSProviderCompareIdCacheData(NSCacheType type, void * data, const char * id
     {\r
         NSCacheTopicSubData * topicData = (NSCacheTopicSubData *) data;\r
 \r
-        NS_LOG_V(DEBUG, "Data(topicData) = [%s]", topicData->id);\r
+        NS_LOG_V(INFO_PRIVATE, "Data(topicData) = [%s]", topicData->id);\r
 \r
         if (strcmp(topicData->id, id) == 0)\r
         {\r
@@ -384,25 +385,25 @@ NSResult NSProviderDeleteCacheData(NSCacheType type, void * data)
         NSCacheSubData * subData = (NSCacheSubData *) data;\r
 \r
         (subData->id)[0] = '\0';\r
-        OICFree(subData);\r
+        NSOICFree(subData);\r
         return NS_OK;\r
     }\r
-    else if(type == NS_PROVIDER_CACHE_REGISTER_TOPIC)\r
+    else if (type == NS_PROVIDER_CACHE_REGISTER_TOPIC)\r
     {\r
 \r
         NSCacheTopicData * topicData = (NSCacheTopicData *) data;\r
         NS_LOG_V(DEBUG, "topicData->topicName = %s, topicData->state = %d", topicData->topicName,\r
                 (int)topicData->state);\r
 \r
-        OICFree(topicData->topicName);\r
-        OICFree(topicData);\r
+        NSOICFree(topicData->topicName);\r
+        NSOICFree(topicData);\r
     }\r
-    else if(type == NS_PROVIDER_CACHE_CONSUMER_TOPIC_NAME ||\r
+    else if (type == NS_PROVIDER_CACHE_CONSUMER_TOPIC_NAME ||\r
             type == NS_PROVIDER_CACHE_CONSUMER_TOPIC_CID)\r
     {\r
         NSCacheTopicSubData * topicData = (NSCacheTopicSubData *) data;\r
-        OICFree(topicData->topicName);\r
-        OICFree(topicData);\r
+        NSOICFree(topicData->topicName);\r
+        NSOICFree(topicData);\r
     }\r
 \r
     return NS_OK;\r
@@ -416,7 +417,7 @@ NSResult NSProviderStorageDelete(NSCacheList * list, const char * delId)
 \r
     NSCacheType type = list->cacheType;\r
 \r
-    if(!del)\r
+    if (!del)\r
     {\r
         NS_LOG(DEBUG, "list head is NULL");\r
         pthread_mutex_unlock(&NSCacheMutex);\r
@@ -434,13 +435,14 @@ NSResult NSProviderStorageDelete(NSCacheList * list, const char * delId)
 \r
             list->head = del->next;\r
             NSProviderDeleteCacheData(type, del->data);\r
-            OICFree(del);\r
+            NSOICFree(del);\r
             pthread_mutex_unlock(&NSCacheMutex);\r
             return NS_OK;\r
         }\r
     }\r
 \r
     del = del->next;\r
+\r
     while (del)\r
     {\r
         if (NSProviderCompareIdCacheData(type, del->data, delId))\r
@@ -452,7 +454,7 @@ NSResult NSProviderStorageDelete(NSCacheList * list, const char * delId)
 \r
             prev->next = del->next;\r
             NSProviderDeleteCacheData(type, del->data);\r
-            OICFree(del);\r
+            NSOICFree(del);\r
             pthread_mutex_unlock(&NSCacheMutex);\r
             return NS_OK;\r
         }\r
@@ -460,6 +462,7 @@ NSResult NSProviderStorageDelete(NSCacheList * list, const char * delId)
         prev = del;\r
         del = del->next;\r
     }\r
+\r
     pthread_mutex_unlock(&NSCacheMutex);\r
     return NS_FAIL;\r
 }\r
@@ -471,7 +474,7 @@ NSTopicLL * NSProviderGetTopicsCacheData(NSCacheList * regTopicList)
 \r
     NSCacheElement * iter = regTopicList->head;\r
 \r
-    if(!iter)\r
+    if (!iter)\r
     {\r
         pthread_mutex_unlock(&NSCacheMutex);\r
         return NULL;\r
@@ -485,7 +488,8 @@ NSTopicLL * NSProviderGetTopicsCacheData(NSCacheList * regTopicList)
     {\r
         NSCacheTopicData * curr = (NSCacheTopicData *) iter->data;\r
         newTopic = (NSTopicLL *) OICMalloc(sizeof(NSTopicLL));\r
-        if(!newTopic)\r
+\r
+        if (!newTopic)\r
         {\r
             pthread_mutex_unlock(&NSCacheMutex);\r
             return NULL;\r
@@ -495,7 +499,7 @@ NSTopicLL * NSProviderGetTopicsCacheData(NSCacheList * regTopicList)
         newTopic->next = NULL;\r
         newTopic->topicName = OICStrdup(curr->topicName);\r
 \r
-        if(!topics)\r
+        if (!topics)\r
         {\r
             iterTopic = topics = newTopic;\r
         }\r
@@ -522,7 +526,7 @@ NSTopicLL * NSProviderGetConsumerTopicsCacheData(NSCacheList * regTopicList,
     pthread_mutex_lock(&NSCacheMutex);\r
     NSTopicLL * topics = NSProviderGetTopicsCacheData(regTopicList);\r
 \r
-    if(!topics)\r
+    if (!topics)\r
     {\r
         pthread_mutex_unlock(&NSCacheMutex);\r
         return NULL;\r
@@ -531,23 +535,24 @@ NSTopicLL * NSProviderGetConsumerTopicsCacheData(NSCacheList * regTopicList,
     NSCacheElement * iter = conTopicList->head;\r
     conTopicList->cacheType = NS_PROVIDER_CACHE_CONSUMER_TOPIC_CID;\r
 \r
-    while(iter)\r
+    while (iter)\r
     {\r
         NSCacheTopicSubData * curr = (NSCacheTopicSubData *)iter->data;\r
 \r
-        if(curr && strcmp(curr->id, consumerId) == 0)\r
+        if (curr && strcmp(curr->id, consumerId) == 0)\r
         {\r
-            NS_LOG_V(DEBUG, "curr->id = %s", curr->id);\r
+            NS_LOG_V(INFO_PRIVATE, "curr->id = %s", curr->id);\r
             NS_LOG_V(DEBUG, "curr->topicName = %s", curr->topicName);\r
-\r
             NSTopicLL * topicIter = topics;\r
-            while(topicIter)\r
+\r
+            while (topicIter)\r
             {\r
-                if(strcmp(topicIter->topicName, curr->topicName) == 0)\r
+                if (strcmp(topicIter->topicName, curr->topicName) == 0)\r
                 {\r
                     topicIter->state = NS_TOPIC_SUBSCRIBED;\r
                     break;\r
                 }\r
+\r
                 topicIter = topicIter->next;\r
             }\r
         }\r
@@ -566,22 +571,24 @@ bool NSProviderIsTopicSubScribed(NSCacheElement * conTopicList, char * cId, char
 {\r
     pthread_mutex_lock(&NSCacheMutex);\r
 \r
-    if(!conTopicList || !cId || !topicName)\r
+    if (!conTopicList || !cId || !topicName)\r
     {\r
         pthread_mutex_unlock(&NSCacheMutex);\r
         return false;\r
     }\r
 \r
     NSCacheElement * iter = conTopicList;\r
-    while(iter)\r
+\r
+    while (iter)\r
     {\r
         NSCacheTopicSubData * curr = (NSCacheTopicSubData *) iter->data;\r
 \r
-        if( (strcmp(curr->id, cId) == 0) && (strcmp(curr->topicName, topicName) == 0) )\r
+        if ( (strcmp(curr->id, cId) == 0) && (strcmp(curr->topicName, topicName) == 0) )\r
         {\r
             pthread_mutex_unlock(&NSCacheMutex);\r
             return true;\r
         }\r
+\r
         iter = iter->next;\r
     }\r
 \r
@@ -597,7 +604,7 @@ NSResult NSProviderDeleteConsumerTopic(NSCacheList * conTopicList,
     char * cId = topicSubData->id;\r
     char * topicName = topicSubData->topicName;\r
 \r
-    if(!conTopicList || !cId || !topicName)\r
+    if (!conTopicList || !cId || !topicName)\r
     {\r
         pthread_mutex_unlock(&NSCacheMutex);\r
         return NS_ERROR;\r
@@ -608,7 +615,7 @@ NSResult NSProviderDeleteConsumerTopic(NSCacheList * conTopicList,
 \r
     NSCacheType type = conTopicList->cacheType;\r
 \r
-    if(!del)\r
+    if (!del)\r
     {\r
         NS_LOG(DEBUG, "list head is NULL");\r
         pthread_mutex_unlock(&NSCacheMutex);\r
@@ -616,12 +623,12 @@ NSResult NSProviderDeleteConsumerTopic(NSCacheList * conTopicList,
     }\r
 \r
     NSCacheTopicSubData * curr = (NSCacheTopicSubData *) del->data;\r
-    NS_LOG_V(DEBUG, "compareid = %s", cId);\r
+    NS_LOG_V(INFO_PRIVATE, "compareid = %s", cId);\r
     NS_LOG_V(DEBUG, "comparetopicName = %s", topicName);\r
-    NS_LOG_V(DEBUG, "curr->id = %s", curr->id);\r
+    NS_LOG_V(INFO_PRIVATE, "curr->id = %s", curr->id);\r
     NS_LOG_V(DEBUG, "curr->topicName = %s", curr->topicName);\r
 \r
-    if( (strncmp(curr->id, cId, NS_UUID_STRING_SIZE) == 0) &&\r
+    if ( (strncmp(curr->id, cId, NS_UUID_STRING_SIZE) == 0) &&\r
             (strcmp(curr->topicName, topicName) == 0) )\r
     {\r
         if (del == conTopicList->head) // first object\r
@@ -633,7 +640,7 @@ NSResult NSProviderDeleteConsumerTopic(NSCacheList * conTopicList,
 \r
             conTopicList->head = del->next;\r
             NSProviderDeleteCacheData(type, del->data);\r
-            OICFree(del);\r
+            NSOICFree(del);\r
             pthread_mutex_unlock(&NSCacheMutex);\r
             return NS_OK;\r
         }\r
@@ -641,10 +648,11 @@ NSResult NSProviderDeleteConsumerTopic(NSCacheList * conTopicList,
 \r
     curr = NULL;\r
     del = del->next;\r
+\r
     while (del)\r
     {\r
         curr = (NSCacheTopicSubData *) del->data;\r
-        if( (strncmp(curr->id, cId, NS_UUID_STRING_SIZE) == 0) &&\r
+        if ( (strncmp(curr->id, cId, NS_UUID_STRING_SIZE) == 0) &&\r
                 (strcmp(curr->topicName, topicName) == 0) )\r
         {\r
             if (del == conTopicList->tail) // delete object same to last object\r
@@ -654,7 +662,7 @@ NSResult NSProviderDeleteConsumerTopic(NSCacheList * conTopicList,
 \r
             prev->next = del->next;\r
             NSProviderDeleteCacheData(type, del->data);\r
-            OICFree(del);\r
+            NSOICFree(del);\r
             pthread_mutex_unlock(&NSCacheMutex);\r
             return NS_OK;\r
         }\r
@@ -662,6 +670,7 @@ NSResult NSProviderDeleteConsumerTopic(NSCacheList * conTopicList,
         prev = del;\r
         del = del->next;\r
     }\r
+\r
     pthread_mutex_unlock(&NSCacheMutex);\r
     return NS_FAIL;\r
 }\r
index edd84f3..0119116 100644 (file)
@@ -19,6 +19,8 @@
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
 #include "NSProviderNotification.h"
+#include "NSProviderListener.h"
+#include "NSProviderSystem.h"
 
 NSResult NSSetMessagePayload(NSMessage *msg, OCRepPayload** msgPayload)
 {
@@ -76,6 +78,31 @@ NSResult NSSetSyncPayload(NSSyncInfo *sync, OCRepPayload** syncPayload)
     return NS_OK;
 }
 
+#ifdef WITH_MQ
+OCStackResult NSProviderPublishTopic(OCRepPayload * payload, OCClientResponseHandler response)
+{
+    NS_LOG(DEBUG, "NSProviderPublishTopic - IN");
+    OCCallbackData cbData;
+    memset(&cbData, 0, sizeof(OCCallbackData));
+    cbData.cb = response;
+    cbData.cd = NULL;
+    cbData.context = NULL;
+
+    NSMQServerInfo * serverInfo = NSGetMQServerInfo();
+
+    if (!serverInfo)
+    {
+        NS_LOG(DEBUG, "serverInfo is not NULL");
+        NS_LOG_V(DEBUG, "serverInfo->serverUri = %s", serverInfo->serverUri);
+    }
+
+    NS_LOG(DEBUG, "NSProviderPublishTopic - OUT");
+
+    return OCDoResource(NULL, OC_REST_POST, serverInfo->serverUri, serverInfo->devAddr,
+            (OCPayload *)payload, CT_ADAPTER_TCP, OC_LOW_QOS, &cbData, NULL, 0);
+}
+#endif
+
 NSResult NSSendNotification(NSMessage *msg)
 {
     NS_LOG(DEBUG, "NSSendMessage - IN");
@@ -90,17 +117,26 @@ NSResult NSSendNotification(NSMessage *msg)
         return NS_ERROR;
     }
 
-    if (consumerSubList->head == NULL)
+    OCRepPayload* payload = NULL;
+
+    if (NSSetMessagePayload(msg, &payload) != NS_OK)
     {
-        NS_LOG(ERROR, "SubList->head is NULL, empty SubList");
+        NS_LOG(ERROR, "fail to Get message payload");
         return NS_ERROR;
     }
 
-    OCRepPayload* payload = NULL;
+#ifdef WITH_MQ
+    if (NSGetMQServerInfo())
+    {
+        NSProviderPublishTopic(OCRepPayloadClone(payload), NSProviderPublishMQResponseCB);
+    }
+#endif
 
-    if (NSSetMessagePayload(msg, &payload) != NS_OK)
+    if (consumerSubList->head == NULL)
     {
-        NS_LOG(ERROR, "fail to Get message payload");
+        NS_LOG(ERROR, "SubList->head is NULL, empty SubList");
+        OCRepPayloadDestroy(payload);
+        msg->extraInfo = NULL;
         return NS_ERROR;
     }
 
@@ -109,7 +145,7 @@ NSResult NSSendNotification(NSMessage *msg)
     while (it)
     {
         NSCacheSubData * subData = (NSCacheSubData *) it->data;
-        NS_LOG_V(DEBUG, "message subData->id = %s", subData->id);
+        NS_LOG_V(INFO_PRIVATE, "message subData->id = %s", subData->id);
         NS_LOG_V(DEBUG, "subData->messageId = %d", subData->messageObId);
         NS_LOG_V(DEBUG, "subData->cloud_messageId = %d", subData->remote_messageObId);
         NS_LOG_V(DEBUG, "subData->syncId = %d", subData->syncObId);
@@ -120,11 +156,11 @@ NSResult NSSendNotification(NSMessage *msg)
         {
             if(subData->messageObId != 0)
             {
-                if(msg->topic && (msg->topic)[0] != '\0')
+                if (msg->topic && (msg->topic)[0] != '\0')
                 {
                     NS_LOG_V(DEBUG, "this is topic message: %s", msg->topic);
 
-                    if(NSProviderIsTopicSubScribed(consumerTopicList->head, subData->id, msg->topic))
+                    if (NSProviderIsTopicSubScribed(consumerTopicList->head, subData->id, msg->topic))
                     {
                         obArray[obCount++] = subData->messageObId;
                     }
@@ -135,13 +171,13 @@ NSResult NSSendNotification(NSMessage *msg)
                 }
             }
 
-#if(defined WITH_CLOUD && defined RD_CLIENT)
-            if(subData->remote_messageObId != 0)
+#if (defined WITH_CLOUD)
+            if (subData->remote_messageObId != 0)
             {
-                if(msg->topic && (msg->topic)[0] != '\0')
+                if (msg->topic && (msg->topic)[0] != '\0')
                 {
                     NS_LOG_V(DEBUG, "this is topic message via remote server: %s", msg->topic);
-                    if(NSProviderIsTopicSubScribed(consumerTopicList->head, subData->id, msg->topic))
+                    if (NSProviderIsTopicSubScribed(consumerTopicList->head, subData->id, msg->topic))
                     {
                         obArray[obCount++] = subData->remote_messageObId;
                     }
@@ -164,9 +200,11 @@ NSResult NSSendNotification(NSMessage *msg)
         NS_LOG(DEBUG, "-------------------------------------------------------message\n");
     }
 
-    if(!obCount)
+    if (!obCount)
     {
         NS_LOG(ERROR, "observer count is zero");
+        OCRepPayloadDestroy(payload);
+        msg->extraInfo = NULL;
         return NS_ERROR;
     }
 
@@ -210,7 +248,7 @@ NSResult NSSendSync(NSSyncInfo *sync)
     while (it)
     {
         NSCacheSubData * subData = (NSCacheSubData *) it->data;
-        NS_LOG_V(DEBUG, "sync subData->id = %s", subData->id);
+        NS_LOG_V(INFO_PRIVATE, "sync subData->id = %s", subData->id);
         NS_LOG_V(DEBUG, "subData->messageId = %d", subData->messageObId);
         NS_LOG_V(DEBUG, "subData->cloud_messageId = %d", subData->remote_messageObId);
         NS_LOG_V(DEBUG, "subData->syncId = %d", subData->syncObId);
@@ -219,13 +257,13 @@ NSResult NSSendSync(NSSyncInfo *sync)
 
         if (subData->isWhite)
         {
-            if(subData->syncObId != 0)
+            if (subData->syncObId != 0)
             {
                 obArray[obCount++] = subData->syncObId;
             }
 
-#if(defined WITH_CLOUD && defined RD_CLIENT)
-            if(subData->remote_syncObId != 0)
+#if (defined WITH_CLOUD)
+            if (subData->remote_syncObId != 0)
             {
                 obArray[obCount++] = subData->remote_syncObId;
             }
@@ -234,13 +272,33 @@ NSResult NSSendSync(NSSyncInfo *sync)
         it = it->next;
     }
 
-    OCRepPayload* payload;
+    OCRepPayload* payload = NULL;
     if (NSSetSyncPayload(sync, &payload) != NS_OK)
     {
         NS_LOG(ERROR, "Failed to allocate payload");
         return NS_ERROR;
     }
 
+#ifdef WITH_MQ
+    if (NSGetMQServerInfo())
+    {
+        OCRepPayload* MQPayload = OCRepPayloadClone(payload);
+        NSMessageType MQType = 0;
+
+        if (sync->state == NS_SYNC_READ)
+        {
+            MQType = NS_MESSAGE_READ;
+        }
+        else if (sync->state == NS_SYNC_DELETED)
+        {
+            MQType = NS_MESSAGE_DELETED;
+        }
+
+        OCRepPayloadSetPropInt(MQPayload, NS_ATTRIBUTE_TYPE, (int64_t) MQType);
+        NSProviderPublishTopic(MQPayload, NSProviderPublishMQResponseCB);
+    }
+#endif
+
     for (i = 0; i < obCount; ++i)
     {
         NS_LOG(DEBUG, "-------------------------------------------------------message\n");
@@ -252,7 +310,6 @@ NSResult NSSendSync(NSSyncInfo *sync)
             obCount, payload, OC_LOW_QOS);
 
     NS_LOG_V(DEBUG, "Sync ocstackResult = %d", ocstackResult);
-
     if (ocstackResult != OC_STACK_OK)
     {
         NS_LOG(ERROR, "fail to send Sync");
@@ -307,11 +364,10 @@ void * NSNotificationSchedule(void *ptr)
                     break;
 
             }
-            OICFree(node);
+            NSOICFree(node);
         }
 
         pthread_mutex_unlock(&NSMutex[NOTIFICATION_SCHEDULER]);
-
     }
 
     NS_LOG(INFO, "Destroy NSNotificationSchedule");
index 0fb9e44..c4d2b58 100644 (file)
@@ -27,17 +27,17 @@ NSMessageResource NotificationMessageResource;
 NSSyncResource NotificationSyncResource;
 NSTopicResource NotificationTopicResource;
 
-#if(defined WITH_CLOUD && defined RD_CLIENT)
+#if (defined WITH_CLOUD)
 #define DEFAULT_CONTEXT_VALUE 0x99
 
 OCStackApplicationResult NSHandlePublishCb(void *ctx, OCDoHandle handle,
     OCClientResponse *clientResponse)
 {
     (void) handle;
-    if(ctx != (void *)DEFAULT_CONTEXT_VALUE)
+    if (ctx != (void *)DEFAULT_CONTEXT_VALUE)
     {
         NS_LOG(DEBUG, "Invalid Publish callback received");
-    } 
+    }
 
     NS_LOG_V(DEBUG, "Publish resource response received code: %d", clientResponse->result);
 
@@ -48,15 +48,15 @@ NSResult NSPublishResourceToCloud(char *serverAddress)
 {
 
     NS_LOG(DEBUG, "NSPublishResourceToCloud - IN");
-    NS_LOG_V(DEBUG, "Remote Server Address: %s", serverAddress);
+    NS_LOG_V(INFO_PRIVATE, "Remote Server Address: %s", serverAddress);
 
     OCCallbackData cbData;
     cbData.cb = NSHandlePublishCb;
     cbData.context = (void *)DEFAULT_CONTEXT_VALUE;
     cbData.cd = NULL;
 
-    OCResourceHandle resourceHandles[1] = {NotificationResource.handle};
-    OCStackResult res = OCRDPublish(serverAddress, CT_ADAPTER_TCP, resourceHandles, 1,
+    OCResourceHandle resourceHandles[1] = { NotificationResource.handle };
+    OCStackResult res = OCRDPublish(NULL, serverAddress, CT_ADAPTER_TCP, resourceHandles, 1,
             &cbData, OC_LOW_QOS);
 
     if (res != OC_STACK_OK)
@@ -75,7 +75,7 @@ NSResult NSCreateResource(char *uri)
 
     if (!uri)
     {
-        NS_LOG(NS_ERROR, "Resource URI cannot be NULL");
+        NS_LOG(ERROR, "Resource URI cannot be NULL");
         return NS_ERROR;
     }
 
@@ -91,7 +91,7 @@ NSResult NSCreateResource(char *uri)
         NotificationResource.version = VERSION;
         NotificationResource.handle = NULL;
 
-        if(NSGetResourceSecurity())
+        if (NSGetResourceSecurity())
         {
             NS_LOG(DEBUG, "Create secured resource");
             resourceProperties = OC_DISCOVERABLE | OC_SECURE;
@@ -105,14 +105,14 @@ NSResult NSCreateResource(char *uri)
                 NS_ROOT_URI, NSEntityHandlerNotificationCb, NULL,
                 resourceProperties) != OC_STACK_OK)
         {
-            NS_LOG(NS_ERROR, "Fail to Create Notification Resource");
+            NS_LOG(ERROR, "Fail to Create Notification Resource");
             return NS_ERROR;
         }
 
         if (OCBindResourceInterfaceToResource(NotificationResource.handle, NS_INTERFACE_READ)
             != OC_STACK_OK)
         {
-            NS_LOG(NS_ERROR, "Fail to bind Notification Resource Type");
+            NS_LOG(ERROR, "Fail to bind Notification Resource Type");
             return NS_ERROR;
         }
     }
@@ -131,7 +131,7 @@ NSResult NSCreateResource(char *uri)
         NotificationMessageResource.topicName = NULL;
         NotificationMessageResource.mediaContents = NULL;
 
-        if(NSGetResourceSecurity())
+        if (NSGetResourceSecurity())
         {
             NS_LOG(DEBUG, "Create secured resource");
             resourceProperties = OC_OBSERVABLE | OC_SECURE;
@@ -145,14 +145,14 @@ NSResult NSCreateResource(char *uri)
                 NS_INTERFACE_BASELINE, NS_COLLECTION_MESSAGE_URI, NSEntityHandlerMessageCb, NULL,
                 resourceProperties) != OC_STACK_OK)
         {
-            NS_LOG(NS_ERROR, "Fail to Create Notification Message Resource");
+            NS_LOG(ERROR, "Fail to Create Notification Message Resource");
             return NS_ERROR;
         }
 
         if (OCBindResourceInterfaceToResource(NotificationMessageResource.handle, NS_INTERFACE_READ)
             != OC_STACK_OK)
         {
-            NS_LOG(NS_ERROR, "Fail to bind Notification Message Resource Type");
+            NS_LOG(ERROR, "Fail to bind Notification Message Resource Type");
             return NS_ERROR;
         }
     }
@@ -163,7 +163,7 @@ NSResult NSCreateResource(char *uri)
         NotificationSyncResource.state = NULL;
         NotificationSyncResource.handle = NULL;
 
-        if(NSGetResourceSecurity())
+        if (NSGetResourceSecurity())
         {
             NS_LOG(DEBUG, "Create secured resource");
             resourceProperties = OC_OBSERVABLE | OC_SECURE;
@@ -177,7 +177,7 @@ NSResult NSCreateResource(char *uri)
                 NS_INTERFACE_BASELINE, NS_COLLECTION_SYNC_URI, NSEntityHandlerSyncCb, NULL,
                 resourceProperties) != OC_STACK_OK)
         {
-            NS_LOG(NS_ERROR, "Fail to Create Notification Sync Resource");
+            NS_LOG(ERROR, "Fail to Create Notification Sync Resource");
             return NS_ERROR;
         }
 
@@ -185,7 +185,7 @@ NSResult NSCreateResource(char *uri)
                 NS_INTERFACE_READWRITE)
             != OC_STACK_OK)
         {
-            NS_LOG(NS_ERROR, "Fail to bind Notification Sync Resource Type");
+            NS_LOG(ERROR, "Fail to bind Notification Sync Resource Type");
             return NS_ERROR;
         }
     }
@@ -196,7 +196,7 @@ NSResult NSCreateResource(char *uri)
         NotificationTopicResource.TopicList = NULL;
         NotificationTopicResource.handle = NULL;
 
-        if(NSGetResourceSecurity())
+        if (NSGetResourceSecurity())
         {
             NS_LOG(DEBUG, "Create secured resource");
             resourceProperties = OC_RES_PROP_NONE | OC_SECURE;
@@ -210,7 +210,7 @@ NSResult NSCreateResource(char *uri)
                 NS_INTERFACE_BASELINE, NS_COLLECTION_TOPIC_URI, NSEntityHandlerTopicCb, NULL,
                 resourceProperties) != OC_STACK_OK)
         {
-            NS_LOG(NS_ERROR, "Fail to Create Notification Sync Resource");
+            NS_LOG(ERROR, "Fail to Create Notification Sync Resource");
             return NS_ERROR;
         }
 
@@ -218,7 +218,7 @@ NSResult NSCreateResource(char *uri)
                 NS_INTERFACE_READWRITE)
             != OC_STACK_OK)
         {
-            NS_LOG(NS_ERROR, "Fail to bind Notification Topic Resource Type");
+            NS_LOG(ERROR, "Fail to bind Notification Topic Resource Type");
             return NS_ERROR;
         }
     }
index fb49337..2dddff0 100755 (executable)
-//******************************************************************\r
-//\r
-// Copyright 2016 Samsung Electronics All Rights Reserved.\r
-//\r
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
-//\r
-// Licensed under the Apache License, Version 2.0 (the "License");\r
-// you may not use this file except in compliance with the License.\r
-// You may obtain a copy of the License at\r
-//\r
-//      http://www.apache.org/licenses/LICENSE-2.0\r
-//\r
-// Unless required by applicable law or agreed to in writing, software\r
-// distributed under the License is distributed on an "AS IS" BASIS,\r
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-// See the License for the specific language governing permissions and\r
-// limitations under the License.\r
-//\r
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
-\r
-#include "NSProviderScheduler.h"\r
-\r
-pthread_t NSThread[THREAD_COUNT];\r
-pthread_mutex_t NSMutex[THREAD_COUNT];\r
-sem_t NSSemaphore[THREAD_COUNT];\r
-bool NSIsRunning[THREAD_COUNT] = { false, };\r
-\r
-NSTask* NSHeadMsg[THREAD_COUNT];\r
-NSTask* NSTailMsg[THREAD_COUNT];\r
-\r
-void * NSCallbackResponseSchedule(void *ptr);\r
-void * NSDiscoverySchedule(void *ptr);\r
-void * NSSubScriptionSchedule(void *ptr);\r
-void * NSNotificationSchedule(void *ptr);\r
-void * NSTopicSchedule(void * ptr);\r
-\r
-bool NSInitScheduler()\r
-{\r
-    NS_LOG(DEBUG, "NSInitScheduler - IN");\r
-\r
-    int i = 0;\r
-\r
-    for (i = 0; i < THREAD_COUNT; i++)\r
-    {\r
-        pthread_mutex_init(&NSMutex[i], NULL);\r
-        NSIsRunning[i] = true;\r
-        sem_init(&(NSSemaphore[i]), 0, 0);\r
-    }\r
-\r
-    NS_LOG(DEBUG, "NSInitScheduler - OUT");\r
-\r
-    return true;\r
-}\r
-\r
-bool NSStartScheduler()\r
-{\r
-    int i = 0;\r
-\r
-    for (i = 0; i < THREAD_COUNT; i++)\r
-    {\r
-        pthread_mutex_lock(&NSMutex[i]);\r
-\r
-        switch (i)\r
-        {\r
-            case CALLBACK_RESPONSE_SCHEDULER:\r
-            {\r
-                NS_LOG(DEBUG, "CASE RESPONSE_SCHEDULER :");\r
-                pthread_create(&NSThread[i], NULL, NSCallbackResponseSchedule, NULL);\r
-            }\r
-                break;\r
-\r
-            case DISCOVERY_SCHEDULER:\r
-            {\r
-                NS_LOG(DEBUG, "CASE DISCOVERY_SCHEDULER :");\r
-                pthread_create(&NSThread[i], NULL, NSDiscoverySchedule, NULL);\r
-            }\r
-                break;\r
-\r
-            case SUBSCRIPTION_SCHEDULER:\r
-            {\r
-                NS_LOG(DEBUG, "CASE SUBSCRIPTION_SCHEDULER :");\r
-                pthread_create(&NSThread[i], NULL, NSSubScriptionSchedule, NULL);\r
-            }\r
-                break;\r
-\r
-            case NOTIFICATION_SCHEDULER:\r
-            {\r
-                NS_LOG(DEBUG, "CASE NOTIFICATION_SCHEDULER :");\r
-                pthread_create(&NSThread[i], NULL, NSNotificationSchedule, NULL);\r
-            }\r
-                break;\r
-\r
-            case TOPIC_SCHEDULER:\r
-            {\r
-                NS_LOG(DEBUG, "CASE TOPIC_SCHEDULER :");\r
-                pthread_create(&NSThread[i], NULL, NSTopicSchedule, NULL);\r
-            }\r
-                break;\r
-            default:\r
-                break;\r
-\r
-        }\r
-\r
-        NSHeadMsg[i] = NSTailMsg[i] = NULL;\r
-\r
-        pthread_mutex_unlock(&NSMutex[i]);\r
-\r
-    }\r
-\r
-    return true;\r
-}\r
-\r
-bool NSStopScheduler()\r
-{\r
-    NS_LOG(DEBUG, "NSStopScheduler - IN");\r
-    int i = 0;\r
-\r
-    for (i = THREAD_COUNT - 1; i >= 0; --i)\r
-    {\r
-        int status = -1;\r
-\r
-        NSIsRunning[i] = false;\r
-\r
-        sem_post(&(NSSemaphore[i]));\r
-        pthread_join(NSThread[i], (void **) &status);\r
-\r
-        NSThread[i] = 0;\r
-\r
-        pthread_mutex_lock(&NSMutex[i]);\r
-\r
-        while (NSHeadMsg[i] != NULL)\r
-        {\r
-            NSTask* temp = NSHeadMsg[i];\r
-            NSHeadMsg[i] = NSHeadMsg[i]->nextTask;\r
-            NSFreeData(i, temp);\r
-            OICFree(temp);\r
-        }\r
-\r
-        NSTailMsg[i] = NSHeadMsg[i] = NULL;\r
-\r
-        pthread_mutex_unlock(&NSMutex[i]);\r
-        pthread_mutex_destroy(&NSMutex[i]);\r
-    }\r
-\r
-    NS_LOG(DEBUG, "NSStopScheduler - OUT");\r
-\r
-    return true;\r
-}\r
-\r
-void NSPushQueue(NSSchedulerType schedulerType, NSTaskType taskType, void* data)\r
-{\r
-\r
-    if(!NSIsRunning[schedulerType])\r
-    {\r
-        return;\r
-    }\r
-\r
-    pthread_mutex_lock(&NSMutex[schedulerType]);\r
-\r
-    NS_LOG(DEBUG, "NSPushQueue - IN");\r
-    NS_LOG_V(DEBUG, "NSSchedulerType = %d", schedulerType);\r
-    NS_LOG_V(DEBUG, "NSTaskType = %d", taskType);\r
-\r
-    if (NSHeadMsg[schedulerType] == NULL)\r
-    {\r
-        NSHeadMsg[schedulerType] = (NSTask*) OICMalloc(sizeof(NSTask));\r
-        if(NSHeadMsg[schedulerType])\r
-        {\r
-            NSHeadMsg[schedulerType]->taskType = taskType;\r
-            NSHeadMsg[schedulerType]->taskData = data;\r
-            NSHeadMsg[schedulerType]->nextTask = NULL;\r
-            NSTailMsg[schedulerType] = NSHeadMsg[schedulerType];\r
-        }\r
-    }\r
-    else\r
-    {\r
-        NSTask* newNode = (NSTask*) OICMalloc(sizeof(NSTask));\r
-        if(newNode)\r
-        {\r
-            newNode->taskType = taskType;\r
-            newNode->taskData = data;\r
-            newNode->nextTask = NULL;\r
-\r
-            NSTailMsg[schedulerType]->nextTask = newNode;\r
-            NSTailMsg[schedulerType] = newNode;\r
-        }\r
-    }\r
-\r
-    sem_post(&(NSSemaphore[schedulerType]));\r
-    NS_LOG(DEBUG, "NSPushQueue - OUT");\r
-    pthread_mutex_unlock(&NSMutex[schedulerType]);\r
-}\r
-\r
-void NSFreeData(NSSchedulerType type, NSTask * task)\r
-{\r
-    NS_LOG(DEBUG, "NSFreeData - IN");\r
-\r
-    if (type == CALLBACK_RESPONSE_SCHEDULER)\r
-    {\r
-        switch (task->taskType)\r
-        {\r
-            case TASK_CB_SUBSCRIPTION:\r
-                NS_LOG(DEBUG, "CASE TASK_CB_SUBSCRIPTION : Free");\r
-                NSFreeOCEntityHandlerRequest((OCEntityHandlerRequest*) task->taskData);\r
-                break;\r
-            case TASK_CB_SYNC:\r
-                NS_LOG(DEBUG, "CASE TASK_CB_SYNC : Free");\r
-                NSFreeSync((NSSyncInfo*) task->taskData);\r
-                break;\r
-            default:\r
-                NS_LOG(DEBUG, "No Task Type");\r
-                break;\r
-        }\r
-    }\r
-    else if (type == DISCOVERY_SCHEDULER)\r
-    {\r
-        switch (task->taskType)\r
-        {\r
-            case TASK_START_PRESENCE:\r
-            case TASK_STOP_PRESENCE:\r
-            case TASK_REGISTER_RESOURCE:\r
-                NS_LOG(DEBUG, "Not required Free");\r
-                break;\r
-            default:\r
-                NS_LOG(DEBUG, "No Task Type");\r
-                break;\r
-        }\r
-    }\r
-    else if (type == SUBSCRIPTION_SCHEDULER)\r
-    {\r
-        switch (task->taskType)\r
-        {\r
-            case TASK_SEND_POLICY:\r
-            case TASK_RECV_SUBSCRIPTION:\r
-            case TASK_RECV_UNSUBSCRIPTION:\r
-            case TASK_SYNC_SUBSCRIPTION:\r
-                NS_LOG(DEBUG, "NSFreeOCEntityHandlerRequest : Free ");\r
-                NSFreeOCEntityHandlerRequest((OCEntityHandlerRequest*) task->taskData);\r
-                break;\r
-            case TASK_SEND_ALLOW:\r
-            case TASK_SEND_DENY:\r
-                NS_LOG(DEBUG, "NSFreeConsumer : Free ");\r
-                NSFreeConsumer((NSConsumer *) task->taskData);\r
-                break;\r
-            default:\r
-                NS_LOG(DEBUG, "No Task Type");\r
-                break;\r
-        }\r
-    }\r
-    else if (type == NOTIFICATION_SCHEDULER)\r
-    {\r
-        switch (task->taskType)\r
-        {\r
-            case TASK_SEND_NOTIFICATION:\r
-            {\r
-                NS_LOG(DEBUG, "NSFreeMessage : Free ");\r
-                NSFreeMessage((NSMessage *)task->taskData);\r
-                break;\r
-            }\r
-            case TASK_SEND_READ:\r
-            case TASK_RECV_READ:\r
-                NS_LOG(DEBUG, "NSFreeSync : Free ");\r
-                NSFreeSync((NSSyncInfo*) task->taskData);\r
-                break;\r
-\r
-            default:\r
-                NS_LOG(DEBUG, "No Task Type");\r
-                break;\r
-        }\r
-    }\r
-    else if (type == TOPIC_SCHEDULER)\r
-    {\r
-        switch (task->taskType)\r
-        {\r
-            case TASK_SUBSCRIBE_TOPIC:\r
-            case TASK_UNSUBSCRIBE_TOPIC:\r
-            {\r
-                NSCacheTopicSubData * data = task->taskData;\r
-                OICFree(data->topicName);\r
-                OICFree(data);\r
-            }\r
-                break;\r
-            case TASK_REGISTER_TOPIC:\r
-            case TASK_UNREGISTER_TOPIC:\r
-            {\r
-                OICFree(task->taskData);\r
-            }\r
-                break;\r
-            case TASK_SEND_TOPICS:\r
-            case TASK_POST_TOPIC:\r
-            {\r
-                NS_LOG(DEBUG, "TASK_POST_TOPIC : ");\r
-                NSFreeOCEntityHandlerRequest((OCEntityHandlerRequest*) task->taskData);\r
-            }\r
-                break;\r
-            default:\r
-                break;\r
-        }\r
-    }\r
-    NS_LOG(DEBUG, "NSFreeData - OUT");\r
-}\r
+//******************************************************************
+//
+// Copyright 2016 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 "NSProviderScheduler.h"
+
+#ifdef __TIZENRT__
+#include <tinyara/config.h>
+#endif
+
+pthread_t NSThread[THREAD_COUNT];
+pthread_mutex_t NSMutex[THREAD_COUNT];
+sem_t NSSemaphore[THREAD_COUNT];
+bool NSIsRunning[THREAD_COUNT] = { false, };
+
+NSTask* NSHeadMsg[THREAD_COUNT];
+NSTask* NSTailMsg[THREAD_COUNT];
+
+void * NSCallbackResponseSchedule(void *ptr);
+void * NSDiscoverySchedule(void *ptr);
+void * NSSubScriptionSchedule(void *ptr);
+void * NSNotificationSchedule(void *ptr);
+void * NSTopicSchedule(void * ptr);
+
+bool NSInitScheduler()
+{
+    NS_LOG(DEBUG, "NSInitScheduler - IN");
+
+    int i = 0;
+
+    for (i = 0; i < THREAD_COUNT; i++)
+    {
+        pthread_mutex_init(&NSMutex[i], NULL);
+        NSIsRunning[i] = true;
+        sem_init(&(NSSemaphore[i]), 0, 0);
+    }
+
+    NS_LOG(DEBUG, "NSInitScheduler - OUT");
+
+    return true;
+}
+
+#ifdef __TIZENRT__
+static int ns_pthread_create(pthread_t *thread, pthread_startroutine_t start_routine,
+                             pthread_addr_t arg, const char *task_name, int stack_size)
+{
+/* All callers have null attr, so ignore it for simple implementation*/
+    pthread_attr_t task_attr;
+
+    pthread_attr_init(&task_attr);
+
+    (void)pthread_attr_setschedparam(&task_attr, PTHREAD_DEFAULT_PRIORITY);
+    (void)pthread_attr_setstacksize(&task_attr, stack_size);
+
+    int ret = pthread_create(thread, &task_attr, start_routine, NULL);
+    if (ret)
+    {
+        return ret;
+    }
+
+    pthread_setname_np(*thread, task_name);
+
+    return 0;
+}
+#endif
+
+bool NSStartScheduler()
+{
+    int i = 0;
+
+    for (i = 0; i < THREAD_COUNT; i++)
+    {
+        pthread_mutex_lock(&NSMutex[i]);
+
+        switch (i)
+        {
+            case CALLBACK_RESPONSE_SCHEDULER:
+            {
+                NS_LOG(DEBUG, "CASE RESPONSE_SCHEDULER :");
+#ifdef __TIZENRT__
+                ns_pthread_create(&NSThread[i], NSCallbackResponseSchedule, NULL,
+                                  "IoT_NS_CallbackResponseSchedule",
+                                  CONFIG_IOTIVITY_NS_CALLBACKRESPONSESCHED_PTHREAD_STACKSIZE);
+#else
+                pthread_create(&NSThread[i], NULL, NSCallbackResponseSchedule, NULL);
+#endif
+            }
+                break;
+
+            case DISCOVERY_SCHEDULER:
+            {
+                NS_LOG(DEBUG, "CASE DISCOVERY_SCHEDULER :");
+#ifdef __TIZENRT__
+                ns_pthread_create(&NSThread[i], NSDiscoverySchedule, NULL,
+                                  "IoT_NS_DiscoverySchedule",
+                                  CONFIG_IOTIVITY_NS_DISCOVERSCHED_PTHREAD_STACKSIZE);
+#else
+                pthread_create(&NSThread[i], NULL, NSDiscoverySchedule, NULL);
+#endif
+            }
+                break;
+
+            case SUBSCRIPTION_SCHEDULER:
+            {
+                NS_LOG(DEBUG, "CASE SUBSCRIPTION_SCHEDULER :");
+#ifdef __TIZENRT__
+                ns_pthread_create(&NSThread[i], NSSubScriptionSchedule, NULL,
+                                  "IOT_NS_SubScriptionSchedule",
+                                  CONFIG_IOTIVITY_NS_SUBSCRIPTIONSCHED_PTHREAD_STACKSIZE);
+#else
+                pthread_create(&NSThread[i], NULL, NSSubScriptionSchedule, NULL);
+#endif
+            }
+                break;
+
+            case NOTIFICATION_SCHEDULER:
+            {
+                NS_LOG(DEBUG, "CASE NOTIFICATION_SCHEDULER :");
+#ifdef __TIZENRT__
+                ns_pthread_create(&NSThread[i], NSNotificationSchedule, NULL,
+                                  "IoT_NS_NotificationSchedule",
+                                  CONFIG_IOTIVITY_NS_NOTIFICATIONSCHED_PTHREAD_STACKSIZE);
+#else
+                pthread_create(&NSThread[i], NULL, NSNotificationSchedule, NULL);
+#endif
+            }
+                break;
+
+            case TOPIC_SCHEDULER:
+            {
+                NS_LOG(DEBUG, "CASE TOPIC_SCHEDULER :");
+#ifdef __TIZENRT__
+                ns_pthread_create(&NSThread[i], NSTopicSchedule, NULL, "IoT_NS_TopicSchedule",
+                                  CONFIG_IOTIVITY_NS_TOPICSCHED_PTHREAD_STACKSIZE);
+#else
+                pthread_create(&NSThread[i], NULL, NSTopicSchedule, NULL);
+#endif
+            }
+                break;
+            default:
+                break;
+
+        }
+
+        NSHeadMsg[i] = NSTailMsg[i] = NULL;
+
+        pthread_mutex_unlock(&NSMutex[i]);
+
+    }
+
+    return true;
+}
+
+bool NSStopScheduler()
+{
+    NS_LOG(DEBUG, "NSStopScheduler - IN");
+    int i = 0;
+
+    for (i = THREAD_COUNT - 1; i >= 0; --i)
+    {
+        int status = -1;
+
+        NSIsRunning[i] = false;
+
+        sem_post(&(NSSemaphore[i]));
+        pthread_join(NSThread[i], (void **) &status);
+
+        NSThread[i] = 0;
+
+        pthread_mutex_lock(&NSMutex[i]);
+
+        while (NSHeadMsg[i] != NULL)
+        {
+            NSTask* temp = NSHeadMsg[i];
+            NSHeadMsg[i] = NSHeadMsg[i]->nextTask;
+            NSFreeData(i, temp);
+            NSOICFree(temp);
+        }
+
+        NSTailMsg[i] = NSHeadMsg[i] = NULL;
+
+        pthread_mutex_unlock(&NSMutex[i]);
+        pthread_mutex_destroy(&NSMutex[i]);
+    }
+
+    NS_LOG(DEBUG, "NSStopScheduler - OUT");
+
+    return true;
+}
+
+void NSPushQueue(NSSchedulerType schedulerType, NSTaskType taskType, void* data)
+{
+
+    if (!NSIsRunning[schedulerType])
+    {
+        return;
+    }
+
+    pthread_mutex_lock(&NSMutex[schedulerType]);
+
+    NS_LOG(DEBUG, "NSPushQueue - IN");
+    NS_LOG_V(DEBUG, "NSSchedulerType = %d", schedulerType);
+    NS_LOG_V(DEBUG, "NSTaskType = %d", taskType);
+
+    if (NSHeadMsg[schedulerType] == NULL)
+    {
+        NSHeadMsg[schedulerType] = (NSTask*) OICMalloc(sizeof(NSTask));
+
+        if (NSHeadMsg[schedulerType])
+        {
+            NSHeadMsg[schedulerType]->taskType = taskType;
+            NSHeadMsg[schedulerType]->taskData = data;
+            NSHeadMsg[schedulerType]->nextTask = NULL;
+            NSTailMsg[schedulerType] = NSHeadMsg[schedulerType];
+        }
+    }
+    else
+    {
+        NSTask* newNode = (NSTask*) OICMalloc(sizeof(NSTask));
+        if (newNode)
+        {
+            newNode->taskType = taskType;
+            newNode->taskData = data;
+            newNode->nextTask = NULL;
+
+            NSTailMsg[schedulerType]->nextTask = newNode;
+            NSTailMsg[schedulerType] = newNode;
+        }
+    }
+
+    sem_post(&(NSSemaphore[schedulerType]));
+    NS_LOG(DEBUG, "NSPushQueue - OUT");
+    pthread_mutex_unlock(&NSMutex[schedulerType]);
+}
+
+void NSFreeData(NSSchedulerType type, NSTask * task)
+{
+    NS_LOG(DEBUG, "NSFreeData - IN");
+
+    if (type == CALLBACK_RESPONSE_SCHEDULER)
+    {
+        switch (task->taskType)
+        {
+            case TASK_CB_SUBSCRIPTION:
+                NS_LOG(DEBUG, "CASE TASK_CB_SUBSCRIPTION : Free");
+                NSFreeOCEntityHandlerRequest((OCEntityHandlerRequest*) task->taskData);
+                break;
+            case TASK_CB_SYNC:
+                NS_LOG(DEBUG, "CASE TASK_CB_SYNC : Free");
+                NSFreeSync((NSSyncInfo*) task->taskData);
+                break;
+            default:
+                NS_LOG(DEBUG, "No Task Type");
+                break;
+        }
+    }
+    else if (type == DISCOVERY_SCHEDULER)
+    {
+        switch (task->taskType)
+        {
+            case TASK_START_PRESENCE:
+            case TASK_STOP_PRESENCE:
+            case TASK_REGISTER_RESOURCE:
+                NS_LOG(DEBUG, "Not required Free");
+                break;
+            default:
+                NS_LOG(DEBUG, "No Task Type");
+                break;
+        }
+    }
+    else if (type == SUBSCRIPTION_SCHEDULER)
+    {
+        switch (task->taskType)
+        {
+            case TASK_SEND_POLICY:
+            case TASK_RECV_SUBSCRIPTION:
+            case TASK_RECV_UNSUBSCRIPTION:
+            case TASK_SYNC_SUBSCRIPTION:
+                NS_LOG(DEBUG, "NSFreeOCEntityHandlerRequest : Free ");
+                NSFreeOCEntityHandlerRequest((OCEntityHandlerRequest*) task->taskData);
+                break;
+            case TASK_SEND_ALLOW:
+            case TASK_SEND_DENY:
+                NS_LOG(DEBUG, "NSFreeConsumer : Free ");
+                NSFreeConsumer((NSConsumer *) task->taskData);
+                break;
+            default:
+                NS_LOG(DEBUG, "No Task Type");
+                break;
+        }
+    }
+    else if (type == NOTIFICATION_SCHEDULER)
+    {
+        switch (task->taskType)
+        {
+            case TASK_SEND_NOTIFICATION:
+            {
+                NS_LOG(DEBUG, "NSFreeMessage : Free ");
+                NSFreeMessage((NSMessage *)task->taskData);
+                break;
+            }
+            case TASK_SEND_READ:
+            case TASK_RECV_READ:
+                NS_LOG(DEBUG, "NSFreeSync : Free ");
+                NSFreeSync((NSSyncInfo*) task->taskData);
+                break;
+
+            default:
+                NS_LOG(DEBUG, "No Task Type");
+                break;
+        }
+    }
+    else if (type == TOPIC_SCHEDULER)
+    {
+        switch (task->taskType)
+        {
+            case TASK_SUBSCRIBE_TOPIC:
+            case TASK_UNSUBSCRIBE_TOPIC:
+            {
+                NSCacheTopicSubData * data = task->taskData;
+                NSOICFree(data->topicName);
+                NSOICFree(data);
+            }
+                break;
+            case TASK_REGISTER_TOPIC:
+            case TASK_UNREGISTER_TOPIC:
+            {
+                NSOICFree(task->taskData);
+            }
+                break;
+            case TASK_SEND_TOPICS:
+            case TASK_POST_TOPIC:
+            {
+                NS_LOG(DEBUG, "TASK_POST_TOPIC : ");
+                NSFreeOCEntityHandlerRequest((OCEntityHandlerRequest*) task->taskData);
+            }
+                break;
+            default:
+                break;
+        }
+    }
+    NS_LOG(DEBUG, "NSFreeData - OUT");
+}
index 321109d..3116cbb 100644 (file)
@@ -19,6 +19,7 @@
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
 \r
 #include "NSProviderSubscription.h"\r
+#include "NSProviderListener.h"\r
 \r
 NSResult NSInitSubscriptionList()\r
 {\r
@@ -78,7 +79,7 @@ NSResult NSSendAccessPolicyResponse(OCEntityHandlerRequest *entityHandlerRequest
         return NS_ERROR;\r
     }\r
 \r
-    NS_LOG_V(DEBUG, "NS Provider ID: %s", NSGetProviderInfo()->providerId);\r
+    NS_LOG_V(INFO_PRIVATE, "NS Provider ID: %s", NSGetProviderInfo()->providerId);\r
 \r
     char * copyReq = OICStrdup(entityHandlerRequest->query);\r
     char * reqInterface = NSGetValueFromQuery(copyReq, NS_QUERY_INTERFACE);\r
@@ -89,7 +90,8 @@ NSResult NSSendAccessPolicyResponse(OCEntityHandlerRequest *entityHandlerRequest
         OCResourcePayloadAddStringLL(&payload->interfaces, NS_INTERFACE_READ);\r
         OCResourcePayloadAddStringLL(&payload->types, NS_ROOT_TYPE);\r
     }\r
-    OICFree(copyReq);\r
+\r
+    NSOICFree(copyReq);\r
     OCRepPayloadSetUri(payload, NS_ROOT_URI);\r
     OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, NSGetProviderInfo()->providerId);\r
     OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_VERSION, VERSION);\r
@@ -125,15 +127,15 @@ void NSHandleSubscription(OCEntityHandlerRequest *entityHandlerRequest, NSResour
     char * copyReq = OICStrdup(entityHandlerRequest->query);\r
     char * id = NSGetValueFromQuery(copyReq, NS_QUERY_CONSUMER_ID);\r
 \r
-    if(!id)\r
+    if (!id)\r
     {\r
-        OICFree(copyReq);\r
+        NSOICFree(copyReq);\r
         NSFreeOCEntityHandlerRequest(entityHandlerRequest);\r
         NS_LOG(ERROR, "Invalid ConsumerID");\r
         return;\r
     }\r
 \r
-    NS_LOG_V(DEBUG, "consumerId = %s", id);\r
+    NS_LOG_V(INFO_PRIVATE, "consumerId = %s", id);\r
     if (resourceType == NS_RESOURCE_MESSAGE)\r
     {\r
         NS_LOG(DEBUG, "resourceType == NS_RESOURCE_MESSAGE");\r
@@ -143,17 +145,17 @@ void NSHandleSubscription(OCEntityHandlerRequest *entityHandlerRequest, NSResour
         NS_VERIFY_NOT_NULL_V(subData);\r
 \r
         OICStrcpy(subData->id, UUID_STRING_SIZE, id);\r
-        NS_LOG_V(DEBUG, "SubList ID = [%s]", subData->id);\r
+        NS_LOG_V(INFO_PRIVATE, "SubList ID = [%s]", subData->id);\r
 \r
-        NS_LOG_V(DEBUG, "Consumer Address: %s", entityHandlerRequest->devAddr.addr);\r
+        NS_LOG_V(INFO_PRIVATE, "Consumer Address: %s", entityHandlerRequest->devAddr.addr);\r
 \r
         subData->remote_messageObId = subData->messageObId = 0;\r
 \r
         bool iSRemoteServer = false;\r
 \r
-#if(defined WITH_CLOUD && defined RD_CLIENT)\r
+#if(defined WITH_CLOUD)\r
         iSRemoteServer = NSIsRemoteServerAddress(entityHandlerRequest->devAddr.addr);\r
-        if(iSRemoteServer)\r
+        if (iSRemoteServer)\r
         {\r
             NS_LOG(DEBUG, "Requested by remote server");\r
             subData->remote_messageObId = entityHandlerRequest->obsInfo.obsId;\r
@@ -161,7 +163,7 @@ void NSHandleSubscription(OCEntityHandlerRequest *entityHandlerRequest, NSResour
         }\r
 #endif\r
 \r
-        if(!iSRemoteServer)\r
+        if (!iSRemoteServer)\r
         {\r
             NS_LOG(DEBUG, "Requested by local consumer");\r
             subData->messageObId = entityHandlerRequest->obsInfo.obsId;\r
@@ -181,7 +183,7 @@ void NSHandleSubscription(OCEntityHandlerRequest *entityHandlerRequest, NSResour
         }\r
 \r
         bool currPolicy = NSGetPolicy();\r
-        NSAskAcceptanceToUser(entityHandlerRequest);\r
+        NSAskAcceptanceToUser(NSCopyOCEntityHandlerRequest(entityHandlerRequest));\r
 \r
         if (currPolicy == NS_POLICY_PROVIDER)\r
         {\r
@@ -192,6 +194,8 @@ void NSHandleSubscription(OCEntityHandlerRequest *entityHandlerRequest, NSResour
             NS_LOG(DEBUG, "NSGetSubscriptionAccepter == NS_ACCEPTER_CONSUMER");\r
             NSSendConsumerSubResponse(NSCopyOCEntityHandlerRequest(entityHandlerRequest));\r
         }\r
+\r
+        NSFreeOCEntityHandlerRequest(entityHandlerRequest);\r
     }\r
     else if (resourceType == NS_RESOURCE_SYNC)\r
     {\r
@@ -202,16 +206,16 @@ void NSHandleSubscription(OCEntityHandlerRequest *entityHandlerRequest, NSResour
         NS_VERIFY_NOT_NULL_V(subData);\r
 \r
         OICStrcpy(subData->id, UUID_STRING_SIZE, id);\r
-        NS_LOG_V(DEBUG, "SubList ID = [%s]", subData->id);\r
+        NS_LOG_V(INFO_PRIVATE, "SubList ID = [%s]", subData->id);\r
 \r
-        NS_LOG_V(DEBUG, "Consumer Address: %s", entityHandlerRequest->devAddr.addr);\r
+        NS_LOG_V(INFO_PRIVATE, "Consumer Address: %s", entityHandlerRequest->devAddr.addr);\r
 \r
         subData->remote_syncObId = subData->syncObId = 0;\r
         bool isRemoteServer = false;\r
 \r
-#if(defined WITH_CLOUD && defined RD_CLIENT)\r
+#if (defined WITH_CLOUD)\r
         isRemoteServer = NSIsRemoteServerAddress(entityHandlerRequest->devAddr.addr);\r
-        if(isRemoteServer)\r
+        if (isRemoteServer)\r
         {\r
             NS_LOG(DEBUG, "Requested by remote server");\r
             subData->remote_syncObId = entityHandlerRequest->obsInfo.obsId;\r
@@ -219,7 +223,7 @@ void NSHandleSubscription(OCEntityHandlerRequest *entityHandlerRequest, NSResour
         }\r
 #endif\r
 \r
-        if(!isRemoteServer)\r
+        if (!isRemoteServer)\r
         {\r
             NS_LOG(DEBUG, "Requested by local consumer");\r
             subData->syncObId = entityHandlerRequest->obsInfo.obsId;\r
@@ -233,14 +237,14 @@ void NSHandleSubscription(OCEntityHandlerRequest *entityHandlerRequest, NSResour
         element->data = (void*) subData;\r
         element->next = NULL;\r
 \r
-        if (NSProviderStorageWrite(consumerSubList, element) != NS_OK)\r
+        if (NS_OK != NSProviderStorageWrite(consumerSubList, element))\r
         {\r
             NS_LOG(ERROR, "Fail to write cache");\r
         }\r
 \r
         NSFreeOCEntityHandlerRequest(entityHandlerRequest);\r
     }\r
-    OICFree(copyReq);\r
+    NSOICFree(copyReq);\r
 \r
     NS_LOG(DEBUG, "NSHandleSubscription - OUT");\r
 }\r
@@ -251,12 +255,11 @@ void NSHandleUnsubscription(OCEntityHandlerRequest *entityHandlerRequest)
 \r
     consumerSubList->cacheType = NS_PROVIDER_CACHE_SUBSCRIBER_OBSERVE_ID;\r
 \r
-    while(NSProviderStorageDelete(consumerSubList, (char *)\r
+    while (NSProviderStorageDelete(consumerSubList, (char *)\r
             &(entityHandlerRequest->obsInfo.obsId)) != NS_FAIL);\r
-    consumerSubList->cacheType = NS_PROVIDER_CACHE_SUBSCRIBER;\r
 \r
+    consumerSubList->cacheType = NS_PROVIDER_CACHE_SUBSCRIBER;\r
     NSFreeOCEntityHandlerRequest(entityHandlerRequest);\r
-\r
     NS_LOG(DEBUG, "NSHandleUnsubscription - OUT");\r
 }\r
 \r
@@ -294,11 +297,12 @@ NSResult NSSendResponse(const char * id, bool accepted)
 \r
     NSCacheElement * element = NSProviderStorageRead(consumerSubList, id);\r
 \r
-    if(element == NULL)\r
+    if (element == NULL)\r
     {\r
         NS_LOG(ERROR, "element is NULL");\r
         return NS_ERROR;\r
     }\r
+\r
     NSCacheSubData * subData = (NSCacheSubData*) element->data;\r
 \r
     if (OCNotifyListOfObservers(rHandle, (OCObservationId*)&subData->messageObId, 1,\r
@@ -309,8 +313,8 @@ NSResult NSSendResponse(const char * id, bool accepted)
         return NS_ERROR;\r
 \r
     }\r
-    OCRepPayloadDestroy(payload);\r
 \r
+    OCRepPayloadDestroy(payload);\r
     NS_LOG(DEBUG, "NSSendResponse - OUT");\r
     return NS_OK;\r
 }\r
@@ -328,9 +332,9 @@ NSResult NSSendConsumerSubResponse(OCEntityHandlerRequest * entityHandlerRequest
     char * copyReq = OICStrdup(entityHandlerRequest->query);\r
     char * id = NSGetValueFromQuery(copyReq, NS_QUERY_CONSUMER_ID);\r
 \r
-    if(!id)\r
+    if (!id)\r
     {\r
-        OICFree(copyReq);\r
+        NSOICFree(copyReq);\r
         NSFreeOCEntityHandlerRequest(entityHandlerRequest);\r
         NS_LOG(ERROR, "Invalid ConsumerID");\r
         return NS_ERROR;\r
@@ -338,12 +342,44 @@ NSResult NSSendConsumerSubResponse(OCEntityHandlerRequest * entityHandlerRequest
 \r
     NSCacheUpdateSubScriptionState(consumerSubList, id, true);\r
     NSSendResponse(id, true);\r
-    OICFree(copyReq);\r
+    NSOICFree(copyReq);\r
     NSFreeOCEntityHandlerRequest(entityHandlerRequest);\r
     NS_LOG(DEBUG, "NSSendSubscriptionResponse - OUT");\r
     return NS_OK;\r
 }\r
 \r
+#ifdef WITH_MQ\r
+void NSProviderMQSubscription(NSMQTopicAddress * topicAddr)\r
+{\r
+    char * serverUri = topicAddr->serverAddr;\r
+    char * topicName = topicAddr->topicName;\r
+\r
+    NS_LOG_V(DEBUG, "input Topic Name2 : %s", topicAddr->topicName);\r
+\r
+    OCDevAddr * addr = NSChangeAddress(serverUri);\r
+    OCCallbackData cbdata = { NULL, NULL, NULL };\r
+    cbdata.cb = NSProviderGetMQResponseCB;\r
+    cbdata.context = OICStrdup(topicName);\r
+    cbdata.cd = NSOICFree;\r
+\r
+    char requestUri[100] = "coap+tcp://";\r
+\r
+    NS_LOG_V(DEBUG, "requestUri1 = %s", requestUri);\r
+    OICStrcat(requestUri, strlen(requestUri)+strlen(serverUri)+1, serverUri);\r
+    NS_LOG_V(DEBUG, "requestUri2 = %s", requestUri);\r
+    OICStrcat(requestUri, strlen(requestUri)+ strlen("/oic/ps") + 1, "/oic/ps");\r
+    NS_LOG_V(DEBUG, "requestUri3 = %s", requestUri);\r
+    OCStackResult ret = OCDoResource(NULL, OC_REST_GET, requestUri, addr,\r
+                                     NULL, CT_DEFAULT, OC_HIGH_QOS, &cbdata, NULL, 0);\r
+\r
+    NSOCResultToSuccess(ret);\r
+\r
+    NSOICFree(topicAddr->serverAddr);\r
+    NSOICFree(topicAddr->topicName);\r
+    NSOICFree(topicAddr);\r
+}\r
+#endif\r
+\r
 void * NSSubScriptionSchedule(void *ptr)\r
 {\r
     if (ptr == NULL)\r
@@ -386,7 +422,7 @@ void * NSSubScriptionSchedule(void *ptr)
 \r
                     NSCacheUpdateSubScriptionState(consumerSubList, consumerId, true);\r
                     NSSendResponse(consumerId, true);\r
-                    OICFree(consumerId);\r
+                    NSOICFree(consumerId);\r
                     break;\r
                 }\r
                 case TASK_SEND_DENY:\r
@@ -396,7 +432,7 @@ void * NSSubScriptionSchedule(void *ptr)
 \r
                     NSCacheUpdateSubScriptionState(consumerSubList, consumerId, false);\r
                     NSSendResponse(consumerId, false);\r
-                    OICFree(consumerId);\r
+                    NSOICFree(consumerId);\r
 \r
                     break;\r
                 }\r
@@ -405,11 +441,17 @@ void * NSSubScriptionSchedule(void *ptr)
                     NSHandleSubscription((OCEntityHandlerRequest*) node->taskData,\r
                             NS_RESOURCE_SYNC);\r
                     break;\r
+#ifdef WITH_MQ\r
+                case TASK_MQ_REQ_SUBSCRIBE:\r
+                    NS_LOG(DEBUG, "CASE TASK_MQ_REQ_SUBSCRIBE : ");\r
+                    NSProviderMQSubscription((NSMQTopicAddress*) node->taskData);\r
+                    break;\r
+#endif\r
                 default:\r
                     break;\r
 \r
             }\r
-            OICFree(node);\r
+            NSOICFree(node);\r
         }\r
 \r
         pthread_mutex_unlock(&NSMutex[SUBSCRIPTION_SCHEDULER]);\r
index b8181bc..0f50776 100644 (file)
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
 #include "NSProviderSystem.h"\r
 \r
-#if(defined WITH_CLOUD && defined RD_CLIENT)\r
+#if (defined WITH_CLOUD)\r
 #define MAX_SERVER_ADDRESS 32\r
 static char NSRemoteServerAddress[MAX_SERVER_ADDRESS] = {0,};\r
 #endif\r
 \r
+#ifdef WITH_MQ\r
+static NSMQServerInfo * mqServerInfo = NULL;\r
+#endif\r
+\r
 static NSConnectionState NSProviderConnectionState;\r
 \r
 NSProviderInfo * providerInfo;\r
 bool NSPolicy = true;\r
-bool NSResourceSecurity = true;\r
+bool NSResourceSecurity = false;\r
 \r
 void NSSetProviderConnectionState(NSConnectionState state)\r
 {\r
@@ -44,7 +48,7 @@ NSConnectionState NSGetProviderConnectionState()
     return NSProviderConnectionState;\r
 }\r
 \r
-#if(defined WITH_CLOUD && defined RD_CLIENT)\r
+#if (defined WITH_CLOUD)\r
 void NSSetRemoteServerAddress(char *serverAddress)\r
 {\r
 \r
@@ -53,16 +57,16 @@ void NSSetRemoteServerAddress(char *serverAddress)
 \r
 void NSDeleteRemoteServerAddress(char *serverAddress)\r
 {\r
-    NS_LOG_V(DEBUG, "Delete cloud address: %s", serverAddress);\r
+    NS_LOG_V(INFO_PRIVATE, "Delete cloud address: %s", serverAddress);\r
 \r
     memset(NSRemoteServerAddress, 0, MAX_SERVER_ADDRESS);\r
 }\r
 \r
 bool NSIsRemoteServerAddress(char *serverAddress)\r
 {\r
-    NS_LOG_V(DEBUG, "Check server address: %s", serverAddress);\r
+    NS_LOG_V(INFO_PRIVATE, "Check server address: %s", serverAddress);\r
 \r
-    if(serverAddress != NULL)\r
+    if (serverAddress != NULL)\r
     {\r
         return strstr(NSRemoteServerAddress, serverAddress);\r
     }\r
@@ -77,45 +81,47 @@ void NSInitProviderInfo(const char * userInfo)
 \r
     providerInfo = (NSProviderInfo *) OICMalloc(sizeof(NSProviderInfo));\r
     const char * generatedUuid = (char *)OCGetServerInstanceIDString();\r
-    NS_LOG_V(DEBUG, "Generate Provider ID: %s", generatedUuid);\r
+    NS_LOG_V(INFO_PRIVATE, "Generate Provider ID: %s", generatedUuid);\r
     OICStrcpy(providerInfo->providerId, UUID_STRING_SIZE, generatedUuid);\r
 \r
     providerInfo->providerName = NULL;\r
     providerInfo->userInfo = NULL;\r
 \r
-    if(userInfo)\r
+    if (userInfo)\r
+    {\r
         providerInfo->userInfo = OICStrdup(userInfo);\r
+    }\r
 }\r
 \r
 void NSDeinitProviderInfo()\r
 {\r
     NS_LOG(DEBUG, "NSDeinitProviderInfo");\r
 \r
-    if(!providerInfo)\r
+    if (!providerInfo)\r
     {\r
         NS_LOG(DEBUG, "providerInfo is NULL");\r
         return;\r
     }\r
 \r
-    if(providerInfo->providerName)\r
+    if (providerInfo->providerName)\r
     {\r
-        OICFree(providerInfo->providerName);\r
+        NSOICFree(providerInfo->providerName);\r
         providerInfo->providerName = NULL;\r
     }\r
 \r
-    if(providerInfo->userInfo)\r
+    if (providerInfo->userInfo)\r
     {\r
-        OICFree(providerInfo->userInfo);\r
+        NSOICFree(providerInfo->userInfo);\r
         providerInfo->userInfo = NULL;\r
     }\r
 \r
-    OICFree(providerInfo);\r
+    NSOICFree(providerInfo);\r
     providerInfo = NULL;\r
 }\r
 \r
 NSProviderInfo * NSGetProviderInfo()\r
 {\r
-    NS_LOG_V(DEBUG, "ProviderInfo: %s", providerInfo->providerId);\r
+    NS_LOG_V(INFO_PRIVATE, "ProviderInfo: %s", providerInfo->providerId);\r
 \r
     return providerInfo;\r
 }\r
@@ -144,3 +150,22 @@ const char * NSGetUserInfo()
 {\r
     return providerInfo->userInfo;\r
 }\r
+\r
+#ifdef WITH_MQ\r
+void NSSetMQServerInfo(const char * serverUri, OCDevAddr * devAddr)\r
+{\r
+    if (!mqServerInfo)\r
+    {\r
+        NS_LOG(DEBUG, "setMqServer");\r
+        mqServerInfo = (NSMQServerInfo *)OICMalloc(sizeof(NSMQServerInfo));\r
+        mqServerInfo->serverUri = OICStrdup(serverUri);\r
+        mqServerInfo->devAddr = (OCDevAddr *)OICMalloc(sizeof(OCDevAddr));\r
+        memcpy(mqServerInfo->devAddr, devAddr, sizeof(OCDevAddr));\r
+    }\r
+}\r
+\r
+NSMQServerInfo * NSGetMQServerInfo()\r
+{\r
+    return mqServerInfo;\r
+}\r
+#endif\r
index a6c7edb..aa14921 100644 (file)
@@ -1,50 +1,55 @@
-//******************************************************************\r
-//\r
-// Copyright 2016 Samsung Electronics All Rights Reserved.\r
-//\r
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
-//\r
-// Licensed under the Apache License, Version 2.0 (the "License");\r
-// you may not use this file except in compliance with the License.\r
-// You may obtain a copy of the License at\r
-//\r
-//      http://www.apache.org/licenses/LICENSE-2.0\r
-//\r
-// Unless required by applicable law or agreed to in writing, software\r
-// distributed under the License is distributed on an "AS IS" BASIS,\r
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-// See the License for the specific language governing permissions and\r
-// limitations under the License.\r
-//\r
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
-\r
-#ifndef _NS_PROVIDER_SYSTEM__H_\r
-#define _NS_PROVIDER_SYSTEM__H_\r
-\r
-#include <string.h>\r
-#include "logger.h"\r
-#include "NSCommon.h"\r
-#include "NSConstants.h"\r
-#include "oic_malloc.h"\r
-#include "NSStructs.h"\r
-#include "NSUtil.h"\r
-\r
-void NSSetProviderConnectionState(NSConnectionState state);\r
-NSConnectionState NSGetProviderConnectionState();\r
-\r
-void NSInitProviderInfo(const char * userInfo);\r
-void NSDeinitProviderInfo();\r
-NSProviderInfo * NSGetProviderInfo();\r
-const char * NSGetUserInfo();\r
-bool NSGetPolicy();\r
-void NSSetPolicy(bool policy);\r
-bool NSGetResourceSecurity();\r
-void NSSetResourceSecurity(bool secured);\r
-\r
-#if (defined WITH_CLOUD && defined RD_CLIENT)\r
-void NSSetRemoteServerAddress(char *serverAddress);\r
-void NSDeleteRemoteServerAddress(char *serverAddress);\r
-bool NSIsRemoteServerAddress(char *serverAddress);\r
-#endif\r
-\r
-#endif /* _NS_PROVIDER_SYSTEM__H_ */\r
+//******************************************************************
+//
+// Copyright 2016 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 _NS_PROVIDER_SYSTEM__H_
+#define _NS_PROVIDER_SYSTEM__H_
+
+#include <string.h>
+#include "logger.h"
+#include "NSCommon.h"
+#include "NSConstants.h"
+#include "oic_malloc.h"
+#include "NSStructs.h"
+#include "NSUtil.h"
+
+void NSSetProviderConnectionState(NSConnectionState state);
+NSConnectionState NSGetProviderConnectionState();
+
+void NSInitProviderInfo(const char * userInfo);
+void NSDeinitProviderInfo();
+NSProviderInfo * NSGetProviderInfo();
+const char * NSGetUserInfo();
+bool NSGetPolicy();
+void NSSetPolicy(bool policy);
+bool NSGetResourceSecurity();
+void NSSetResourceSecurity(bool secured);
+
+#ifdef WITH_MQ
+void NSSetMQServerInfo(const char * serverUri, OCDevAddr * devAddr);
+NSMQServerInfo * NSGetMQServerInfo();
+#endif
+
+#if (defined WITH_CLOUD)
+void NSSetRemoteServerAddress(char *serverAddress);
+void NSDeleteRemoteServerAddress(char *serverAddress);
+bool NSIsRemoteServerAddress(char *serverAddress);
+#endif
+
+#endif /* _NS_PROVIDER_SYSTEM__H_ */
index bd23e91..a262f89 100644 (file)
-//******************************************************************\r
-//\r
-// Copyright 2016 Samsung Electronics All Rights Reserved.\r
-//\r
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
-//\r
-// Licensed under the Apache License, Version 2.0 (the "License");\r
-// you may not use this file except in compliance with the License.\r
-// You may obtain a copy of the License at\r
-//\r
-//      http://www.apache.org/licenses/LICENSE-2.0\r
-//\r
-// Unless required by applicable law or agreed to in writing, software\r
-// distributed under the License is distributed on an "AS IS" BASIS,\r
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-// See the License for the specific language governing permissions and\r
-// limitations under the License.\r
-//\r
-//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
-\r
-#include "NSProviderTopic.h"\r
-#include "oic_string.h"\r
-#include "oic_malloc.h"\r
-#include <pthread.h>\r
-\r
-NSResult NSSendTopicUpdation();\r
-\r
-NSResult NSInitTopicList()\r
-{\r
-    NS_LOG(DEBUG, "NSInitTopicList - IN");\r
-\r
-    consumerTopicList = NSProviderStorageCreate();\r
-    NS_VERIFY_NOT_NULL(consumerTopicList, NS_FAIL);\r
-    consumerTopicList->cacheType = NS_PROVIDER_CACHE_CONSUMER_TOPIC_NAME;\r
-\r
-    registeredTopicList = NSProviderStorageCreate();\r
-    NS_VERIFY_NOT_NULL(registeredTopicList, NS_FAIL);\r
-    registeredTopicList->cacheType = NS_PROVIDER_CACHE_REGISTER_TOPIC;\r
-\r
-    NS_LOG(DEBUG, "NSInitTopicList - OUT");\r
-    return NS_OK;\r
-}\r
-\r
-size_t NSProviderGetTopicListSize(NSTopicLL * firstElement)\r
-{\r
-    if (!firstElement)\r
-    {\r
-        return 0;\r
-    }\r
-\r
-    int cnt = 0;\r
-\r
-    NSTopicLL * iter = firstElement;\r
-\r
-    while (iter)\r
-    {\r
-        cnt++;\r
-        iter = iter->next;\r
-    }\r
-\r
-    return cnt;\r
-}\r
-\r
-NSResult NSRegisterTopic(const char * topicName)\r
-{\r
-    NS_LOG(DEBUG, "NSWriteTopicsToStorage()");\r
-\r
-    NSCacheTopicData * data = (NSCacheTopicData *) OICMalloc(sizeof(NSCacheTopicData));\r
-    NS_VERIFY_NOT_NULL(data, NS_FAIL);\r
-    data->topicName = (char *) topicName;\r
-    data->state = NS_TOPIC_UNSUBSCRIBED;\r
-\r
-    NSCacheElement * element = (NSCacheElement *) OICMalloc(sizeof(NSCacheElement));\r
-    if (!element)\r
-    {\r
-        OICFree(data->topicName);\r
-        OICFree(data);\r
-        return NS_FAIL;\r
-    }\r
-    element->data = (void *) data;\r
-    element->next = NULL;\r
-\r
-    if(NSProviderStorageWrite(registeredTopicList, element) != NS_OK)\r
-    {\r
-        NS_LOG(DEBUG, "fail to write cache");\r
-        return NS_FAIL;\r
-    }\r
-    NSSendTopicUpdation();\r
-\r
-    NS_LOG(DEBUG, "NSWriteTopicsToStorage() NS_OK");\r
-    return NS_OK;\r
-}\r
-\r
-NSResult NSUnregisterTopic(const char * topicName)\r
-{\r
-    NS_LOG(DEBUG, "NSDeleteTopics()");\r
-    NSResult result = NS_OK;\r
-\r
-    if (!topicName)\r
-    {\r
-        NS_LOG(ERROR, "topicName is NULL");\r
-        return NS_ERROR;\r
-    }\r
-\r
-    result = NSProviderStorageDelete(registeredTopicList, topicName);\r
-    while (NSProviderStorageDelete(consumerTopicList, topicName) != NS_FAIL)\r
-    {\r
-    }\r
-\r
-    if (result == NS_OK)\r
-    {\r
-        NSSendTopicUpdation();\r
-    }\r
-\r
-    return result;\r
-}\r
-\r
-NSResult NSSendTopicUpdation()\r
-{\r
-    NS_LOG(DEBUG, "NSSendTopicUpdation - IN");\r
-\r
-    OCRepPayload* payload = OCRepPayloadCreate();\r
-\r
-    if (!payload)\r
-    {\r
-        NS_LOG(ERROR, "fail to create playload");\r
-        return NS_ERROR;\r
-    }\r
-\r
-    OCResourceHandle rHandle = NULL;\r
-    if (NSPutMessageResource(NULL, &rHandle) != NS_OK)\r
-    {\r
-        NS_LOG(ERROR, "Fail to put message resource");\r
-        return NS_ERROR;\r
-    }\r
-\r
-    OCRepPayloadSetUri(payload, NS_COLLECTION_MESSAGE_URI);\r
-    OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, NS_TOPIC);\r
-    OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, NSGetProviderInfo()->providerId);\r
-\r
-    OCObservationId obArray[255] =\r
-    { 0, };\r
-    int obCount = 0;\r
-\r
-    NSCacheElement * it = consumerSubList->head;\r
-\r
-    while (it)\r
-    {\r
-        NSCacheSubData * subData = (NSCacheSubData *) it->data;\r
-\r
-        if (subData->isWhite)\r
-        {\r
-            if (subData->messageObId != 0)\r
-            {\r
-                obArray[obCount++] = subData->messageObId;\r
-            }\r
-\r
-#if(defined WITH_CLOUD && defined RD_CLIENT)\r
-            if(subData->remote_messageObId != 0)\r
-            {\r
-                obArray[obCount++] = subData->remote_messageObId;\r
-            }\r
-#endif\r
-        }\r
-        it = it->next;\r
-    }\r
-\r
-    if (!obCount)\r
-    {\r
-        NS_LOG(ERROR, "observer count is zero");\r
-        return NS_ERROR;\r
-    }\r
-\r
-    if (OCNotifyListOfObservers(rHandle, obArray, obCount, payload, OC_HIGH_QOS) != OC_STACK_OK)\r
-    {\r
-        NS_LOG(ERROR, "fail to send topic updation");\r
-        OCRepPayloadDestroy(payload);\r
-        return NS_ERROR;\r
-\r
-    }\r
-    OCRepPayloadDestroy(payload);\r
-\r
-    NS_LOG(DEBUG, "NSSendTopicUpdation - OUT");\r
-    return NS_OK;\r
-}\r
-\r
-NSResult NSSendTopicUpdationToConsumer(char *consumerId)\r
-{\r
-    NS_LOG(DEBUG, "NSSendTopicUpdationToConsumer - IN");\r
-\r
-    OCRepPayload* payload = OCRepPayloadCreate();\r
-\r
-    if (!payload)\r
-    {\r
-        NS_LOG(ERROR, "fail to create playload");\r
-        return NS_ERROR;\r
-    }\r
-\r
-    OCResourceHandle rHandle = NULL;\r
-    if (NSPutMessageResource(NULL, &rHandle) != NS_OK)\r
-    {\r
-        NS_LOG(ERROR, "Fail to put message resource");\r
-        return NS_ERROR;\r
-    }\r
-\r
-    OCRepPayloadSetUri(payload, NS_COLLECTION_MESSAGE_URI);\r
-    OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, NS_TOPIC);\r
-    OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, NSGetProviderInfo()->providerId);\r
-\r
-    NSCacheElement * element = NSProviderStorageRead(consumerSubList, consumerId);\r
-\r
-    if (element == NULL)\r
-    {\r
-        NS_LOG(ERROR, "element is NULL");\r
-        return NS_ERROR;\r
-    }\r
-\r
-    NSCacheSubData * subData = (NSCacheSubData*) element->data;\r
-\r
-    if (OCNotifyListOfObservers(rHandle, (OCObservationId*) &subData->messageObId, 1, payload,\r
-            OC_HIGH_QOS) != OC_STACK_OK)\r
-    {\r
-        NS_LOG(ERROR, "fail to send topic updation");\r
-        OCRepPayloadDestroy(payload);\r
-        return NS_ERROR;\r
-    }\r
-\r
-    OCRepPayloadDestroy(payload);\r
-\r
-    NS_LOG(DEBUG, "NSSendTopicUpdationToConsumer - OUT");\r
-    return NS_OK;\r
-}\r
-\r
-NSResult NSSendTopicList(OCEntityHandlerRequest * entityHandlerRequest)\r
-{\r
-    NS_LOG(DEBUG, "NSSendTopicList - IN");\r
-\r
-    char * copyReq = OICStrdup(entityHandlerRequest->query);\r
-    char * id = NSGetValueFromQuery(copyReq, NS_QUERY_CONSUMER_ID);\r
-    NSTopicLL * topics = NULL;\r
-\r
-    if (!id)\r
-    {\r
-        NS_LOG(DEBUG, "Send registered topic list");\r
-        topics = NSProviderGetTopicsCacheData(registeredTopicList);\r
-    }\r
-    else\r
-    {\r
-        NS_LOG(DEBUG, "Send subscribed topic list to consumer");\r
-        topics = NSProviderGetConsumerTopicsCacheData(registeredTopicList, consumerTopicList, id);\r
-        if (!topics)\r
-        {\r
-            topics = NSProviderGetTopicsCacheData(registeredTopicList);\r
-        }\r
-    }\r
-\r
-    // make response for the Get Request\r
-    OCEntityHandlerResponse response;\r
-    response.numSendVendorSpecificHeaderOptions = 0;\r
-    memset(response.sendVendorSpecificHeaderOptions, 0,\r
-            sizeof response.sendVendorSpecificHeaderOptions);\r
-    memset(response.resourceUri, 0, sizeof response.resourceUri);\r
-\r
-    OCRepPayload* payload = OCRepPayloadCreate();\r
-    if (!payload)\r
-    {\r
-        NS_LOG(ERROR, "payload is NULL");\r
-        OICFree(copyReq);\r
-        return NS_ERROR;\r
-    }\r
-\r
-    OCRepPayloadSetUri(payload, NS_COLLECTION_TOPIC_URI);\r
-    if (id)\r
-    {\r
-        OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_CONSUMER_ID, id);\r
-    }\r
-    OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, NSGetProviderInfo()->providerId);\r
-    OICFree(copyReq);\r
-\r
-    if (topics)\r
-    {\r
-        NS_LOG(DEBUG, "topicList is NULL");\r
-        size_t dimensionSize = (size_t) NSProviderGetTopicListSize(topics);\r
-        NS_LOG_V(DEBUG, "dimensionSize = %d", (int)dimensionSize);\r
-\r
-        if (!dimensionSize)\r
-        {\r
-            return NS_ERROR;\r
-        }\r
-\r
-        OCRepPayload** payloadTopicArray = (OCRepPayload **) OICMalloc(\r
-                sizeof(OCRepPayload *) * dimensionSize);\r
-        NS_VERIFY_NOT_NULL(payloadTopicArray, NS_ERROR);\r
-\r
-        size_t dimensions[3] = { dimensionSize, 0, 0 };\r
-\r
-        for (int i = 0; i < (int) dimensionSize; i++)\r
-        {\r
-            NS_LOG_V(DEBUG, "topicName = %s", topics->topicName);\r
-            NS_LOG_V(DEBUG, "topicState = %d",(int) topics->state);\r
-\r
-            payloadTopicArray[i] = OCRepPayloadCreate();\r
-            NS_VERIFY_NOT_NULL(payloadTopicArray[i], NS_ERROR);\r
-            OCRepPayloadSetPropString(payloadTopicArray[i], NS_ATTRIBUTE_TOPIC_NAME,\r
-                    topics->topicName);\r
-            OCRepPayloadSetPropInt(payloadTopicArray[i], NS_ATTRIBUTE_TOPIC_SELECTION,\r
-                    (int) topics->state);\r
-\r
-            NSTopicLL * next = topics->next;\r
-            OICFree(topics->topicName);\r
-            OICFree(topics);\r
-            topics = next;\r
-        }\r
-\r
-        OCRepPayloadSetPropObjectArray(payload, NS_ATTRIBUTE_TOPIC_LIST,\r
-                (const OCRepPayload**) (payloadTopicArray), dimensions);\r
-        for (int i = 0; i < (int) dimensionSize; ++i)\r
-        {\r
-            OCRepPayloadDestroy(payloadTopicArray[i]);\r
-        }\r
-        OICFree(payloadTopicArray);\r
-    }\r
-    else\r
-    {\r
-        size_t dimensions[3] = { 0, 0, 0 };\r
-\r
-        OCRepPayloadSetPropObjectArrayAsOwner(payload, NS_ATTRIBUTE_TOPIC_LIST,\r
-                (OCRepPayload **) NULL, dimensions);\r
-    }\r
-\r
-    copyReq = OICStrdup(entityHandlerRequest->query);\r
-    char * reqInterface = NSGetValueFromQuery(copyReq, NS_QUERY_INTERFACE);\r
-\r
-    if (reqInterface && strcmp(reqInterface, NS_INTERFACE_BASELINE) == 0)\r
-    {\r
-        OCResourcePayloadAddStringLL(&payload->interfaces, NS_INTERFACE_BASELINE);\r
-        OCResourcePayloadAddStringLL(&payload->interfaces, NS_INTERFACE_READ);\r
-        OCResourcePayloadAddStringLL(&payload->types, NS_ROOT_TYPE);\r
-    }\r
-    OICFree(copyReq);\r
-\r
-    response.requestHandle = entityHandlerRequest->requestHandle;\r
-    response.resourceHandle = entityHandlerRequest->resource;\r
-    response.persistentBufferFlag = 0;\r
-    response.ehResult = OC_EH_OK;\r
-    response.payload = (OCPayload *) payload;\r
-\r
-    if (OCDoResponse(&response) != OC_STACK_OK)\r
-    {\r
-        NS_LOG(ERROR, "Fail to response topic list");\r
-        OCRepPayloadDestroy(payload);\r
-        return NS_ERROR;\r
-    }\r
-\r
-    OCRepPayloadDestroy(payload);\r
-    NS_LOG(DEBUG, "NSSendTopicList - OUT");\r
-    return NS_OK;\r
-}\r
-\r
-NSResult NSPostConsumerTopics(OCEntityHandlerRequest * entityHandlerRequest)\r
-{\r
-    NS_LOG(DEBUG, "NSPostConsumerTopics() - IN");\r
-\r
-    char * consumerId = NULL;\r
-    OCRepPayload * payload = (OCRepPayload *) entityHandlerRequest->payload;\r
-    OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_CONSUMER_ID, &consumerId);\r
-\r
-    if (!consumerId)\r
-    {\r
-        NS_LOG(DEBUG, "Invalid consumer ID");\r
-        return NS_FAIL;\r
-    }\r
-\r
-    NS_LOG_V(DEBUG, "TOPIC consumer ID = %s", consumerId);\r
-\r
-    consumerTopicList->cacheType = NS_PROVIDER_CACHE_CONSUMER_TOPIC_CID;\r
-
-    while (NSProviderStorageDelete(consumerTopicList, consumerId) != NS_FAIL)\r
-    {\r
-    }\r
-    consumerTopicList->cacheType = NS_PROVIDER_CACHE_CONSUMER_TOPIC_NAME;\r
-\r
-    OCRepPayload ** topicListPayload = NULL;\r
-    OCRepPayloadValue * payloadValue = NULL;\r
-    payloadValue = NSPayloadFindValue(payload, NS_ATTRIBUTE_TOPIC_LIST);\r
-    size_t dimensionSize = calcDimTotal(payloadValue->arr.dimensions);\r
-    size_t dimensions[3] = { dimensionSize, 0, 0 };\r
-    OCRepPayloadGetPropObjectArray(payload, NS_ATTRIBUTE_TOPIC_LIST, &topicListPayload, dimensions);\r
-\r
-    for (int i = 0; i < (int) dimensionSize; i++)\r
-    {\r
-        char * topicName = NULL;\r
-        int64_t topicState = 0;\r
-\r
-        OCRepPayloadGetPropString(topicListPayload[i], NS_ATTRIBUTE_TOPIC_NAME, &topicName);\r
-        OCRepPayloadGetPropInt(topicListPayload[i], NS_ATTRIBUTE_TOPIC_SELECTION, &topicState);\r
-        NS_LOG_V(DEBUG, "Topic Name(state):  %s(%d)", topicName, (int)topicState);\r
-\r
-        if (NS_TOPIC_SUBSCRIBED == (NSTopicState) topicState)\r
-        {\r
-            NSCacheTopicSubData * topicSubData = (NSCacheTopicSubData *) OICMalloc(\r
-                    sizeof(NSCacheTopicSubData));\r
-            NS_VERIFY_NOT_NULL(topicSubData, NS_FAIL);\r
-\r
-            OICStrcpy(topicSubData->id, NS_UUID_STRING_SIZE, consumerId);\r
-            topicSubData->topicName = topicName;\r
-\r
-            NSCacheElement * newObj = (NSCacheElement *) OICMalloc(sizeof(NSCacheElement));\r
-\r
-            if (!newObj)\r
-            {\r
-                OICFree(topicSubData->topicName);\r
-                OICFree(topicSubData);\r
-                OICFree(consumerId);\r
-                return NS_FAIL;\r
-            }\r
-\r
-            newObj->data = (NSCacheData *) topicSubData;\r
-            newObj->next = NULL;\r
-\r
-            NSProviderStorageWrite(consumerTopicList, newObj);
-        }\r
-    }\r
-    NSSendTopicUpdationToConsumer(consumerId);\r
-    OICFree(consumerId);\r
-    NS_LOG(DEBUG, "NSPostConsumerTopics() - OUT");\r
-    return NS_OK;\r
-}\r
-\r
-void * NSTopicSchedule(void * ptr)\r
-{\r
-    if (ptr == NULL)\r
-    {\r
-        NS_LOG(DEBUG, "Create NSTopicSchedule");\r
-    }\r
-\r
-    while (NSIsRunning[TOPIC_SCHEDULER])\r
-    {\r
-        sem_wait(&NSSemaphore[TOPIC_SCHEDULER]);\r
-        pthread_mutex_lock(&NSMutex[TOPIC_SCHEDULER]);\r
-\r
-        if (NSHeadMsg[TOPIC_SCHEDULER] != NULL)\r
-        {\r
-            NSTask *node = NSHeadMsg[TOPIC_SCHEDULER];\r
-            NSHeadMsg[TOPIC_SCHEDULER] = node->nextTask;\r
-\r
-            switch (node->taskType)\r
-            {\r
-                case TASK_SEND_TOPICS:\r
-                    NS_LOG(DEBUG, "CASE TASK_SEND_TOPICS : ");\r
-                    NSSendTopicList((OCEntityHandlerRequest*) node->taskData);\r
-                    NSFreeOCEntityHandlerRequest((OCEntityHandlerRequest*) node->taskData);\r
-                    break;\r
-                case TASK_SUBSCRIBE_TOPIC:\r
-                {\r
-                    NS_LOG(DEBUG, "CASE TASK_SUBSCRIBE_TOPIC : ");\r
-                    NSTopicSyncResult * topicSyncResult = (NSTopicSyncResult *) node->taskData;\r
-                    pthread_mutex_lock(topicSyncResult->mutex);\r
-                    NSCacheElement * newObj = (NSCacheElement *) OICMalloc(sizeof(NSCacheElement));\r
-                    NSCacheTopicSubData * subData =\r
-                            (NSCacheTopicSubData *) topicSyncResult->topicData;\r
-                    if (!newObj)\r
-                    {\r
-                        OICFree(subData->topicName);\r
-                        OICFree(subData);\r
-                        pthread_cond_signal(topicSyncResult->condition);\r
-                        pthread_mutex_unlock(topicSyncResult->mutex);\r
-                    }\r
-                    else\r
-                    {\r
-                        if (NSProviderStorageRead(registeredTopicList, subData->topicName))\r
-                        {\r
-                            newObj->data = topicSyncResult->topicData;\r
-                            newObj->next = NULL;\r
-                            if(NSProviderStorageWrite(consumerTopicList, newObj) == NS_OK)\r
-                            {\r
-                                NSSendTopicUpdationToConsumer(subData->id);\r
-                                topicSyncResult->result = NS_OK;\r
-                            }\r
-                        }\r
-                        else\r
-                        {\r
-                            OICFree(subData->topicName);\r
-                            OICFree(subData);\r
-                            OICFree(newObj);\r
-                        }\r
-                    }\r
-                    pthread_cond_signal(topicSyncResult->condition);\r
+//******************************************************************
+//
+// Copyright 2016 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 "NSProviderTopic.h"
+#include "oic_string.h"
+#include "oic_malloc.h"
+#include <pthread.h>
+
+NSResult NSSendTopicUpdation();
+
+NSResult NSInitTopicList()
+{
+    NS_LOG(DEBUG, "NSInitTopicList - IN");
+
+    consumerTopicList = NSProviderStorageCreate();
+    NS_VERIFY_NOT_NULL(consumerTopicList, NS_FAIL);
+    consumerTopicList->cacheType = NS_PROVIDER_CACHE_CONSUMER_TOPIC_NAME;
+
+    registeredTopicList = NSProviderStorageCreate();
+    NS_VERIFY_NOT_NULL(registeredTopicList, NS_FAIL);
+    registeredTopicList->cacheType = NS_PROVIDER_CACHE_REGISTER_TOPIC;
+
+    NS_LOG(DEBUG, "NSInitTopicList - OUT");
+    return NS_OK;
+}
+
+size_t NSProviderGetTopicListSize(NSTopicLL * firstElement)
+{
+    if (!firstElement)
+    {
+        return 0;
+    }
+
+    int cnt = 0;
+
+    NSTopicLL * iter = firstElement;
+
+    while (iter)
+    {
+        cnt++;
+        iter = iter->next;
+    }
+
+    return cnt;
+}
+
+NSResult NSRegisterTopic(const char * topicName)
+{
+    NS_LOG(DEBUG, "NSWriteTopicsToStorage()");
+
+    NSCacheTopicData * data = (NSCacheTopicData *) OICMalloc(sizeof(NSCacheTopicData));
+    NS_VERIFY_NOT_NULL(data, NS_FAIL);
+    data->topicName = (char *) topicName;
+    data->state = NS_TOPIC_UNSUBSCRIBED;
+
+    NSCacheElement * element = (NSCacheElement *) OICMalloc(sizeof(NSCacheElement));
+    if (!element)
+    {
+        NSOICFree(data->topicName);
+        NSOICFree(data);
+        return NS_FAIL;
+    }
+
+    element->data = (void *) data;
+    element->next = NULL;
+
+    if (NSProviderStorageWrite(registeredTopicList, element) != NS_OK)
+    {
+        NS_LOG(DEBUG, "fail to write cache");
+        return NS_FAIL;
+    }
+
+    NSSendTopicUpdation();
+    NS_LOG(DEBUG, "NSWriteTopicsToStorage() NS_OK");
+    return NS_OK;
+}
+
+NSResult NSUnregisterTopic(const char * topicName)
+{
+    NS_LOG(DEBUG, "NSDeleteTopics()");
+    NSResult result = NS_OK;
+
+    if (!topicName)
+    {
+        NS_LOG(ERROR, "topicName is NULL");
+        return NS_ERROR;
+    }
+
+    result = NSProviderStorageDelete(registeredTopicList, topicName);
+
+    while (NSProviderStorageDelete(consumerTopicList, topicName) != NS_FAIL)
+    {
+    }
+
+    if (result == NS_OK)
+    {
+        NSSendTopicUpdation();
+    }
+
+    return result;
+}
+
+NSResult NSSendTopicUpdation()
+{
+    NS_LOG(DEBUG, "NSSendTopicUpdation - IN");
+
+    OCRepPayload* payload = OCRepPayloadCreate();
+
+    if (!payload)
+    {
+        NS_LOG(ERROR, "fail to create playload");
+        return NS_ERROR;
+    }
+
+    OCResourceHandle rHandle = NULL;
+    if (NSPutMessageResource(NULL, &rHandle) != NS_OK)
+    {
+        NS_LOG(ERROR, "Fail to put message resource");
+        return NS_ERROR;
+    }
+
+    OCRepPayloadSetUri(payload, NS_COLLECTION_MESSAGE_URI);
+    OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, NS_TOPIC);
+    OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, NSGetProviderInfo()->providerId);
+
+    OCObservationId obArray[255] =
+    { 0, };
+    int obCount = 0;
+
+    NSCacheElement * it = consumerSubList->head;
+
+    while (it)
+    {
+        NSCacheSubData * subData = (NSCacheSubData *) it->data;
+
+        if (subData->isWhite)
+        {
+            if (subData->messageObId != 0)
+            {
+                obArray[obCount++] = subData->messageObId;
+            }
+
+#if (defined WITH_CLOUD)
+            if (subData->remote_messageObId != 0)
+            {
+                obArray[obCount++] = subData->remote_messageObId;
+            }
+#endif
+        }
+
+        it = it->next;
+    }
+
+    if (!obCount)
+    {
+        NS_LOG(ERROR, "observer count is zero");
+        return NS_ERROR;
+    }
+
+    if (OCNotifyListOfObservers(rHandle, obArray, obCount, payload, OC_HIGH_QOS) != OC_STACK_OK)
+    {
+        NS_LOG(ERROR, "fail to send topic updation");
+        OCRepPayloadDestroy(payload);
+        return NS_ERROR;
+
+    }
+    OCRepPayloadDestroy(payload);
+
+    NS_LOG(DEBUG, "NSSendTopicUpdation - OUT");
+    return NS_OK;
+}
+
+NSResult NSSendTopicUpdationToConsumer(char *consumerId)
+{
+    NS_LOG(DEBUG, "NSSendTopicUpdationToConsumer - IN");
+
+    OCRepPayload* payload = OCRepPayloadCreate();
+
+    if (!payload)
+    {
+        NS_LOG(ERROR, "fail to create playload");
+        return NS_ERROR;
+    }
+
+    OCResourceHandle rHandle = NULL;
+    if (NSPutMessageResource(NULL, &rHandle) != NS_OK)
+    {
+        NS_LOG(ERROR, "Fail to put message resource");
+        return NS_ERROR;
+    }
+
+    OCRepPayloadSetUri(payload, NS_COLLECTION_MESSAGE_URI);
+    OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, NS_TOPIC);
+    OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, NSGetProviderInfo()->providerId);
+
+    NSCacheElement * element = NSProviderStorageRead(consumerSubList, consumerId);
+
+    if (element == NULL)
+    {
+        NS_LOG(ERROR, "element is NULL");
+        return NS_ERROR;
+    }
+
+    NSCacheSubData * subData = (NSCacheSubData*) element->data;
+
+    if (OCNotifyListOfObservers(rHandle, (OCObservationId*) &subData->messageObId, 1, payload,
+            OC_HIGH_QOS) != OC_STACK_OK)
+    {
+        NS_LOG(ERROR, "fail to send topic updation");
+        OCRepPayloadDestroy(payload);
+        return NS_ERROR;
+    }
+
+    OCRepPayloadDestroy(payload);
+
+    NS_LOG(DEBUG, "NSSendTopicUpdationToConsumer - OUT");
+    return NS_OK;
+}
+
+NSResult NSSendTopicList(OCEntityHandlerRequest * entityHandlerRequest)
+{
+    NS_LOG(DEBUG, "NSSendTopicList - IN");
+
+    char * copyReq = OICStrdup(entityHandlerRequest->query);
+    char * id = NSGetValueFromQuery(copyReq, NS_QUERY_CONSUMER_ID);
+    NSTopicLL * topics = NULL;
+
+    if (!id)
+    {
+        NS_LOG(DEBUG, "Send registered topic list");
+        topics = NSProviderGetTopicsCacheData(registeredTopicList);
+    }
+    else
+    {
+        NS_LOG(DEBUG, "Send subscribed topic list to consumer");
+        topics = NSProviderGetConsumerTopicsCacheData(registeredTopicList, consumerTopicList, id);
+        if (!topics)
+        {
+            topics = NSProviderGetTopicsCacheData(registeredTopicList);
+        }
+    }
+
+    // make response for the Get Request
+    OCEntityHandlerResponse response;
+    response.numSendVendorSpecificHeaderOptions = 0;
+    memset(response.sendVendorSpecificHeaderOptions, 0,
+            sizeof response.sendVendorSpecificHeaderOptions);
+    memset(response.resourceUri, 0, sizeof response.resourceUri);
+
+    OCRepPayload* payload = OCRepPayloadCreate();
+    if (!payload)
+    {
+        NS_LOG(ERROR, "payload is NULL");
+        NSOICFree(copyReq);
+        return NS_ERROR;
+    }
+
+    OCRepPayloadSetUri(payload, NS_COLLECTION_TOPIC_URI);
+    if (id)
+    {
+        OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_CONSUMER_ID, id);
+    }
+    OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, NSGetProviderInfo()->providerId);
+    NSOICFree(copyReq);
+
+    if (topics)
+    {
+        NS_LOG(DEBUG, "topicList is NULL");
+        size_t dimensionSize = (size_t) NSProviderGetTopicListSize(topics);
+        NS_LOG_V(DEBUG, "dimensionSize = %d", (int)dimensionSize);
+
+        if (!dimensionSize)
+        {
+            return NS_ERROR;
+        }
+
+        OCRepPayload** payloadTopicArray = (OCRepPayload **) OICMalloc(
+                sizeof(OCRepPayload *) * dimensionSize);
+        NS_VERIFY_NOT_NULL(payloadTopicArray, NS_ERROR);
+
+        size_t dimensions[3] = { dimensionSize, 0, 0 };
+
+        for (int i = 0; i < (int) dimensionSize; i++)
+        {
+            NS_LOG_V(DEBUG, "topicName = %s", topics->topicName);
+            NS_LOG_V(DEBUG, "topicState = %d",(int) topics->state);
+
+            payloadTopicArray[i] = OCRepPayloadCreate();
+            NS_VERIFY_NOT_NULL(payloadTopicArray[i], NS_ERROR);
+            OCRepPayloadSetPropString(payloadTopicArray[i], NS_ATTRIBUTE_TOPIC_NAME,
+                    topics->topicName);
+            OCRepPayloadSetPropInt(payloadTopicArray[i], NS_ATTRIBUTE_TOPIC_SELECTION,
+                    (int) topics->state);
+
+            NSTopicLL * next = topics->next;
+            NSOICFree(topics->topicName);
+            NSOICFree(topics);
+            topics = next;
+        }
+
+        OCRepPayloadSetPropObjectArrayAsOwner(payload, NS_ATTRIBUTE_TOPIC_LIST,
+                    payloadTopicArray, dimensions);
+    }
+    else
+    {
+        size_t dimensions[3] = { 0, 0, 0 };
+
+        OCRepPayloadSetPropObjectArrayAsOwner(payload, NS_ATTRIBUTE_TOPIC_LIST,
+                (OCRepPayload **) NULL, dimensions);
+    }
+
+    copyReq = OICStrdup(entityHandlerRequest->query);
+    char * reqInterface = NSGetValueFromQuery(copyReq, NS_QUERY_INTERFACE);
+
+    if (reqInterface && strcmp(reqInterface, NS_INTERFACE_BASELINE) == 0)
+    {
+        OCResourcePayloadAddStringLL(&payload->interfaces, NS_INTERFACE_BASELINE);
+        OCResourcePayloadAddStringLL(&payload->interfaces, NS_INTERFACE_READ);
+        OCResourcePayloadAddStringLL(&payload->types, NS_ROOT_TYPE);
+    }
+
+    NSOICFree(copyReq);
+    response.requestHandle = entityHandlerRequest->requestHandle;
+    response.resourceHandle = entityHandlerRequest->resource;
+    response.persistentBufferFlag = 0;
+    response.ehResult = OC_EH_OK;
+    response.payload = (OCPayload *) payload;
+
+    if (OCDoResponse(&response) != OC_STACK_OK)
+    {
+        NS_LOG(ERROR, "Fail to response topic list");
+        OCRepPayloadDestroy(payload);
+        return NS_ERROR;
+    }
+
+    OCRepPayloadDestroy(payload);
+    NS_LOG(DEBUG, "NSSendTopicList - OUT");
+    return NS_OK;
+}
+
+NSResult NSPostConsumerTopics(OCEntityHandlerRequest * entityHandlerRequest)
+{
+    NS_LOG(DEBUG, "NSPostConsumerTopics() - IN");
+
+    char * consumerId = NULL;
+    OCRepPayload * payload = (OCRepPayload *) entityHandlerRequest->payload;
+    OCRepPayloadGetPropString(payload, NS_ATTRIBUTE_CONSUMER_ID, &consumerId);
+
+    if (!consumerId)
+    {
+        NS_LOG(DEBUG, "Invalid consumer ID");
+        return NS_FAIL;
+    }
+
+    NS_LOG_V(INFO_PRIVATE, "TOPIC consumer ID = %s", consumerId);
+
+    consumerTopicList->cacheType = NS_PROVIDER_CACHE_CONSUMER_TOPIC_CID;
+
+    while (NSProviderStorageDelete(consumerTopicList, consumerId) != NS_FAIL)
+    {
+    }
+
+    consumerTopicList->cacheType = NS_PROVIDER_CACHE_CONSUMER_TOPIC_NAME;
+    OCRepPayload ** topicListPayload = NULL;
+    OCRepPayloadValue * payloadValue = NULL;
+    payloadValue = NSPayloadFindValue(payload, NS_ATTRIBUTE_TOPIC_LIST);
+    size_t dimensionSize = calcDimTotal(payloadValue->arr.dimensions);
+    size_t dimensions[3] = { dimensionSize, 0, 0 };
+    OCRepPayloadGetPropObjectArray(payload, NS_ATTRIBUTE_TOPIC_LIST, &topicListPayload, dimensions);
+
+    for (int i = 0; i < (int) dimensionSize; i++)
+    {
+        char * topicName = NULL;
+        int64_t topicState = 0;
+
+        OCRepPayloadGetPropString(topicListPayload[i], NS_ATTRIBUTE_TOPIC_NAME, &topicName);
+        if (OCRepPayloadGetPropInt(topicListPayload[i], NS_ATTRIBUTE_TOPIC_SELECTION, &topicState))
+        {
+            NS_LOG_V(DEBUG, "Topic Name(state):  %s(%d)", topicName, (int)topicState);
+        }
+
+        if (NS_TOPIC_SUBSCRIBED == (NSTopicState) topicState)
+        {
+            NSCacheTopicSubData * topicSubData = (NSCacheTopicSubData *) OICMalloc(
+                    sizeof(NSCacheTopicSubData));
+            NS_VERIFY_NOT_NULL(topicSubData, NS_FAIL);
+
+            OICStrcpy(topicSubData->id, NS_UUID_STRING_SIZE, consumerId);
+            topicSubData->topicName = topicName;
+
+            NSCacheElement * newObj = (NSCacheElement *) OICMalloc(sizeof(NSCacheElement));
+
+            if (!newObj)
+            {
+                NSOICFree(topicSubData->topicName);
+                NSOICFree(topicSubData);
+                NSOICFree(consumerId);
+                return NS_FAIL;
+            }
+
+            newObj->data = (NSCacheData *) topicSubData;
+            newObj->next = NULL;
+
+            if (NS_OK != NSProviderStorageWrite(consumerTopicList, newObj))
+            {
+                NS_LOG(ERROR, "Fail to write cache");
+            }
+        }
+    }
+    NSSendTopicUpdationToConsumer(consumerId);
+    NSOICFree(consumerId);
+    NS_LOG(DEBUG, "NSPostConsumerTopics() - OUT");
+    return NS_OK;
+}
+
+void * NSTopicSchedule(void * ptr)
+{
+    if (ptr == NULL)
+    {
+        NS_LOG(DEBUG, "Create NSTopicSchedule");
+    }
+
+    while (NSIsRunning[TOPIC_SCHEDULER])
+    {
+        sem_wait(&NSSemaphore[TOPIC_SCHEDULER]);
+        pthread_mutex_lock(&NSMutex[TOPIC_SCHEDULER]);
+
+        if (NSHeadMsg[TOPIC_SCHEDULER] != NULL)
+        {
+            NSTask *node = NSHeadMsg[TOPIC_SCHEDULER];
+            NSHeadMsg[TOPIC_SCHEDULER] = node->nextTask;
+
+            switch (node->taskType)
+            {
+                case TASK_SEND_TOPICS:
+                    NS_LOG(DEBUG, "CASE TASK_SEND_TOPICS : ");
+                    NSSendTopicList((OCEntityHandlerRequest*) node->taskData);
+                    NSFreeOCEntityHandlerRequest((OCEntityHandlerRequest*) node->taskData);
+                    break;
+                case TASK_SUBSCRIBE_TOPIC:
+                {
+                    NS_LOG(DEBUG, "CASE TASK_SUBSCRIBE_TOPIC : ");
+                    NSTopicSyncResult * topicSyncResult = (NSTopicSyncResult *) node->taskData;
+                    pthread_mutex_lock(topicSyncResult->mutex);
+                    NSCacheElement * newObj = (NSCacheElement *) OICMalloc(sizeof(NSCacheElement));
+                    NSCacheTopicSubData * subData =
+                            (NSCacheTopicSubData *) topicSyncResult->topicData;
+                    if (!newObj)
+                    {
+                        NSOICFree(subData->topicName);
+                        NSOICFree(subData);
+                        pthread_cond_signal(topicSyncResult->condition);
+                        pthread_mutex_unlock(topicSyncResult->mutex);
+                    }
+                    else
+                    {
+                        if (NSProviderStorageRead(registeredTopicList, subData->topicName))
+                        {
+                            newObj->data = topicSyncResult->topicData;
+                            newObj->next = NULL;
+
+                            if (NSProviderStorageWrite(consumerTopicList, newObj) == NS_OK)
+                            {
+                                NSSendTopicUpdationToConsumer(subData->id);
+                                topicSyncResult->result = NS_OK;
+                            }
+                        }
+                        else
+                        {
+                            NSOICFree(subData->topicName);
+                            NSOICFree(subData);
+                            NSOICFree(newObj);
+                        }
+                    }
+                    pthread_cond_signal(topicSyncResult->condition);
+                    pthread_mutex_unlock(topicSyncResult->mutex);
+                }
+                    break;
+                case TASK_UNSUBSCRIBE_TOPIC:
+                {
+                    NS_LOG(DEBUG, "CASE TASK_UNSUBSCRIBE_TOPIC : ");
+                    NSTopicSyncResult * topicSyncResult = (NSTopicSyncResult *) node->taskData;
+                    pthread_mutex_lock(topicSyncResult->mutex);
+                    NSCacheTopicSubData * topicSubData =
+                            (NSCacheTopicSubData *) topicSyncResult->topicData;
+
+                    if (NSProviderDeleteConsumerTopic(consumerTopicList, topicSubData) == NS_OK)
+                    {
+                        NSSendTopicUpdationToConsumer(topicSubData->id);
+                        topicSyncResult->result = NS_OK;
+                    }
+
+                    NSOICFree(topicSubData->topicName);
+                    NSOICFree(topicSubData);
+                    pthread_cond_signal(topicSyncResult->condition);
+                    pthread_mutex_unlock(topicSyncResult->mutex);
+
+                }
+                    break;
+                case TASK_REGISTER_TOPIC:
+                {
+                    NS_LOG(DEBUG, "CASE TASK_ADD_TOPIC : ");
+                    NSTopicSyncResult * topicSyncResult = (NSTopicSyncResult *) node->taskData;
+
+                    pthread_mutex_lock(topicSyncResult->mutex);
+                    topicSyncResult->result = NSRegisterTopic(
+                            (const char *) topicSyncResult->topicData);
+                    pthread_cond_signal(topicSyncResult->condition);
+                    pthread_mutex_unlock(topicSyncResult->mutex);
+                }
+                    break;
+                case TASK_UNREGISTER_TOPIC:
+                {
+                    NS_LOG(DEBUG, "CASE_TASK_DELETE_TOPIC : ");
+                    NSTopicSyncResult * topicSyncResult = (NSTopicSyncResult *) node->taskData;
+                    pthread_mutex_lock(topicSyncResult->mutex);
+                    topicSyncResult->result = NSUnregisterTopic(
+                            (const char *) topicSyncResult->topicData);
+                    pthread_cond_signal(topicSyncResult->condition);
                     pthread_mutex_unlock(topicSyncResult->mutex);
-                }\r
-                    break;\r
-                case TASK_UNSUBSCRIBE_TOPIC:\r
-                {\r
-                    NS_LOG(DEBUG, "CASE TASK_UNSUBSCRIBE_TOPIC : ");\r
-                    NSTopicSyncResult * topicSyncResult = (NSTopicSyncResult *) node->taskData;\r
-                    pthread_mutex_lock(topicSyncResult->mutex);\r
-                    NSCacheTopicSubData * topicSubData =\r
-                            (NSCacheTopicSubData *) topicSyncResult->topicData;\r
-                    if (NSProviderDeleteConsumerTopic(consumerTopicList, topicSubData) == NS_OK)\r
-                    {\r
-                        NSSendTopicUpdationToConsumer(topicSubData->id);\r
-                        topicSyncResult->result = NS_OK;\r
-                    }\r
-                    OICFree(topicSubData->topicName);\r
-                    OICFree(topicSubData);\r
-                    pthread_cond_signal(topicSyncResult->condition);\r
-                    pthread_mutex_unlock(topicSyncResult->mutex);\r
-\r
-                }\r
-                    break;\r
-                case TASK_REGISTER_TOPIC:\r
-                {\r
-                    NS_LOG(DEBUG, "CASE TASK_ADD_TOPIC : ");\r
-                    NSTopicSyncResult * topicSyncResult = (NSTopicSyncResult *) node->taskData;\r
-\r
-                    pthread_mutex_lock(topicSyncResult->mutex);\r
-                    topicSyncResult->result = NSRegisterTopic(\r
-                            (const char *) topicSyncResult->topicData);\r
-                    pthread_cond_signal(topicSyncResult->condition);\r
-                    pthread_mutex_unlock(topicSyncResult->mutex);\r
-                }\r
-                    break;\r
-                case TASK_UNREGISTER_TOPIC:\r
-                {\r
-                    NS_LOG(DEBUG, "CASE_TASK_DELETE_TOPIC : ");\r
-                    NSTopicSyncResult * topicSyncResult = (NSTopicSyncResult *) node->taskData;\r
-                    pthread_mutex_lock(topicSyncResult->mutex);\r
-                    topicSyncResult->result = NSUnregisterTopic(\r
-                            (const char *) topicSyncResult->topicData);\r
-                    pthread_cond_signal(topicSyncResult->condition);\r
-                    pthread_mutex_unlock(topicSyncResult->mutex);\r
-                }\r
-                    break;\r
-                case TASK_POST_TOPIC:\r
-                {\r
-                    NS_LOG(DEBUG, "TASK_POST_TOPIC : ");\r
-                    NSPostConsumerTopics((OCEntityHandlerRequest*) node->taskData);\r
-                    NSFreeOCEntityHandlerRequest((OCEntityHandlerRequest*) node->taskData);\r
-                }\r
-                    break;\r
-                case TASK_GET_TOPICS:\r
-                {\r
-                    NS_LOG(DEBUG, "TASK_GET_TOPICS : ");\r
-                    NSTopicSync * topicSync = (NSTopicSync *) node->taskData;\r
-                    pthread_mutex_lock(topicSync->mutex);\r
-                    NSTopicLL * topics = NSProviderGetTopicsCacheData(registeredTopicList);\r
-                    topicSync->topics = topics;\r
-                    pthread_cond_signal(topicSync->condition);\r
-                    pthread_mutex_unlock(topicSync->mutex);\r
-                }\r
-                    break;\r
-                case TAST_GET_CONSUMER_TOPICS:\r
-                {\r
-                    NS_LOG(DEBUG, "TASK_GET_CONSUMER_TOPICS : ");\r
-                    NSTopicSync * topicSync = (NSTopicSync *) node->taskData;\r
-                    pthread_mutex_lock(topicSync->mutex);\r
-                    NSTopicLL * topics = NSProviderGetConsumerTopicsCacheData(registeredTopicList,\r
-                            consumerTopicList, topicSync->consumerId);\r
-                    topicSync->topics = topics;\r
-                    pthread_cond_signal(topicSync->condition);\r
-                    pthread_mutex_unlock(topicSync->mutex);\r
-                }\r
-                    break;\r
-                default:\r
-                    break;\r
-            }\r
-\r
-            OICFree(node);\r
-        }\r
-\r
-        pthread_mutex_unlock(&NSMutex[TOPIC_SCHEDULER]);\r
-    }\r
-\r
-    NS_LOG(DEBUG, "Destroy NSTopicSchedule");\r
-    return NULL;\r
-}\r
+                }
+                    break;
+                case TASK_POST_TOPIC:
+                {
+                    NS_LOG(DEBUG, "TASK_POST_TOPIC : ");
+                    NSPostConsumerTopics((OCEntityHandlerRequest*) node->taskData);
+                    NSFreeOCEntityHandlerRequest((OCEntityHandlerRequest*) node->taskData);
+                }
+                    break;
+                case TASK_GET_TOPICS:
+                {
+                    NS_LOG(DEBUG, "TASK_GET_TOPICS : ");
+                    NSTopicSync * topicSync = (NSTopicSync *) node->taskData;
+                    pthread_mutex_lock(topicSync->mutex);
+                    NSTopicLL * topics = NSProviderGetTopicsCacheData(registeredTopicList);
+                    topicSync->topics = topics;
+                    pthread_cond_signal(topicSync->condition);
+                    pthread_mutex_unlock(topicSync->mutex);
+                }
+                    break;
+                case TAST_GET_CONSUMER_TOPICS:
+                {
+                    NS_LOG(DEBUG, "TASK_GET_CONSUMER_TOPICS : ");
+                    NSTopicSync * topicSync = (NSTopicSync *) node->taskData;
+                    pthread_mutex_lock(topicSync->mutex);
+                    NSTopicLL * topics = NSProviderGetConsumerTopicsCacheData(registeredTopicList,
+                            consumerTopicList, topicSync->consumerId);
+                    topicSync->topics = topics;
+                    pthread_cond_signal(topicSync->condition);
+                    pthread_mutex_unlock(topicSync->mutex);
+                }
+                    break;
+                default:
+                    break;
+            }
+
+            NSOICFree(node);
+        }
+
+        pthread_mutex_unlock(&NSMutex[TOPIC_SCHEDULER]);
+    }
+
+    NS_LOG(DEBUG, "Destroy NSTopicSchedule");
+    return NULL;
+}
index 1a7a8ff..161a9ee 100644 (file)
@@ -53,7 +53,7 @@ public:
 
     void findProvider()
     {
-        OC::OCPlatform::findResource("", std::string("/oic/res?rt=oic.wk.notification"),
+        OC::OCPlatform::findResource("", std::string("/oic/res?rt=x.org.iotivity.notification"),
                 OCConnectivityType::CT_DEFAULT,
                 std::bind(&NSConsumerSimulator::findResultCallback, this, std::placeholders::_1),
                 OC::QualityOfService::LowQos);
@@ -67,9 +67,9 @@ public:
         }
 
         OC::OCRepresentation rep;
-        rep.setValue("providerid", providerID);
-        rep.setValue("messageid", id);
-        rep.setValue("state", type);
+        rep.setValue("x.org.iotivity.ns.providerid", providerID);
+        rep.setValue("x.org.iotivity.ns.messageid", id);
+        rep.setValue("x.org.iotivity.ns.state", type);
 
         m_syncResource->post(rep, OC::QueryParamsMap(), &onPost, OC::QualityOfService::LowQos);
     }
@@ -99,7 +99,7 @@ private:
     {
         if(resource->uri() == "/notification")
         {
-            resource->get(std::string("oic.wk.notification"), std::string("oic.if.baseline"),
+            resource->get(std::string("x.org.iotivity.notification"), std::string("oic.if.baseline"),
                     OC::QueryParamsMap(), std::bind(&NSConsumerSimulator::onGet, this,
                             std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
                             resource), OC::QualityOfService::LowQos);
@@ -110,12 +110,12 @@ private:
             std::shared_ptr<OC::OCResource> resource)
     {
         OC::QueryParamsMap map;
-        map.insert(std::pair<std::string,std::string>(std::string("consumerid"),
+        map.insert(std::pair<std::string,std::string>(std::string("x.org.iotivity.ns.consumerid"),
                 std::string("123456789012345678901234567890123456")));
 
         try
         {
-            std::vector<std::string> rts{"oic.wk.notification"};
+            std::vector<std::string> rts{"x.org.iotivity.notification"};
 
             m_msgResource
                 = OC::OCPlatform::constructResourceObject(
@@ -155,17 +155,17 @@ private:
             const OC::OCRepresentation &rep , const int & /*eCode*/, const int &,
             std::shared_ptr<OC::OCResource> )
     {
-        if (rep.getUri() == "/notification/message" && rep.hasAttribute("messageid")
-                && rep.getValue<int>("messageid") != 1)
+        if (rep.getUri() == "/notification/message" && rep.hasAttribute("x.org.iotivity.ns.messageid")
+                && rep.getValue<int>("x.org.iotivity.ns.messageid") != 1)
         {
-            m_messageFunc(int(rep.getValue<int>("messageid")),
-                          std::string(rep.getValueToString("title")),
-                          std::string(rep.getValueToString("contenttext")),
-                          std::string(rep.getValueToString("source")));
+            m_messageFunc(int(rep.getValue<int>("x.org.iotivity.ns.messageid")),
+                          std::string(rep.getValueToString("x.org.iotivity.ns.title")),
+                          std::string(rep.getValueToString("x.org.iotivity.ns.contenttext")),
+                          std::string(rep.getValueToString("x.org.iotivity.ns.source")));
 
-            if(rep.getValue<int>("messageid") == 3)
+            if(rep.getValue<int>("x.org.iotivity.ns.messageid") == 3)
             {
-                m_topicResource->get(std::string("oic.wk.notification"),
+                m_topicResource->get(std::string("x.org.iotivity.notification"),
                         std::string("oic.if.baseline"), OC::QueryParamsMap(),
                         std::bind(&NSConsumerSimulator::onTopicGet, this, std::placeholders::_1,
                                 std::placeholders::_2, std::placeholders::_3, m_topicResource),
@@ -174,7 +174,7 @@ private:
         }
         else if (rep.getUri() == "/notification/sync")
         {
-            m_syncFunc(int(rep.getValue<int>("state")), int(rep.getValue<int>("messageid")));
+            m_syncFunc(int(rep.getValue<int>("x.org.iotivity.ns.state")), int(rep.getValue<int>("x.org.iotivity.ns.messageid")));
         }
     }
 
@@ -189,7 +189,7 @@ private:
             OC::OCRepresentation postRep;
 
             std::vector<OC::OCRepresentation> topicArr =
-                            rep.getValue<std::vector<OC::OCRepresentation>>("topiclist");
+                            rep.getValue<std::vector<OC::OCRepresentation>>("x.org.iotivity.ns.topiclist");
 
             std::vector<OC::OCRepresentation> postTopicArr;
 
@@ -200,8 +200,8 @@ private:
                 OC::OCRepresentation topic = *it;
                 OC::OCRepresentation postTopic;
 
-                postTopic.setValue("topicname", topic.getValueToString("topicname"));
-                postTopic.setValue("topicstate", (int) topic.getValue<int>("topicstate"));
+                postTopic.setValue("x.org.iotivity.ns.topicname", topic.getValueToString("x.org.iotivity.ns.topicname"));
+                postTopic.setValue("x.org.iotivity.ns.topicstate", (int) topic.getValue<int>("x.org.iotivity.ns.topicstate"));
 
                 postTopicArr.push_back(topic);
 
@@ -210,10 +210,10 @@ private:
             }
 
             postRep.setValue<std::vector<OC::OCRepresentation>>
-                ("topiclist", postTopicArr);
+                ("x.org.iotivity.ns.topiclist", postTopicArr);
 
             OC::QueryParamsMap map;
-            map.insert(std::pair<std::string,std::string>(std::string("consumerid"),
+            map.insert(std::pair<std::string,std::string>(std::string("x.org.iotivity.ns.consumerid"),
                     std::string("123456789012345678901234567890123456")));
             m_topicResource->post(postRep, map, &onPost, OC::QualityOfService::LowQos);
         }
index 0a262cd..eebae7e 100644 (file)
@@ -124,11 +124,11 @@ private:
                     std::string syncUri = m_notificationUri + m_syncUri;
                     std::string topicUri = m_notificationUri + m_topicUri;
                     std::string providerId = "123456789012345678901234567890123456";
-                    rep.setValue("subcontrollability", m_accepter);
-                    rep.setValue("messageuri", msgUri);
-                    rep.setValue("syncuri", syncUri);
-                    rep.setValue("topicuri", topicUri);
-                    rep.setValue("providerid", providerId);
+                    rep.setValue("x.org.iotivity.ns.subcontrollability", m_accepter);
+                    rep.setValue("x.org.iotivity.ns.messageuri", msgUri);
+                    rep.setValue("x.org.iotivity.ns.syncuri", syncUri);
+                    rep.setValue("x.org.iotivity.ns.topicuri", topicUri);
+                    rep.setValue("x.org.iotivity.ns.providerid", providerId);
                 }
                 else if (type == requestType::NS_SYNC)
                 {
@@ -158,14 +158,14 @@ private:
                         [& topicArr](const NS_TopicState & topicState)
                         {
                             OC::OCRepresentation topic;
-                            topic.setValue("topicname", topicState.first);
-                            topic.setValue("topicstate", (int) topicState.second);
+                            topic.setValue("x.org.iotivity.ns.topicname", topicState.first);
+                            topic.setValue("x.org.iotivity.ns.topicstate", (int) topicState.second);
                             topicArr.push_back(topic);
                         }
                     );
 
                     rep.setValue<std::vector<OC::OCRepresentation>>
-                        ("topiclist", topicArr);
+                        ("x.org.iotivity.ns.topiclist", topicArr);
                 }
                 else
                 {
@@ -183,8 +183,8 @@ private:
                     m_syncRep = requests->getResourceRepresentation();
 
                     std::cout << "Receive POST for Sync" << std::endl;
-                    std::cout << "provider Id : " << m_syncRep.getValueToString("providerid") << std::endl;
-                    std::cout << "Sync State : " << m_syncRep.getValueToString("state") << std::endl;
+                    std::cout << "provider Id : " << m_syncRep.getValueToString("x.org.iotivity.ns.providerid") << std::endl;
+                    std::cout << "Sync State : " << m_syncRep.getValueToString("x.org.iotivity.ns.state") << std::endl;
 
                     response->setResourceRepresentation(m_syncRep);
 
@@ -196,15 +196,15 @@ private:
                 {
                     auto receivePayload =
                             requests->getResourceRepresentation()
-                            .getValue<std::vector<OC::OCRepresentation>>("topiclist");
+                            .getValue<std::vector<OC::OCRepresentation>>("x.org.iotivity.ns.topiclist");
 
                     std::for_each (receivePayload.begin(), receivePayload.end(),
                           [this](const OC::OCRepresentation & rep)
                           {
-                              auto tmp = m_allowedTopicList.find(rep.getValueToString("topicname"));
+                              auto tmp = m_allowedTopicList.find(rep.getValueToString("x.org.iotivity.ns.topicname"));
                               if (tmp != m_allowedTopicList.end())
                               {
-                                  tmp->second = (TopicAllowState) rep.getValue<int>("topicstate");
+                                  tmp->second = (TopicAllowState) rep.getValue<int>("x.org.iotivity.ns.topicstate");
                               }
                           }
                     );
@@ -235,8 +235,8 @@ private:
         {
             OC::OCRepresentation rep;
             std::string providerId = "123456789012345678901234567890123456";
-            rep.setValue<int>("messageid", (int)messageType::NS_ALLOW);
-            rep.setValue("providerid", providerId);
+            rep.setValue<int>("x.org.iotivity.ns.messageid", (int)messageType::NS_ALLOW);
+            rep.setValue("x.org.iotivity.ns.providerid", providerId);
 
             auto response = std::make_shared<OC::OCResourceResponse>();
             response->setRequestHandle(requests->getRequestHandle());
@@ -308,27 +308,27 @@ public:
     void sendRead(const uint64_t & id)
     {
         std::string providerId = "123456789012345678901234567890123456";
-        m_syncRep.setValue<int>("messageid", id);
-        m_syncRep.setValue("state", (int)1);
-        m_syncRep.setValue("providerid", providerId);
+        m_syncRep.setValue<int>("x.org.iotivity.ns.messageid", id);
+        m_syncRep.setValue("x.org.iotivity.ns.state", (int)1);
+        m_syncRep.setValue("x.org.iotivity.ns.providerid", providerId);
         OC::OCPlatform::notifyAllObservers(m_syncHandle);
     }
     void sendDismiss(const uint64_t & id)
     {
         std::string providerId = "123456789012345678901234567890123456";
-        m_syncRep.setValue<int>("messageid", id);
-        m_syncRep.setValue("state", (int)2);
-        m_syncRep.setValue("providerid", providerId);
+        m_syncRep.setValue<int>("x.org.iotivity.ns.messageid", id);
+        m_syncRep.setValue("x.org.iotivity.ns.state", (int)2);
+        m_syncRep.setValue("x.org.iotivity.ns.providerid", providerId);
         OC::OCPlatform::notifyAllObservers(m_syncHandle);
     }
 
     void setMessage(const uint64_t & id, const std::string & title, const std::string & content)
     {
         std::string providerId = "123456789012345678901234567890123456";
-        m_messageRep.setValue<int>("messageid", id);
-        m_messageRep.setValue("title", title);
-        m_messageRep.setValue("contenttext", content);
-        m_messageRep.setValue("providerid", providerId);
+        m_messageRep.setValue<int>("x.org.iotivity.ns.messageid", id);
+        m_messageRep.setValue<std::string>("x.org.iotivity.ns.title", title);
+        m_messageRep.setValue<std::string>("x.org.iotivity.ns.contenttext", content);
+        m_messageRep.setValue<std::string>("x.org.iotivity.ns.providerid", providerId);
     }
 
     void setTopics(const NS_TopicList & topics)
@@ -400,7 +400,7 @@ public:
         OC::OCPlatform::startPresence(30);
 
         std::string notificationUri = m_notificationUri;
-        std::string resourceTypeName = "oic.wk.notification.topic";
+        std::string resourceTypeName = "x.org.iotivity.notification.topic";
         std::string resourceInterface = OC::DEFAULT_INTERFACE;
 
         uint8_t resourceProperty = OC_OBSERVABLE;
@@ -420,7 +420,7 @@ public:
         }
 
         //resourceProperty |= OC_OBSERVABLE;
-        resourceTypeName = "oic.wk.notification.message";
+        resourceTypeName = "x.org.iotivity.notification.message";
         childUri = uri + m_messageUri;
         try
         {
@@ -436,7 +436,7 @@ public:
             std::cout << e.what() << std::endl;
         }
 
-        resourceTypeName = "oic.wk.notification.sync";
+        resourceTypeName = "x.org.iotivity.notification.sync";
         childUri = uri + m_syncUri;
         try
         {
@@ -453,7 +453,7 @@ public:
         }
 
         resourceProperty |= OC_DISCOVERABLE;
-        resourceTypeName = "oic.wk.notification";
+        resourceTypeName = "x.org.iotivity.notification";
         try
         {
             OC::OCPlatform::registerResource(
index 7312159..fc30637 100644 (file)
@@ -53,7 +53,7 @@ GTest_Main = File(gtest_dir + '/lib/.libs/libgtest_main.a')
 
 notification_test_env.AppendUnique(LIBPATH = [lib_env.get('BUILD_DIR')])
 notification_test_env.AppendUnique(LIBS = [
-    'connectivity_abstraction', 'oc', 'octbstack', 'oc_logger', 'coap',
+    'connectivity_abstraction', 'oc', 'octbstack', 'oc_logger', 'coap', 'resource_directory',
     GTest_Main, GTest])
 
 if target_os not in ['windows', 'winrt']:
@@ -104,3 +104,4 @@ if env.get('TEST') == '1':
                      '',
 #                    'service_notification_unittest_notification_provider_test.memcheck',
                      'service/notification/unittest/notification_provider_test')
+
index 6bf73e1..53e96cf 100644 (file)
@@ -52,7 +52,7 @@ BMISensor::~BMISensor()
 int BMISensor::executeBMISensorLogic(std::map<std::string, std::string> *pInputData,
                                      std::string *pOutput)
 {
-    BMIResult result;
+    BMIResult result = ERROR;
 
     if (pInputData->find("weight") != pInputData->end())
     {
@@ -81,10 +81,12 @@ int BMISensor::executeBMISensorLogic(std::map<std::string, std::string> *pInputD
  */
 BMIResult BMISensor::makeBMI(void)
 {
-    double BMIvalue, timediffsecond;
-    double dWeight, dHeight;
+    double BMIvalue = 0.0;
+    double timediffsecond = 0.0;
+    double dWeight = 0.0;
+    double dHeight = 0.0;
 
-    int BMIResult;
+    int BMIResult = 0;
 
     if (!m_weight.empty() && !m_height.empty())
     {
@@ -147,4 +149,4 @@ BMIResult BMISensor::makeBMI(void)
     }
 
     return ERROR;
-}
\ No newline at end of file
+}
index 801f8b9..971d43a 100644 (file)
@@ -52,7 +52,7 @@ OCResourceHandle HeightResource::getHandle()
 
 void HeightResource::setResourceRepresentation(OCRepresentation &rep)
 {
-    double tempHeight;
+    double tempHeight = 0.0;
 
     rep.getValue("height", tempHeight);
 
@@ -80,7 +80,7 @@ void *TestSensorVal(void *param)
 
     bool bFlag = true;
     int nSleep_time = INTERVAL_FOR_CHECK;
-    double nHeight;
+    double nHeight = 0.0;
 
     std::cout << "[HeightSensorAPP] ::" << __func__ << " is called."
               << std::endl;
@@ -181,7 +181,7 @@ OCEntityHandlerResult entityHandler(std::shared_ptr< OCResourceRequest > request
 
         if (requestFlag & RequestHandlerFlag::ObserverFlag)
         {
-            pthread_t threadId;
+            pthread_t threadId = {};
 
             cout << "\t\trequestFlag : Observer\n";
             g_Observation = 1;
@@ -222,7 +222,7 @@ int main()
 
         OC::OCPlatform::stopPresence();
     }
-    catch (std::exception e)
+    catch (std::exception e)
     {
         cout << e.what() << endl;
     }
index 2cf051b..e9c21e2 100644 (file)
@@ -53,7 +53,7 @@ OCResourceHandle WeightResource::getHandle()
 
 void WeightResource::setResourceRepresentation(OCRepresentation &rep)
 {
-    double tempWeight;
+    double tempWeight = 0.0;
 
     rep.getValue("weight", tempWeight);
 
@@ -80,7 +80,7 @@ void *TestSensorVal(void *param)
 
     bool bFlag = true;
     int nSleep_time = INTERVAL_FOR_CHECK;
-    double nWeight;
+    double nWeight = 0.0;
 
     std::cout << "[WeightSensorAPP] ::" << __func__ << " is called."
               << std::endl;
@@ -182,7 +182,7 @@ OCEntityHandlerResult entityHandler(std::shared_ptr< OCResourceRequest > request
 
         if (requestFlag & RequestHandlerFlag::ObserverFlag)
         {
-            pthread_t threadId;
+            pthread_t threadId = {};
 
             cout << "\t\trequestFlag : Observer\n";
             g_Observation = 1;
index 4d1c2df..32397b7 100644 (file)
@@ -68,7 +68,7 @@ RCSResourceContainer *g_pResourceContainer = nullptr;
 
 void getCurrentPath(std::string *pPath)
 {
-    char buffer[MAX_PATH];
+    char buffer[MAX_PATH] = {0,};
 
     if (!pPath->empty())
     {
@@ -95,7 +95,7 @@ void getCurrentPath(std::string *pPath)
 
 int processUserInput(int min, int max)
 {
-    int input;
+    int input = 0;
 
     std::cin >> input;
 
index d4d2729..60993a8 100644 (file)
@@ -717,9 +717,9 @@ int main(int argc, char *argv[])
         cv.wait(lock);
 
     }
-    catch (OCException &e)
+    catch (const OCException &e)
     {
-        oclog() << "Exception in main: " << e.what();
+        std::cout << "Exception in main: " << e.what();
     }
 
     return 0;
index 5da9ebb..7fd0309 100644 (file)
@@ -51,7 +51,7 @@ int DiscomfortIndexSensor::executeDISensorLogic(std::map<std::string, std::strin
     std::cout << "[DiscomfortIndexSensor] DiscomfortIndexSensor::" << __func__ << " is called."
               << std::endl;
 
-    DIResult result;
+    DIResult result = ERROR;
 
     m_temperature = pInputData->at("temperature");
     m_humidity = pInputData->at("humidity");
@@ -116,4 +116,4 @@ DIResult DiscomfortIndexSensor::makeDiscomfortIndex()
     m_discomfortIndex = std::to_string(DILevel);
 
     return SUCCESS;
-}
\ No newline at end of file
+}
index 2f6f857..e98ce5f 100644 (file)
@@ -66,8 +66,8 @@ void DiscomfortIndexSensorResource::executeLogic()
 void DiscomfortIndexSensorResource::onUpdatedInputResource(const std::string attributeName,
         std::vector<RCSResourceAttributes::Value> values)
 {
-    double sum = 0;
-    double dConvert;
+    double sum = 0.0;
+    double dConvert = 0.0;
     int inputCount = 0;
     std::string itString;
 
@@ -80,7 +80,11 @@ void DiscomfortIndexSensorResource::onUpdatedInputResource(const std::string att
         ++inputCount;
     }
 
-    double result = sum / inputCount;
+    double result = 0.0;
+    if (inputCount)
+    {
+        result = sum / inputCount;
+    }
     std::string indexCount;//string which will contain the indexCount
     std::stringstream convert; // stringstream used for the conversion
     convert << result;//add the value of Number to the characters in the stream
index 2161f0e..2f39fb6 100644 (file)
@@ -59,8 +59,8 @@ OCResourceHandle TemphumidResource::getHandle()
 
 void TemphumidResource::setResourceRepresentation(OCRepresentation &rep)
 {
-    int tempHumid;
-    int tempTemp;
+    int tempHumid = 0;
+    int tempTemp = 0;
 
     rep.getValue("humidity", tempTemp);
     rep.getValue("temperature", tempHumid);
@@ -173,7 +173,7 @@ OCEntityHandlerResult entityHandler(std::shared_ptr< OCResourceRequest > request
 
         if (requestFlag & RequestHandlerFlag::ObserverFlag)
         {
-            pthread_t threadId;
+            pthread_t threadId = {};
 
             cout << "\t\trequestFlag : Observer\n";
             g_Observation = 1;
@@ -214,7 +214,7 @@ int main()
 
         OC::OCPlatform::stopPresence();
     }
-    catch (std::exception e)
+    catch (std::exception e)
     {
         cout << e.what() << endl;
     }
index 6f2645e..9806e19 100644 (file)
@@ -60,8 +60,8 @@ OCResourceHandle TemphumidResource::getHandle()
 
 void TemphumidResource::setResourceRepresentation(OCRepresentation &rep)
 {
-    int tempHumid;
-    int tempTemp;
+    int tempHumid = 0;
+    int tempTemp = 0;
 
     rep.getValue("humidity", tempTemp);
     rep.getValue("temperature", tempHumid);
@@ -172,7 +172,7 @@ OCEntityHandlerResult entityHandler(std::shared_ptr< OCResourceRequest > request
 
         if (requestFlag & RequestHandlerFlag::ObserverFlag)
         {
-            pthread_t threadId;
+            pthread_t threadId = {};
 
             cout << "\t\trequestFlag : Observer\n";
             g_Observation = 1;
@@ -213,7 +213,7 @@ int main()
 
         OC::OCPlatform::stopPresence();
     }
-    catch (std::exception e)
+    catch (std::exception e)
     {
         cout << e.what() << endl;
     }
index de7121b..297faa1 100644 (file)
@@ -68,8 +68,8 @@ void HueConnector::disconnect()
 std::string HueConnector::transmit(std::string target, std::string payload)
 {
     std::cout << "Transmitting to " << target << " " << payload << endl;
-    CURL *curl;
-    CURLcode res;
+    CURL *curl = NULL;
+    CURLcode res = CURLE_OK;
     struct curl_slist *headers = NULL; /* http headers to send with request */
     /* set content type */
     headers = curl_slist_append(headers, "Accept: application/json");
@@ -114,8 +114,8 @@ static int writer(char *data, size_t size, size_t nmemb, std::string *buffer_in)
 std::string HueConnector::read(std::string target)
 {
     std::cout << "Reading from to " << target << endl;
-    CURL *curl;
-    CURLcode res;
+    CURL *curl = NULL;
+    CURLcode res = CURLE_OK;
     struct curl_slist *headers = NULL; /* http headers to send with request */
     /* set content type */
     headers = curl_slist_append(headers, "Accept: application/json");
index fc5e1ae..3a7fd95 100644 (file)
@@ -87,8 +87,8 @@ namespace OIC
 
         void Configuration::getConfiguredBundles(configInfo *configOutput)
         {
-            rapidxml::xml_node< char > *bundle;
-            rapidxml::xml_node< char > *subItem;
+            rapidxml::xml_node< char > *bundle = nullptr;
+            rapidxml::xml_node< char > *subItem = nullptr;
 
             string strKey, strValue;
 
@@ -130,7 +130,7 @@ namespace OIC
 
         void Configuration::getBundleConfiguration(string bundleId, configInfo *configOutput)
         {
-            rapidxml::xml_node< char > *bundle;
+            rapidxml::xml_node< char > *bundle = nullptr;
 
             string strBundleId, strPath, strVersion;
 
@@ -202,9 +202,11 @@ namespace OIC
         void Configuration::getResourceConfiguration(std::string bundleId, std::string resourceUri,
                         resourceInfo *resourceInfoOut)
         {
-            rapidxml::xml_node< char > *bundle;
-            rapidxml::xml_node< char > *resource;
-            rapidxml::xml_node< char > *item, *subItem, *subItem2;
+            rapidxml::xml_node< char > *bundle = nullptr;
+            rapidxml::xml_node< char > *resource = nullptr;
+            rapidxml::xml_node< char > *item = nullptr;
+            rapidxml::xml_node< char > *subItem = nullptr;
+            rapidxml::xml_node< char > *subItem2 = nullptr;
 
             string strBundleId;
             string strKey, strValue;
@@ -327,9 +329,11 @@ namespace OIC
         void Configuration::getResourceConfiguration(std::string bundleId,
                 std::vector< resourceInfo > *configOutput)
         {
-            rapidxml::xml_node< char > *bundle;
-            rapidxml::xml_node< char > *resource;
-            rapidxml::xml_node< char > *item, *subItem, *subItem2;
+            rapidxml::xml_node< char > *bundle = nullptr;
+            rapidxml::xml_node< char > *resource = nullptr;
+            rapidxml::xml_node< char > *item = nullptr;
+            rapidxml::xml_node< char > *subItem = nullptr;
+            rapidxml::xml_node< char > *subItem2 = nullptr;
 
             string strBundleId;
             string strKey, strValue;
@@ -347,7 +351,10 @@ namespace OIC
                                  bundle->next_sibling())
                         {
                             // <id>
-                            strBundleId = bundle->first_node(BUNDLE_ID)->value();
+                            if (bundle->first_node(BUNDLE_ID))
+                            {
+                                strBundleId = bundle->first_node(BUNDLE_ID)->value();
+                            }
 
                             OIC_LOG_V(INFO, CONTAINER_TAG, "Comparing bundle ids %s - %s !",
                                     strBundleId.c_str(), bundleId.c_str());
index 922d515..6c7aeb3 100644 (file)
@@ -30,7 +30,7 @@ RemoteResourceUnit::RemoteResourceUnit()
     pStateChangedCB = std::bind(&RemoteResourceUnit::stateChangedCB, this,
                         std::placeholders::_1);
     pCacheUpdateCB = std::bind(&RemoteResourceUnit::cacheUpdateCB, this,
-                    std::placeholders::_1);
+                    std::placeholders::_1, std::placeholders::_2);
 }
 
 RemoteResourceUnit::~RemoteResourceUnit()
@@ -115,7 +115,7 @@ void RemoteResourceUnit::stateChangedCB(ResourceState changedState) const
     }
 }
 
-void RemoteResourceUnit::cacheUpdateCB(const RCSResourceAttributes & updatedAtt) const
+void RemoteResourceUnit::cacheUpdateCB(const RCSResourceAttributes & updatedAtt, int) const
 {
     std::lock_guard<std::mutex> lock(m_mutex);
     (void)updatedAtt;
index 272f576..4444449 100644 (file)
@@ -54,7 +54,7 @@ namespace OIC
             RCSRemoteResourceObject::CacheUpdatedCallback pCacheUpdateCB;
 
             void stateChangedCB(ResourceState changedState) const;
-            void cacheUpdateCB(const RCSResourceAttributes & updatedAtt) const;
+            void cacheUpdateCB(const RCSResourceAttributes & updatedAtt, int) const;
 
         public:
             static RemoteResourceUnit::Ptr createRemoteResourceInfo(
index e22692d..099acd5 100644 (file)
@@ -270,7 +270,7 @@ namespace OIC
             OIC_LOG_V(INFO, CONTAINER_TAG, "Unregister bundle: (%s)",
                      std::string(m_bundles[id]->getID()).c_str());
 
-            const char *error;
+            const char *error = NULL;
             dlclose(bundleHandle);
 
             if ((error = dlerror()) != NULL)
@@ -690,7 +690,7 @@ namespace OIC
         void ResourceContainerImpl::registerSoBundle(shared_ptr<RCSBundleInfo> bundleInfo)
         {
             OIC_LOG_V(DEBUG, CONTAINER_TAG, "Register SO bundle");
-            const char *error;
+            const char *error = NULL;
 
             activator_t *bundleActivator = NULL;
             deactivator_t *bundleDeactivator = NULL;
@@ -943,7 +943,7 @@ namespace OIC
         void ResourceContainerImpl::addSoBundleResource(const std::string &bundleId,
                 resourceInfo newResourceInfo)
         {
-            resourceCreator_t *resourceCreator;
+            resourceCreator_t *resourceCreator = nullptr;
 
             resourceCreator = m_bundles[bundleId]->getResourceCreator();
 
index 63100fa..423e8e1 100644 (file)
@@ -48,7 +48,7 @@ string CONFIG_FILE = "ResourceContainerTestConfig.xml";
 
 void getCurrentPath(std::string *pPath)
 {
-    char buffer[MAX_PATH];
+    char buffer[MAX_PATH] = {0,};
 
 #if defined(__linux__)
     char *strPath = NULL;
@@ -735,7 +735,7 @@ TEST_F(DiscoverResourceUnitTest, onUpdateCalled)
 
 namespace
 {
-    void onCacheCB(const RCSResourceAttributes &)
+    void onCacheCB(const RCSResourceAttributes &, int)
     {
     }
 }
@@ -814,7 +814,7 @@ TEST_F(RemoteResourceUnitTest, onCacheCBCalled)
 {
     bool isCalled = false;
     mocks.ExpectCallFunc(onCacheCB).Do(
-        [this, &isCalled](const RCSResourceAttributes &)
+        [this, &isCalled](const RCSResourceAttributes &, int)
     {
         isCalled = true;
     });
index 85b45d5..b09b8ee 100644 (file)
@@ -121,7 +121,7 @@ resourceClient_env.UserInstallTargetHeader('include/RCSSeparateResponse.h', 'ser
 ######################################################################
 # Build Sample App: SampleResourceClient & SampleResourceServer
 ######################################################################
-SConscript('examples/SConscript')
+#SConscript('examples/SConscript')
 
 ######################################################################
 # Build UnitTests Resource Client , resourceCache and resourceBroker and 
diff --git a/service/resource-encapsulation/android/service/src/main/java/org/iotivity/service/RcsByteString.java b/service/resource-encapsulation/android/service/src/main/java/org/iotivity/service/RcsByteString.java
new file mode 100644 (file)
index 0000000..e02ad74
--- /dev/null
@@ -0,0 +1,23 @@
+package org.iotivity.service;
+
+/**
+ * This Class represents byte string value for RcsResourceAttributes.
+ */
+public class RcsByteString {
+
+    private byte[] mData;
+    private long mSize;
+
+    public RcsByteString(byte[] data, long size) {
+        this.mData = data;
+        this.mSize =  size;
+    }
+
+    public byte[] getValue() {
+        return this.mData;
+    }
+
+    public long getSize() {
+        return this.mSize;
+    }
+}
\ No newline at end of file
index e1fd331..a9edc82 100644 (file)
@@ -47,7 +47,7 @@ public final class RcsValue {
      * @see Type
      */
     public static enum TypeId {
-        NULL, BOOLEAN, INTEGER, DOUBLE, STRING, ATTRIBUTES, ARRAY;
+        NULL, BOOLEAN, INTEGER, DOUBLE, STRING, BYTESTRING, ATTRIBUTES, ARRAY;
     }
 
     /**
@@ -189,12 +189,14 @@ public final class RcsValue {
         types.put(Integer.class, new Type(TypeId.INTEGER));
         types.put(Double.class, new Type(TypeId.DOUBLE));
         types.put(String.class, new Type(TypeId.STRING));
+        types.put(RcsByteString.class, new Type(TypeId.BYTESTRING));
         types.put(RcsResourceAttributes.class, new Type(TypeId.ATTRIBUTES));
 
         types.put(boolean[].class, new ArrayType(TypeId.BOOLEAN, 1));
         types.put(int[].class, new ArrayType(TypeId.INTEGER, 1));
         types.put(double[].class, new ArrayType(TypeId.DOUBLE, 1));
         types.put(String[].class, new ArrayType(TypeId.STRING, 1));
+        types.put(RcsByteString[].class, new ArrayType(TypeId.BYTESTRING, 1));
         types.put(RcsResourceAttributes[].class,
                 new ArrayType(TypeId.ATTRIBUTES, 1));
 
@@ -202,6 +204,7 @@ public final class RcsValue {
         types.put(int[][].class, new ArrayType(TypeId.INTEGER, 2));
         types.put(double[][].class, new ArrayType(TypeId.DOUBLE, 2));
         types.put(String[][].class, new ArrayType(TypeId.STRING, 2));
+        types.put(RcsByteString[][].class, new ArrayType(TypeId.BYTESTRING, 2));
         types.put(RcsResourceAttributes[][].class,
                 new ArrayType(TypeId.ATTRIBUTES, 2));
 
@@ -209,6 +212,7 @@ public final class RcsValue {
         types.put(int[][][].class, new ArrayType(TypeId.INTEGER, 3));
         types.put(double[][][].class, new ArrayType(TypeId.DOUBLE, 3));
         types.put(String[][][].class, new ArrayType(TypeId.STRING, 3));
+        types.put(RcsByteString[][][].class, new ArrayType(TypeId.BYTESTRING, 3));
         types.put(RcsResourceAttributes[][][].class,
                 new ArrayType(TypeId.ATTRIBUTES, 3));
 
@@ -469,8 +473,35 @@ public final class RcsValue {
     /**
      * Constructs a new value that holds a RcsResourceAttributes array.
      *
-     * @param value
-     *            a RcsResourceAttributes array
+     * @param value a RcsByteString array
+     * @throws NullPointerException if value is null.
+     */
+    public RcsValue(RcsByteString[] value) {
+        this((Object) value);
+    }
+
+    /**
+     * Constructs a new value that holds a two-dimensional RcsByteString array.
+     *
+     * @param value a two-dimensional RcsByteString array
+     * @throws NullPointerException if value is null.
+     */
+    public RcsValue(RcsByteString[][] value) {
+        this((Object) value);
+    }
+
+    /**
+     * Constructs a new value that holds a three-dimensional RcsByteString array.
+     *
+     * @param value a three-dimensional RcsByteString array
+     * @throws NullPointerException if value is null.
+     */
+    public RcsValue(RcsByteString[][][] value) {
+        this((Object) value);
+    }
+
+    /**
+     * Constructs a new value that holds a RcsResourceAttributes array.
      *
      * @throws NullPointerException
      *             if value is null.
@@ -822,6 +853,36 @@ public final class RcsValue {
     }
 
     /**
+     * Returns the value as an RcsByteString array, null if the value is not the
+     * desired type.
+     *
+     * @return an RcsByteString array
+     */
+    public RcsByteString[] asByteStringArray() {
+        return getOrNull();
+    }
+
+    /**
+     * Returns the value as a two-dimensional RcsByteString array, null if the
+     * value is not the desired type.
+     *
+     * @return a two-dimensional RcsByteString array
+     */
+    public RcsByteString[][] asByteString2DArray() {
+        return getOrNull();
+    }
+
+    /**
+     * Returns the value as a three-dimensional RcsByteString array, null if the
+     * value is not the desired type.
+     *
+     * @return a three-dimensional RcsByteString array
+     */
+    public RcsByteString[][][] asByteString3DArray() {
+        return getOrNull();
+    }
+
+    /**
      * Returns the value as an attributes array, null if the value is not the
      * desired type.
      *
index df13696..71b3647 100644 (file)
@@ -148,7 +148,7 @@ public final class RcsRemoteResourceObject extends RcsObject {
          *            the updated attributes
          *
          */
-        public void onCacheUpdated(RcsResourceAttributes attributes);
+        public void onCacheUpdated(RcsResourceAttributes attributes, int eCode);
 
     }
 
index d4116e2..fd84e22 100644 (file)
@@ -135,7 +135,8 @@ namespace
         }
     }
 
-    void onCacheUpdated(const RCSResourceAttributes& attrs, const JavaGlobalRef& listener)
+    void onCacheUpdated(const RCSResourceAttributes& attrs, int eCode,
+                        const JavaGlobalRef& listener)
     {
         LOGD("onCacheUpdated");
 
@@ -186,7 +187,7 @@ void initRCSRemoteResourceObject(JNIEnvWrapper* env)
 
     auto clsOnCacheUpdatedListener = env->FindClass(CLS_NAME_ON_CACHE_UPDATED_LISTENER);
     g_method_onCacheUpdated = env->GetMethodID(clsOnCacheUpdatedListener, "onCacheUpdated",
-            "(" AS_SIG(CLS_NAME_RESOURCEATTRIBUTES) ")V");
+            "(" AS_SIG(CLS_NAME_RESOURCEATTRIBUTES) "I)V");
 
     auto clsOnRemoteAttributesReceivedListener =
             env->FindClass(CLS_NAME_ON_REMOTE_ATTRIBUTES_RECEIVED_LISTENER);
@@ -341,7 +342,8 @@ Java_org_iotivity_service_client_RcsRemoteResourceObject_nativeStartCaching
         if (listener)
         {
             res->startCaching(std::bind(onCacheUpdated,
-                    std::placeholders::_1, JavaGlobalRef{ env, listener }));
+                    std::placeholders::_1, std::placeholders::_2,
+                    JavaGlobalRef{ env, listener }));
         }
         else
         {
index 46ea958..cb1639f 100644 (file)
@@ -56,6 +56,7 @@ namespace
     jobject g_obj_TypeId_Integer;
     jobject g_obj_TypeId_Double;
     jobject g_obj_TypeId_String;
+    jobject g_obj_TypeId_ByteString;
     jobject g_obj_TypeId_Attributes;
     jobject g_obj_TypeId_Array;
 
@@ -189,6 +190,68 @@ namespace
         static constexpr char className[] = "L" CLS_NAME_STRING ";";
     };
     constexpr char JniTypeTrait< std::string >::className[];
+    template< typename ENV >
+    inline RCSByteString invoke_ByteString_byteStringValue(JNIEnvWrapper *env, jobject byteStringObj)
+    {
+        EXPECT_RET(byteStringObj, "byteStringObj is null!", { });
+
+        jclass g_cls_RCSByteString = env->FindClassAsGlobalRef(CLS_NAME_RESOURCEBYTESTRING);
+
+        static jfieldID field_data = env->GetFieldID(g_cls_RCSByteString, "mData", "[B");
+        static jfieldID field_length = env->GetFieldID(g_cls_RCSByteString, "mSize", "J");
+
+        jbyteArray jDataInfo = (jbyteArray)env->GetObjectField(byteStringObj, field_data);
+        jlong jDataLength = env->GetLongField(byteStringObj, field_length);
+
+        jbyte *byteStringData = env->GetByteArrayElements(jDataInfo, NULL);
+
+        RCSByteString byteString((uint8_t *)byteStringData, (size_t)jDataLength);
+
+        env->ReleaseByteArrayElements(jDataInfo, (jbyte*) byteStringData, JNI_ABORT);
+        env->DeleteGlobalRef(g_cls_RCSByteString);
+
+        return byteString;
+    }
+
+    template< typename ENV >
+    inline jobject newRCSByteStringObject(ENV* env, const RCSByteString& value)
+    {
+        jsize jSize = (jsize)value.size();
+
+        jbyteArray jData = env->NewByteArray(jSize);
+
+        std::vector<uint8_t> byteString = value.getByteString();
+
+        env->SetByteArrayRegion(jData, 0, jSize, (const jbyte*)&byteString[0]);
+
+        jclass g_cls_RCSByteString = env->FindClassAsGlobalRef(CLS_NAME_RESOURCEBYTESTRING);
+        jmethodID g_ctor_RCSByteString = env->GetConstructorID(g_cls_RCSByteString, "([BJ)V");
+
+        EXPECT_RET(g_ctor_RCSByteString, "g_ctor_RCSByteString is null!", { });
+
+        jobject jObj = (jobject)env->NewObject(g_cls_RCSByteString, g_ctor_RCSByteString, jData,
+                                               (jlong)jSize);
+
+        EXPECT_RET(jObj, "jObj is null!", { });
+
+        return jObj;
+    }
+
+    template<>
+    struct JniTypeTrait< RCSByteString >: public ObjectType
+    {
+        static decltype(&invoke_ByteString_byteStringValue<JNIEnvWrapper>) converter;
+
+        static decltype(&newRCSByteStringObject<JNIEnvWrapper>) newObjectFunc;
+
+        static constexpr char className[] = CLS_NAME_RESOURCEBYTESTRING;
+    };
+    constexpr char JniTypeTrait< RCSByteString >::className[];
+    decltype(&invoke_ByteString_byteStringValue<JNIEnvWrapper>) JniTypeTrait< RCSByteString >::converter =
+        &invoke_ByteString_byteStringValue<JNIEnvWrapper>;
+
+    decltype(&newRCSByteStringObject<JNIEnvWrapper>) JniTypeTrait< RCSByteString >::newObjectFunc =
+        &newRCSByteStringObject<JNIEnvWrapper>;
 
     template<>
     struct JniTypeTrait< RCSResourceAttributes >: public ObjectType
@@ -316,6 +379,9 @@ namespace
              case RCSResourceAttributes::TypeId::STRING:
                  return toNativeValue< std::string >(env, val, depth);
 
+            case RCSResourceAttributes::TypeId::BYTESTRING:
+                return toNativeValue< RCSByteString >(env, val, depth);
+
              case RCSResourceAttributes::TypeId::ATTRIBUTES:
                  return toNativeValue< RCSResourceAttributes >(env, val, depth);
          }
@@ -414,6 +480,11 @@ namespace
                         value.get< typename SeqType< DEPTH, std::string >::type >(),
                         Int2Type< DEPTH >{ });
 
+            case RCSResourceAttributes::TypeId::BYTESTRING:
+                return createJavaObject(env,
+                                        value.get< typename SeqType< DEPTH, RCSByteString >::type >(),
+                                        Int2Type< DEPTH > { });
+
             case RCSResourceAttributes::TypeId::ATTRIBUTES:
                 return createJavaObject(env,
                         value.get< typename SeqType< DEPTH, RCSResourceAttributes >::type >(),
@@ -452,6 +523,7 @@ namespace
         if (env->IsSameObject(g_obj_TypeId_Integer, typeIdObj)) return TypeId::INT;
         if (env->IsSameObject(g_obj_TypeId_Double, typeIdObj)) return TypeId::DOUBLE;
         if (env->IsSameObject(g_obj_TypeId_String, typeIdObj)) return TypeId::STRING;
+        if (env->IsSameObject(g_obj_TypeId_ByteString, typeIdObj)) return TypeId::BYTESTRING;
         if (env->IsSameObject(g_obj_TypeId_Attributes, typeIdObj)) return TypeId::ATTRIBUTES;
         if (env->IsSameObject(g_obj_TypeId_Array, typeIdObj)) return TypeId::VECTOR;
 
@@ -494,6 +566,7 @@ void initRCSValue(JNIEnvWrapper* env)
     g_obj_TypeId_Integer = getTypeIdObj(env, "INTEGER");
     g_obj_TypeId_Double = getTypeIdObj(env, "DOUBLE");
     g_obj_TypeId_String = getTypeIdObj(env, "STRING");
+    g_obj_TypeId_ByteString = getTypeIdObj(env, "BYTESTRING");
     g_obj_TypeId_Attributes = getTypeIdObj(env, "ATTRIBUTES");
     g_obj_TypeId_Array = getTypeIdObj(env, "ARRAY");
 }
@@ -509,6 +582,7 @@ void clearRCSValue(JNIEnvWrapper* env)
     env->DeleteGlobalRef(g_obj_TypeId_Integer);
     env->DeleteGlobalRef(g_obj_TypeId_Double);
     env->DeleteGlobalRef(g_obj_TypeId_String);
+    env->DeleteGlobalRef(g_obj_TypeId_ByteString);
     env->DeleteGlobalRef(g_obj_TypeId_Attributes);
     env->DeleteGlobalRef(g_obj_TypeId_Array);
 }
index 2723178..facc807 100644 (file)
@@ -294,7 +294,14 @@ public:
         return ret;
     }
 
-    jobjectArray NewObjectArray(jsize len, jclass cls, jobject init)
+    jbyteArray NewByteArray(jsize len)
+    {
+        auto ret = m_env->NewByteArray(len);
+        if (m_env->ExceptionCheck()) throw JavaException();
+        return ret;
+    }
+
+  jobjectArray NewObjectArray(jsize len, jclass cls, jobject init)
     {
         auto ret = m_env->NewObjectArray(len, cls, init);
         if (m_env->ExceptionCheck()) throw JavaException();
@@ -315,6 +322,13 @@ public:
         return ret;
     }
 
+    jbyte *GetByteArrayElements(jbyteArray array, jboolean *value)
+    {
+        auto ret = m_env->GetByteArrayElements(array, value);
+        if (m_env->ExceptionCheck()) throw JavaException();
+        return ret;
+    }
+
     void SetObjectArrayElement(jobjectArray array, jsize index, jobject val)
     {
         m_env->SetObjectArrayElement(array, index, val);
@@ -339,6 +353,12 @@ public:
         if (m_env->ExceptionCheck()) throw JavaException();
     }
 
+    void SetByteArrayRegion(jbyteArray array, jsize start, jsize len, const jbyte *buf)
+    {
+        m_env->SetByteArrayRegion(array, start, len, buf);
+        if (m_env->ExceptionCheck()) throw JavaException();
+    }
+
     void* GetPrimitiveArrayCritical(jarray array, jboolean* isCopy)
     {
         auto ret = m_env->GetPrimitiveArrayCritical(array, isCopy);
@@ -352,7 +372,14 @@ public:
         if (m_env->ExceptionCheck()) throw JavaException();
     }
 
-    void ThrowNew(jclass cls, const char* msg) {
+    void ReleaseByteArrayElements(jbyteArray array, jbyte* byteArray, int mode)
+    {
+        m_env->ReleaseByteArrayElements(array, byteArray, mode);
+        if (m_env->ExceptionCheck()) throw JavaException();
+    }
+
+    void ThrowNew(jclass cls, const char* msg)
+    {
         m_env->ThrowNew(cls, msg);
         throw JavaException();
     }
index d87e3d5..10033ad 100644 (file)
@@ -31,6 +31,7 @@
 
 #define CLS_NAME_RESOURCEATTRIBUTES PACKAGE_NAME "/RcsResourceAttributes"
 #define CLS_NAME_REMOTERESOURCEOBJECT PACKAGE_NAME "/client/RcsRemoteResourceObject"
+#define CLS_NAME_RESOURCEBYTESTRING PACKAGE_NAME "/RcsByteString"
 
 #define CLS_NAME_OBJECT "java/lang/Object"
 #define CLS_NAME_STRING "java/lang/String"
index cb1c742..2b878b7 100644 (file)
@@ -112,7 +112,7 @@ public class ResourceClientActivity extends Activity
 
     private OnCacheUpdatedListener mOnCacheUpdatedListener = new OnCacheUpdatedListener() {
         @Override
-        public void onCacheUpdated(RcsResourceAttributes attrs) {
+        public void onCacheUpdated(RcsResourceAttributes attrs, int eCode) {
             Log.i(LOG_TAG, "onCacheUpdated");
 
             mHandler.obtainMessage(MSG_ID_ATTRIBUTE_RECEIVED, attrs)
index 4a7d87d..6ef9202 100644 (file)
@@ -183,7 +183,7 @@ std::vector< std::vector< RCSResourceAttributes > > createNestedAttribute(int sp
 
 int processUserInput()
 {
-    int userInput;
+    int userInput = 0;
     std::cin >> userInput;
     if (std::cin.fail())
     {
@@ -201,7 +201,8 @@ void getAttributeFromRemoteServer()
 
 void setAttributeToRemoteServer()
 {
-    int speed, airc;
+    int speed = 0;
+    int airc = 0;
 
     std::cout << "\tEnter the Fan Speed you want to set : ";
     std::cin >> speed;
index 66534f6..005e0a5 100644 (file)
@@ -223,7 +223,7 @@ void initServer()
 
 int processUserInput()
 {
-    int userInput;
+    int userInput = 0;
     std::cin >> userInput;
     if (std::cin.fail())
     {
@@ -324,6 +324,10 @@ int main(void)
     {
         std::cout << "main exception  : " << e.what() << std::endl;
     }
+    catch (...)
+    {
+        std::cout << "main exception  : unknown" << std::endl;
+    }
 
     std::cout << "Stopping the server" << std::endl;
 }
index cf0ff40..d7336ca 100644 (file)
@@ -87,7 +87,7 @@ int processUserInput(int min = std::numeric_limits<int>::min(),
 {
     assert(min <= max);
 
-    int input;
+    int input = 0;
 
     std::cin >> input;
     std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
@@ -270,9 +270,9 @@ void onResourceStateChanged(ResourceState resourceState)
     }
 }
 
-void onCacheUpdated(const RCSResourceAttributes& attributes)
+void onCacheUpdated(const RCSResourceAttributes& attributes, int eCode)
 {
-    std::cout << "onCacheUpdated callback" << std::endl;
+    std::cout << "onCacheUpdated callback : " << eCode << std::endl;
 
     printAttributes(attributes);
 }
@@ -423,16 +423,16 @@ std::string selectResourceType()
 
     switch (processUserInput(RESOURCE_TEMP, RESOURCE_LIGHT))
     {
-    case RESOURCE_TEMP:
-    {
-        g_attrKey = "Temperature";
-        return RESOURCE_TYPE_TEMP;
-    }
-    case RESOURCE_LIGHT:
-    {
-        g_attrKey = "Brightness";
-        return RESOURCE_TYPE_LIGHT;
-    }
+        case RESOURCE_TEMP:
+        {
+            g_attrKey = "Temperature";
+            return RESOURCE_TYPE_TEMP;
+        }
+        case RESOURCE_LIGHT:
+        {
+            g_attrKey = "Brightness";
+            return RESOURCE_TYPE_LIGHT;
+        }
     }
 
     throw std::logic_error("unreachable");
index 65b9cd6..9e919b6 100644 (file)
@@ -19,6 +19,7 @@
  ******************************************************************/
 
 #include "RCSResourceObject.h"
+#include "RCSRequest.h"
 #include "OCPlatform.h"
 
 using namespace OC::OCPlatform;
@@ -53,7 +54,7 @@ int processUserInput(int min, int max)
 {
     assert(min <= max);
 
-    int input;
+    int input = 0;
 
     std::cin >> input;
 
@@ -102,7 +103,7 @@ void printAttributes(const RCSResourceAttributes& attrs)
     }
 }
 
-RCSGetResponse requestHandlerForGet(const RCSRequest&, RCSResourceAttributes& attrs)
+RCSGetResponse requestHandlerForGet(const RCSRequest & req, RCSResourceAttributes& attrs)
 {
     std::cout << "Received a Get request from Client" << std::endl;
     printAttributes(attrs);
@@ -110,10 +111,21 @@ RCSGetResponse requestHandlerForGet(const RCSRequest&, RCSResourceAttributes& at
     {
         RCSResourceObject::LockGuard lock(g_resource);
         std::cout << "\nSending response to Client : " << std::endl;
-        printAttributes(g_resource->getAttributes());
+        if (req.getInterface() == CUSTOM_INTERFACE)
+        {
+            auto attr = g_resource->getAttributes();
+            static RCSByteString::DataType binval {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+                                                   0x9, 0x0, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF};
+            attr["blob"] = RCSByteString {binval};
+            printAttributes(attr);
+            return RCSGetResponse::create(attr);
+        }
+        else
+        {
+            printAttributes(g_resource->getAttributes());
+            return RCSGetResponse::defaultAction();
+        }
     }
-
-    return RCSGetResponse::defaultAction();
 }
 
 RCSSetResponse requestHandlerForSet(const RCSRequest&, RCSResourceAttributes& attrs)
@@ -178,7 +190,7 @@ void runResourceTypeSelection(int resourceMode)
     std::cout << "========================================================\n";
 
     int resourceType = processUserInput(RESOURCE_TEMP, RESOURCE_LIGHT);
-    DisplayControlMenuFunc displayMenuFunc;
+    DisplayControlMenuFunc displayMenuFunc = nullptr;
     std::string attrKey;
 
     switch (resourceType)
@@ -264,7 +276,14 @@ int main(void)
 
     if (g_isPresenceStarted)
     {
-        stopPresence();
+        try
+        {
+            stopPresence();
+        }
+        catch(...)
+        {
+            std::cout << "presence stop fail" << std::endl;
+        }
     }
 }
 
index 4c9b4f6..1a76655 100755 (executable)
@@ -70,7 +70,7 @@ int processUserInput(int min, int max)
 {
     assert(min <= max);
 
-    int input;
+    int input = 0;
 
     while(true)
     {
index 07aa7ed..8518573 100644 (file)
@@ -127,7 +127,7 @@ void onResourceStateChanged(const ResourceState &resourceState)
                                           &logMessage);
 }
 
-void onCacheUpdated(const RCSResourceAttributes &attributes)
+void onCacheUpdated(const RCSResourceAttributes &attributes, int)
 {
     dlog_print(DLOG_INFO, LOG_TAG, "#### onCacheUpdated callback");
 
@@ -277,7 +277,7 @@ static void setAttributeToRemoteServer(int setValue)
                                           &logMessage);
 }
 
-static void startCaching(std::function <void (const RCSResourceAttributes &)>cb)
+static void startCaching(std::function <void (const RCSResourceAttributes &, int)>cb)
 {
     string logMessage = "";
 
index 935c66f..e5af9a2 100644 (file)
@@ -169,7 +169,7 @@ namespace OIC
          * @see RCSDiscoveryManager
          *
          */
-        class RCSRemoteResourceObject
+        class RCSRemoteResourceObject : public std::enable_shared_from_this<RCSRemoteResourceObject>
         {
         public:
             typedef std::shared_ptr< RCSRemoteResourceObject > Ptr;
@@ -187,7 +187,8 @@ namespace OIC
              *
              * @param attrs the updated attributes
              */
-            typedef std::function< void(const RCSResourceAttributes& attrs) > CacheUpdatedCallback;
+            typedef std::function< void(const RCSResourceAttributes& attrs, int eCode) >
+                CacheUpdatedCallback;
 
             /**
              * Callback definition to be invoked when the response of getRemoteAttributes is
index 6fcff21..99d29bf 100644 (file)
@@ -49,6 +49,166 @@ namespace OIC
 {
     namespace Service
     {
+        /**
+        * This RCSByteString the one of RCSResourceAttributes value for Byte String (Binary).
+        *
+        * It provides similar usage to c++ standard vector.<br/>
+        * An RCSByteString can be one of various attribute value type.
+        *
+        * @see Value
+        * @see Type
+        * @see RCSRemoteResourceObject
+        * @see RCSResourceObject
+        * @see RCSResourceAttributes
+        */
+        class RCSByteString
+        {
+        public:
+            typedef std::vector<uint8_t> DataType;
+
+            /**
+             * Returns a vector<uint8_t> type of byte string.
+             *
+             * @return A stored byte string with std::vector<uint8_t>
+             */
+            DataType getByteString() const
+            {
+                return {m_data};
+            }
+
+            /**
+             * Returns a size of stored vector<uint8_t>.
+             *
+             * @return A size of stored byte string.
+             */
+            size_t size() const
+            {
+                return m_data.size();
+            }
+
+            /**
+              * @relates RCSByteString
+              *
+              * Checks if the byte string is same contents, or not.
+              *
+              * @return true if the byte string are equal, false otherwise.
+              */
+            inline bool operator==(const RCSByteString& rhs) const
+            {
+                return this->m_data == rhs.getByteString();
+            }
+
+            /**
+             * @relates RCSByteString
+             *
+             * Checks if the byte string is not same contents, or is same.
+             *
+             * @return true if the byte string are not equal, false otherwise.
+             */
+            inline bool operator!=(const RCSByteString& rhs) const
+            {
+                return this->m_data != rhs.getByteString();
+            }
+
+            /**
+             * Return a value of indexed byte string.
+             *
+             * @param it location of the element.
+             *
+             * @return A copied value of indexed byte string.
+             */
+            inline uint8_t operator[](size_t it) const
+            {
+                return this->m_data[it];
+            }
+
+            RCSByteString()
+            {
+            }
+            RCSByteString(DataType && rhs)
+            : m_data {std::move(rhs)}
+            {
+            }
+            RCSByteString(const DataType & rhs)
+            : m_data {rhs}
+            {
+            }
+            RCSByteString(RCSByteString && rhs)
+            : m_data {DataType{rhs.getByteString()}}
+            {
+            }
+            RCSByteString(const RCSByteString & rhs)
+            : m_data {DataType{rhs.getByteString()}}
+            {
+            }
+
+            RCSByteString(::OCByteString && rhs)
+            : m_data {DataType{rhs.bytes, rhs.bytes + rhs.len}}
+            {
+            }
+            RCSByteString(const ::OCByteString & rhs)
+            : m_data {DataType{rhs.bytes, rhs.bytes + rhs.len}}
+            {
+            }
+
+            RCSByteString(uint8_t* bytes, size_t size)
+            : m_data {DataType{bytes, bytes + size}}
+            {
+            }
+            inline RCSByteString& operator=(RCSByteString&& rhs)
+            {
+                return operator =(rhs);
+            }
+            inline RCSByteString& operator=(const RCSByteString& rhs)
+            {
+                if (!m_data.empty())
+                {
+                    m_data.clear();
+                }
+                m_data = DataType{rhs.getByteString()};
+                return *this;
+            }
+        private:
+            DataType m_data;
+        };
+
+#ifdef __APPLE__
+    class RCSResourceAttributes;
+    typedef boost::variant<
+                    std::nullptr_t,
+                    int,
+                    double,
+                    bool,
+                    std::string,
+                    RCSByteString,
+                    RCSResourceAttributes,
+
+                    std::vector< int >,
+                    std::vector< double >,
+                    std::vector< bool >,
+                    std::vector< std::string >,
+                    std::vector< RCSByteString >,
+                    std::vector< RCSResourceAttributes >,
+
+                    std::vector< std::vector< int > >,
+                    std::vector< std::vector< std::vector< int > > >,
+
+                    std::vector< std::vector< double > >,
+                    std::vector< std::vector< std::vector< double > > >,
+
+                    std::vector< std::vector< bool > >,
+                    std::vector< std::vector< std::vector< bool > > >,
+
+                    std::vector< std::vector< std::string > >,
+                    std::vector< std::vector< std::vector< std::string > > >,
+
+                    std::vector< std::vector< RCSByteString > >,
+                    std::vector< std::vector< std::vector< RCSByteString > > >,
+
+                    std::vector< std::vector< RCSResourceAttributes > >,
+                    std::vector< std::vector< std::vector< RCSResourceAttributes > > >
+                > ValueVariant;
+#endif
 
         /**
         * This represents the attributes for a resource.
@@ -65,24 +225,27 @@ namespace OIC
         * @see RCSDiscoveryManager
         * @see RCSRemoteResourceObject
         * @see RCSResourceObject
+        * @see RCSByteString
         */
         class RCSResourceAttributes
         {
         private:
             template< typename T > struct IsSupportedTypeHelper;
-
+#ifndef __APPLE__
             typedef boost::variant<
                 std::nullptr_t,
                 int,
                 double,
                 bool,
                 std::string,
+                RCSByteString,
                 RCSResourceAttributes,
 
                 std::vector< int >,
                 std::vector< double >,
                 std::vector< bool >,
                 std::vector< std::string >,
+                std::vector< RCSByteString >,
                 std::vector< RCSResourceAttributes >,
 
                 std::vector< std::vector< int > >,
@@ -97,10 +260,13 @@ namespace OIC
                 std::vector< std::vector< std::string > >,
                 std::vector< std::vector< std::vector< std::string > > >,
 
+                std::vector< std::vector< RCSByteString > >,
+                std::vector< std::vector< std::vector< RCSByteString > > >,
+
                 std::vector< std::vector< RCSResourceAttributes > >,
                 std::vector< std::vector< std::vector< RCSResourceAttributes > > >
             > ValueVariant;
-
+#endif
             template< typename T, typename V = void,
                     typename = typename std::enable_if<
                         IsSupportedTypeHelper< T >::type::value, V >::type >
@@ -159,6 +325,7 @@ namespace OIC
                 DOUBLE, /**< double */
                 BOOL, /**< bool */
                 STRING, /**< std::string */
+                BYTESTRING, /**< RCSByteString */
                 ATTRIBUTES, /**< RCSResourceAttributes */
                 VECTOR /**< std::vector */
             };
@@ -264,12 +431,14 @@ namespace OIC
                 double
                 bool
                 std::string
+                RCSByteString
                 RCSResourceAttributes
 
                 std::vector< int >
                 std::vector< double >
                 std::vector< bool >
                 std::vector< std::string >
+                std::vector< RCSByteString >
                 std::vector< RCSResourceAttributes >
 
                 std::vector< std::vector< int > >
@@ -284,6 +453,9 @@ namespace OIC
                 std::vector< std::vector< std::string > >
                 std::vector< std::vector< std::vector< std::string > > >
 
+                std::vector< std::vector< RCSByteString > >
+                std::vector< std::vector< std::vector< RCSByteString > > >
+
                 std::vector< std::vector< RCSResourceAttributes > >
                 std::vector< std::vector< std::vector< RCSResourceAttributes > > >
              * @endcode
@@ -380,7 +552,14 @@ namespace OIC
                 {
                     try
                     {
-                        return boost::get< T >(*m_data);
+                        if ((*m_data).type() == typeid(T))
+                        {
+                            return boost::get< T >(*m_data);
+                        }
+                        else
+                        {
+                            throw RCSBadGetException{ "Wrong type" };
+                        }
                     }
                     catch (const boost::bad_get&)
                     {
@@ -401,7 +580,11 @@ namespace OIC
                     }
                 }
 
+#ifdef __APPLE__
+            public:
+#else
             private:
+#endif
                 boost::scoped_ptr< ValueVariant > m_data;
             };
 
@@ -586,8 +769,11 @@ namespace OIC
                     boost::apply_visitor(helper, key, *i.second.m_data);
                 }
             }
-
+#ifdef __APPLE__
+        public:
+#else
         private:
+#endif
             std::unordered_map< std::string, Value > m_values;
 
             //! @cond
index c91597b..258a28a 100644 (file)
@@ -97,7 +97,7 @@ TEST_F(ExpiryTimerImplTest, CallbackBeInvokedWithinTolerance)
 
 TEST_F(ExpiryTimerImplTest, CallbackBeInvokedWithTimerId)
 {
-    ExpiryTimerImpl::Id returnedId;
+    ExpiryTimerImpl::Id returnedId = 0;
     FunctionObject* functor = mocks.Mock< FunctionObject >();
 
     mocks.ExpectCall(functor, FunctionObject::execute).Match(
@@ -236,7 +236,7 @@ TEST_F(ExpiryTimerTest, CallbackBeInvokedWithinTolerance)
 
 TEST_F(ExpiryTimerTest, CallbackBeInvokedWithTimerId)
 {
-    ExpiryTimer::Id returnedId;
+    ExpiryTimer::Id returnedId = 0;
     FunctionObject* functor = mocks.Mock< FunctionObject >();
 
     mocks.ExpectCall(functor, FunctionObject::execute).Match(
index 8ba772b..59409ea 100644 (file)
@@ -91,6 +91,7 @@ namespace OIC
             virtual std::string getHost() const = 0;
             virtual std::vector< std::string > getTypes() const = 0;
             virtual std::vector< std::string > getInterfaces() const = 0;
+            virtual OCConnectivityType getConnectivityType() const = 0;
 
             virtual bool isObservable() const = 0;
 
index b531b34..778a62a 100644 (file)
@@ -211,6 +211,11 @@ namespace OIC
                 return invokeOC(m_baseResource, &BaseResource::getResourceInterfaces);
             }
 
+            OCConnectivityType getConnectivityType() const
+            {
+                return invokeOC(m_baseResource, &BaseResource::connectivityType);
+            }
+
             bool isObservable() const
             {
                 return invokeOC(m_baseResource, &BaseResource::isObservable);
index b4c5b63..10f59e0 100644 (file)
@@ -56,6 +56,12 @@ namespace OIC
             struct OCBaseType< OC::AttributeType::String > : TypeDef< std::string > { };
 
             template< >
+            struct OCBaseType< OC::AttributeType::Binary > : TypeDef< RCSByteString::DataType > { };
+
+            template< >
+            struct OCBaseType< OC::AttributeType::OCByteString > : TypeDef< OCByteString > { };
+
+            template< >
             struct OCBaseType< OC::AttributeType::OCRepresentation >
                 : TypeDef< OC::OCRepresentation >
             {};
@@ -124,6 +130,16 @@ namespace OIC
                         case OC::AttributeType::String:
                             return insertItem< DEPTH, OC::AttributeType::String >(item);
 
+                        case OC::AttributeType::Binary:
+                            // OCRep support only 0-depth for binary type.
+                            // If RI changed, this line should be changed to DEPTH.
+                            return insertOcBinary< OC::AttributeType::Binary >
+                            (Detail::Int2Type< 0 >{ }, item);
+
+                        case OC::AttributeType::OCByteString:
+                            return insertOcBinary< OC::AttributeType::OCByteString >
+                            (Detail::Int2Type< DEPTH >{ }, item);
+
                         case OC::AttributeType::OCRepresentation:
                             return insertOcRep(Detail::Int2Type< DEPTH >{ }, item);
 
@@ -170,6 +186,37 @@ namespace OIC
                             insertOcRep(Detail::Int2Type< DEPTH >{ }, item.getValue< ItemType >()));
                 }
 
+                template< typename OCREP >
+                RCSByteString insertOcBinary(Detail::Int2Type< 0 >, const OCREP& ocBinary)
+                {
+                    return RCSByteString(ocBinary);
+                }
+
+                template< int DEPTH, typename OCREPS,
+                    typename ATTRS = typename Detail::SeqType< DEPTH, RCSByteString >::type >
+                ATTRS insertOcBinary(Detail::Int2Type< DEPTH >, const OCREPS& ocBinaryVec)
+                {
+                    ATTRS result;
+
+                    for (const auto& nested : ocBinaryVec)
+                    {
+                        result.push_back(insertOcBinary(Detail::Int2Type< DEPTH - 1 >{ }, nested));
+                    }
+
+                    return result;
+                }
+
+                template< OC::AttributeType BASE_TYPE, int DEPTH >
+                void insertOcBinary(Detail::Int2Type< DEPTH >,
+                        const OC::OCRepresentation::AttributeItem& item)
+                {
+                    typedef typename Detail::OCItemType< DEPTH, BASE_TYPE >::type ItemType;
+
+                    putValue(item.attrname(),
+                             insertOcBinary(Detail::Int2Type< DEPTH >{ },
+                                            item.getValue< ItemType >()));
+                }
+
             public:
                 ResourceAttributesBuilder() = default;
 
@@ -213,7 +260,10 @@ namespace OIC
                 OCRepresentationBuilder() = default;
 
                 template< typename T, typename B = typename Detail::TypeInfo< T >::base_type >
-                typename std::enable_if< !std::is_same< B, RCSResourceAttributes >::value >::type
+                typename std::enable_if< (
+                !std::is_same< B, RCSResourceAttributes >::value &&
+                !std::is_same< B, RCSByteString >::value
+                )>::type
                 operator()(const std::string& key, const T& value)
                 {
                     m_target[key] = value;
@@ -227,6 +277,14 @@ namespace OIC
                     m_target[key] = convertAttributes(Detail::Int2Type< I::depth >{ }, value);
                 }
 
+                template< typename T, typename I = Detail::TypeInfo< T > >
+                typename std::enable_if< std::is_same< typename I::base_type,
+                                                RCSByteString >::value >::type
+                operator()(const std::string& key, const T& value)
+                {
+                    m_target[key] = convertByteString(Detail::Int2Type< I::depth >{ }, value);
+                }
+
                 void operator()(const std::string& key, const std::nullptr_t&)
                 {
                     m_target.setNULL(key);
@@ -253,6 +311,35 @@ namespace OIC
                     return result;
                 }
 
+                OCByteString convertByteString(Detail::Int2Type< 0 >,
+                        const RCSByteString& byteString)
+                {
+                    OCByteString blob;
+                    blob.len = byteString.size();
+                    blob.bytes = new uint8_t[blob.len];
+                    for (size_t i = 0; i < blob.len; ++i)
+                    {
+                        blob.bytes[i] = byteString[i];
+                    }
+
+                    return blob;
+                }
+
+                template< int DEPTH, typename ATTRS, typename OCREPS = typename Detail::SeqType<
+                        DEPTH, OCByteString >::type >
+                OCREPS convertByteString(Detail::Int2Type< DEPTH >, const ATTRS& byteStringVec)
+                {
+                    OCREPS result;
+
+                    for (const auto& nested : byteStringVec)
+                    {
+                        result.push_back(
+                                convertByteString(Detail::Int2Type< DEPTH - 1 >{ }, nested));
+                    }
+
+                    return result;
+                }
+
                 OC::OCRepresentation&& extract()
                 {
                     return std::move(m_target);
index ee66c98..75e9d56 100644 (file)
 #include "boost/mpl/size.hpp"
 #include "boost/mpl/deref.hpp"
 
-#ifdef __APPLE__
-#define OC_CONSTEXPR_INLINE inline
-#else
-#define OC_CONSTEXPR_INLINE constexpr inline
-#endif
-
 namespace
 {
 
@@ -84,6 +78,14 @@ namespace
             m_stream << "\"" + value + "\"";
         }
 
+        void operator()(const RCSByteString& value)
+        {
+            for (size_t i = 0; i < value.size(); ++i)
+            {
+                m_stream << "\\x" << std::hex << (int)value[i];
+            }
+        }
+
         void operator()(const RCSResourceAttributes& attrs)
         {
             m_stream << "{";
@@ -161,6 +163,13 @@ namespace
     };
 
     template< >
+    struct TypeInfoConverter< RCSByteString >
+    {
+        static constexpr RCSResourceAttributes::TypeId typeId =
+                RCSResourceAttributes::TypeId::BYTESTRING;
+    };
+
+    template< >
     struct TypeInfoConverter< RCSResourceAttributes >
     {
         static constexpr RCSResourceAttributes::TypeId typeId =
@@ -212,7 +221,7 @@ namespace
     };
 
     template< typename VARIANT, int POS >
-    OC_CONSTEXPR_INLINE std::vector< TypeInfo > getTypeInfo(Int2Type< POS >) noexcept
+    inline std::vector< TypeInfo > getTypeInfo(Int2Type< POS >) noexcept
     {
         auto vec = getTypeInfo< VARIANT >(Int2Type< POS - 1 >{ });
         vec.push_back(TypeInfo::get< VARIANT, POS >());
@@ -220,7 +229,7 @@ namespace
     }
 
     template< typename VARIANT >
-    OC_CONSTEXPR_INLINE std::vector< TypeInfo > getTypeInfo(Int2Type< 0 >) noexcept
+    inline std::vector< TypeInfo > getTypeInfo(Int2Type< 0 >) noexcept
     {
         return { TypeInfo::get< VARIANT, 0 >() };
     }
@@ -237,7 +246,6 @@ namespace
 
         return typeInfos[which];
     }
-
 } // unnamed namespace
 
 
@@ -245,7 +253,6 @@ namespace OIC
 {
     namespace Service
     {
-
         RCSResourceAttributes::Value::ComparisonHelper::ComparisonHelper(const Value& v) :
                 m_valueRef(v)
         {
index b1aa1a0..dcf5c3c 100644 (file)
@@ -54,6 +54,7 @@ public:
     virtual std::string host() const = 0;
     virtual std::vector<std::string> getResourceTypes() const = 0;
     virtual std::vector<std::string> getResourceInterfaces() const = 0;
+    virtual OCConnectivityType connectivityType() const = 0;
 
     virtual bool isObservable() const = 0;
 };
index a2a7876..37f4bca 100644 (file)
@@ -343,6 +343,48 @@ TEST(ResourceAttributesConverterTest, OCRepresentationCanBeConvertedIntoResource
     ASSERT_TRUE(value == resourceAttributes[KEY]);
 }
 
+TEST(ResourceAttributesConverterTest, OCRepresentationCanBeConvertedIntoResourceAttributesTypeBinary)
+{
+    static uint8_t binval[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+                               0x9, 0x0, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF};
+
+    OCByteString value {binval, sizeof(binval)};
+    OC::OCRepresentation ocRep;
+    ocRep[KEY] = value;
+
+    RCSResourceAttributes resourceAttributes{
+        ResourceAttributesConverter::fromOCRepresentation(ocRep) };
+
+    auto rcsValue = resourceAttributes[KEY].get<RCSByteString>();
+    for (size_t i = 0; i < rcsValue.size(); ++i)
+    {
+        ASSERT_EQ(binval[i], rcsValue[i]);
+    }
+}
+
+TEST(ResourceAttributesConverterTest, ResourceAttributesCanBeConvertedIntoOCRepresentationTypeBinary)
+{
+    static RCSByteString::DataType binval {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8,
+                                           0x9, 0x0, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF};
+    RCSResourceAttributes resourceAttributes;
+    RCSByteString value {binval};
+    resourceAttributes[KEY] = value;
+
+    OC::OCRepresentation ocRep{
+        ResourceAttributesConverter::toOCRepresentation(resourceAttributes) };
+
+    auto rcsValue = resourceAttributes[KEY].get<RCSByteString>();
+    auto ocValue = ocRep[KEY].getValue<OCByteString>();
+
+    ASSERT_EQ(rcsValue.size(), ocValue.len);
+    ASSERT_EQ(rcsValue.size(), binval.size());
+    ASSERT_EQ(binval.size(), ocValue.len);
+
+    for (size_t i = 0; i < rcsValue.size(); ++i)
+    {
+        ASSERT_EQ(ocValue.bytes[i], rcsValue[i]);
+    }
+}
 
 TEST(ResourceAttributesConverterTest, NestedOCRepresentationCanBeConvertedIntoResourceAttributes)
 {
index 478f716..69f1612 100644 (file)
@@ -108,7 +108,7 @@ TEST_F(ResourceBrokerTest,CancelHostResource_NoThrowIfNormalParams)
 
     MockingFunc();
 
-    BrokerID ret;
+    BrokerID ret = 0;
     ret = brokerInstance->hostResource(pResource,cb);
 
     ASSERT_NO_THROW(brokerInstance->cancelHostResource(ret));
@@ -137,7 +137,7 @@ TEST_F(ResourceBrokerTest,getResourceState_ReturnNormalValueIfNormalId)
 
     MockingFunc();
 
-    BrokerID ret;
+    BrokerID ret = 0;
     ret = brokerInstance->hostResource(pResource,cb);
 
     ASSERT_NE(brokerInstance->getResourceState(ret),BROKER_STATE::NONE);
@@ -160,7 +160,7 @@ TEST_F(ResourceBrokerTest,getResourceState_ReturnNormalValueIfNormalResource)
 
     MockingFunc();
 
-    BrokerID ret;
+    BrokerID ret = 0;
     ret = brokerInstance->hostResource(pResource,cb);
 
     ASSERT_NE(brokerInstance->getResourceState(pResource),BROKER_STATE::NONE);
@@ -181,8 +181,8 @@ TEST_F(ResourceBrokerTest,getResourceState_NormalErrorHandlingIfAbnormalResource
 
     MockingFunc();
 
-    PrimitiveResource::Ptr resource[3];
-    BrokerID id[3];
+    PrimitiveResource::Ptr resource[3] = {nullptr,};
+    BrokerID id[3] = {0,};
 
     for(int i=0;i!=3;i++)
     {
index d87d186..0199887 100644 (file)
@@ -97,7 +97,7 @@ TEST_F(ResourcePresenceTest,timeoutCB_TimeOverWhenIsRequestGet)
     MockingFunc();
     instance->initializeResourcePresence(pResource);
     std::cout<<"wait while done timeout requestGet\n";
-    BROKER_STATE state;
+    BROKER_STATE state = BROKER_STATE::NONE;
     state = instance->getResourceState();
     sleep((BROKER_DEVICE_PRESENCE_TIMEROUT/1000)+1);
     ASSERT_EQ(state,instance->getResourceState());
index 8c21cdc..737edf1 100644 (file)
@@ -82,7 +82,7 @@ namespace OIC
         typedef int CacheID;
 
         typedef std::function<OCStackResult(std::shared_ptr<PrimitiveResource>,
-                                            const RCSResourceAttributes &)> CacheCB;
+                        const RCSResourceAttributes &, int eCode)> CacheCB;
         typedef std::map<int, std::pair<Report_Info, CacheCB>> SubscriberInfo;
         typedef std::pair<int, std::pair<Report_Info, CacheCB>> SubscriberInfoPair;
 
index 025aca6..090edb1 100644 (file)
@@ -98,7 +98,7 @@ namespace OIC
 
                 CacheID generateCacheID();
                 SubscriberInfoPair findSubscriber(CacheID id);
-                void notifyObservers(const RCSResourceAttributes Att);
+                void notifyObservers(const RCSResourceAttributes Att, int eCode);
         };
     } // namespace Service
 } // namespace OIC
index a30e8b6..11b72a6 100644 (file)
@@ -39,7 +39,7 @@ namespace OIC
         {
             public:
                 typedef std::function<OCStackResult(std::shared_ptr<PrimitiveResource>,
-                                            const RCSResourceAttributes &)> DataCacheCB;
+                            const RCSResourceAttributes &, int)> DataCacheCB;
                 typedef std::shared_ptr<ObserveCache> Ptr;
 
             public:
index e774d68..23ffd30 100644 (file)
@@ -208,14 +208,7 @@ namespace OIC
                                   const ResponseStatement &_rep, int _result, unsigned int _seq)
         {
 
-            if (_result != OC_STACK_OK || _rep.getAttributes().empty() || lastSequenceNum > _seq)
-            {
-                return;
-            }
-            else
-            {
-                lastSequenceNum = _seq;
-            }
+            lastSequenceNum = _seq;
 
             if (state != CACHE_STATE::READY)
             {
@@ -231,7 +224,7 @@ namespace OIC
             networkTimer.cancel(networkTimeOutHandle);
             networkTimeOutHandle = networkTimer.post(CACHE_DEFAULT_EXPIRED_MILLITIME, pTimerCB);
 
-            notifyObservers(_rep.getAttributes());
+            notifyObservers(_rep.getAttributes(), _result);
         }
 
         void DataCache::onGet(const HeaderOptions & /*_hos*/,
@@ -257,10 +250,10 @@ namespace OIC
                 pollingHandle = pollingTimer.post(CACHE_DEFAULT_REPORT_MILLITIME, pPollingCB);
             }
 
-            notifyObservers(_rep.getAttributes());
+            notifyObservers(_rep.getAttributes(), _result);
         }
 
-        void DataCache::notifyObservers(const RCSResourceAttributes Att)
+        void DataCache::notifyObservers(const RCSResourceAttributes Att, int eCode)
         {
             {
                 std::lock_guard<std::mutex> lock(att_mutex);
@@ -276,7 +269,7 @@ namespace OIC
             {
                 if (i.second.first.rf == REPORT_FREQUENCY::UPTODATE)
                 {
-                    i.second.second(this->sResource, Att);
+                    i.second.second(this->sResource, Att, eCode);
                 }
             }
         }
index 637faf9..608aa75 100644 (file)
@@ -102,22 +102,18 @@ namespace OIC
         void ObserveCache::onObserve(const HeaderOptions &,
                        const ResponseStatement & rep, int _result, unsigned int)
         {
-            if (!convertOCResultToSuccess((OCStackResult)_result))
-            {
-                return;
-            }
-
             m_state = CACHE_STATE::READY;
 
-            if (m_attributes == rep.getAttributes())
+            if (m_attributes == rep.getAttributes() &&
+                    convertOCResultToSuccess((OCStackResult)_result))
             {
                 return ;
             }
 
-            m_attributes = rep.getAttributes();
             if (m_reportCB)
             {
-                m_reportCB(m_wpResource.lock(), m_attributes);
+                m_attributes = rep.getAttributes();
+                m_reportCB(m_wpResource.lock(), m_attributes, _result);
             }
         }
 
index c57c7f0..e572575 100644 (file)
 #include "RCSException.h"
 #include "ocrandom.h"
 
+#include "ScopeLogger.h"
+
+#define TAG PCF("RCSResourceCacheManager")
+
 namespace OIC
 {
     namespace Service
@@ -59,6 +63,8 @@ namespace OIC
             PrimitiveResourcePtr pResource, CacheCB func, CACHE_METHOD cm,
             REPORT_FREQUENCY rf, long reportTime)
         {
+            SCOPE_LOG_F(DEBUG, TAG);
+
             if (pResource == nullptr)
             {
                 throw RCSInvalidParameterException {"[requestResourceCache] Primitive Resource is invaild"};
@@ -109,6 +115,8 @@ namespace OIC
                 newHandler->initializeDataCache(pResource);
                 s_cacheDataList->push_back(newHandler);
             }
+
+            std::lock_guard<std::mutex> lock(s_mutex);
             retID = newHandler->addSubscriber(func, rf, reportTime);
 
             cacheIDmap.insert(std::make_pair(retID, newHandler));
@@ -118,17 +126,31 @@ namespace OIC
 
         void ResourceCacheManager::cancelResourceCache(CacheID id)
         {
+            SCOPE_LOG_F(DEBUG, TAG);
+            std::lock_guard<std::mutex> lock(s_mutex);
+
             auto observeIns = observeCacheIDmap.find(id);
             auto dataCacheIns = cacheIDmap.find(id);
             if ((dataCacheIns == cacheIDmap.end() && observeIns == observeCacheIDmap.end())
                 || id == 0)
             {
+                lock.~lock_guard();
                 throw RCSInvalidParameterException {"[cancelResourceCache] CacheID is invaild"};
             }
 
             if (observeIns != observeCacheIDmap.end())
             {
-                (observeIns->second)->stopCache();
+                try
+                {
+                    (observeIns->second)->stopCache();
+                }
+                catch (...)
+                {
+                    (observeIns->second).reset();
+                    observeCacheIDmap.erase(observeIns);
+                    lock.~lock_guard();
+                    throw;
+                }
                 (observeIns->second).reset();
                 observeCacheIDmap.erase(observeIns);
                 return;
@@ -142,7 +164,6 @@ namespace OIC
                 {
                     cacheIDmap.erase(id);
                 }
-                std::lock_guard<std::mutex> lock(s_mutex);
                 if (foundCacheHandler->isEmptySubscriber())
                 {
                     s_cacheDataList->remove(foundCacheHandler);
@@ -152,6 +173,8 @@ namespace OIC
 
         void ResourceCacheManager::updateResourceCache(CacheID updateId) const
         {
+            SCOPE_LOG_F(DEBUG, TAG);
+
             if (updateId == 0)
             {
                 throw RCSInvalidParameterException {"[getCachedData] CacheID is NULL"};
@@ -167,6 +190,8 @@ namespace OIC
 
         const RCSResourceAttributes ResourceCacheManager::getCachedData(CacheID id) const
         {
+            SCOPE_LOG_F(DEBUG, TAG);
+
             if (id == 0)
             {
                 throw RCSInvalidParameterException {"[getCachedData] CacheID is NULL"};
@@ -194,6 +219,8 @@ namespace OIC
 
         CACHE_STATE ResourceCacheManager::getResourceCacheState(CacheID id) const
         {
+            SCOPE_LOG_F(DEBUG, TAG);
+
             if (id == 0)
             {
                 throw RCSInvalidParameterException {"[getResourceCacheState] CacheID is NULL"};
@@ -215,6 +242,8 @@ namespace OIC
 
         bool ResourceCacheManager::isCachedData(CacheID id) const
         {
+            SCOPE_LOG_F(DEBUG, TAG);
+
             if (id == 0)
             {
                 throw RCSInvalidParameterException {"[isCachedData] CacheID is NULL"};
@@ -236,6 +265,8 @@ namespace OIC
 
         void ResourceCacheManager::initializeResourceCacheManager()
         {
+            SCOPE_LOG_F(DEBUG, TAG);
+
             std::lock_guard<std::mutex> lock(s_mutex);
             if (s_cacheDataList == nullptr)
             {
@@ -246,6 +277,8 @@ namespace OIC
 
         DataCachePtr ResourceCacheManager::findDataCache(PrimitiveResourcePtr pResource) const
         {
+            SCOPE_LOG_F(DEBUG, TAG);
+
             DataCachePtr retHandler = nullptr;
             std::lock_guard<std::mutex> lock(s_mutex);
             for (auto &i : * s_cacheDataList)
@@ -262,6 +295,8 @@ namespace OIC
 
         DataCachePtr ResourceCacheManager::findDataCache(CacheID id) const
         {
+            SCOPE_LOG_F(DEBUG, TAG);
+
             DataCachePtr retHandler = nullptr;
             for (auto it : cacheIDmap)
             {
index b7a8d56..e00d506 100644 (file)
@@ -58,7 +58,8 @@ class DataCacheTest : public TestWithMock
 
             mocks.OnCall(pResource.get(), PrimitiveResource::isObservable).Return(false);
             cacheHandler.reset(new DataCache());
-            cb = ([](std::shared_ptr<PrimitiveResource >, const RCSResourceAttributes &)->OCStackResult
+            cb = ([](std::shared_ptr<PrimitiveResource >,
+                    const RCSResourceAttributes &, int) -> OCStackResult
                     {
                         return OC_STACK_OK;
                     });
index b3a2bfd..a344d41 100644 (file)
@@ -46,7 +46,8 @@ class ResourceCacheManagerTest : public TestWithMock
 
                                                });
             mocks.OnCall(pResource.get(), PrimitiveResource::isObservable).Return(false);
-            cb = ([](std::shared_ptr<PrimitiveResource >, const RCSResourceAttributes &)->OCStackResult
+            cb = ([](std::shared_ptr<PrimitiveResource >,
+                    const RCSResourceAttributes &, int) -> OCStackResult
                     {
                         return OC_STACK_OK;
                     });
index bc57893..319c9b8 100755 (executable)
@@ -197,7 +197,12 @@ namespace OIC
         {
             for (const auto& it : m_resourceTypes)
             {
-                discoverResource(m_address, m_relativeUri + "?rt=" + it, m_discoverCb);
+                std::string uri = std::string(OC_RSRVD_WELL_KNOWN_URI);
+                if (!it.empty())
+                {
+                    uri = std::string(OC_RSRVD_WELL_KNOWN_URI) + "?rt=" + it;
+                }
+                discoverResource(m_address, uri, m_discoverCb);
             }
         }
 
index e909261..bc95aa9 100644 (file)
@@ -92,12 +92,40 @@ namespace
     }
 
     OCStackResult cachingCallback(std::shared_ptr< PrimitiveResource >,
-            const RCSResourceAttributes& data,
-            RCSRemoteResourceObject::CacheUpdatedCallback onCacheUpdated)
+            const RCSResourceAttributes& data, int eCode,
+            RCSRemoteResourceObject::CacheUpdatedCallback onCacheUpdated,
+            std::weak_ptr<RCSRemoteResourceObject> resourcePtr)
     {
         SCOPE_LOG_F(DEBUG, TAG);
 
-        onCacheUpdated(data);
+        //If error code is failure then RE Cache module should
+        //do clean up for caching flags, maps etc.
+        if(eCode > 4)
+        {
+            OIC_LOG_V(ERROR, TAG, "Error code: %d",eCode);
+            try
+            {
+                std::shared_ptr<RCSRemoteResourceObject> resource = resourcePtr.lock();
+                if(resource)
+                {
+                    resource->stopCaching();
+                }
+                else
+                {
+                    OIC_LOG(ERROR, TAG, "Resource object is null");
+                }
+            }
+            catch(...)
+            {
+                //Exception will be thrown: stack will return OC_STACK_ERROR
+                // if it already stopped observe. This call is reqired for clearing
+                //Cache manager.
+                OIC_LOG(DEBUG, TAG, "Cleared Cache");
+            }
+        }
+
+        //Calling application callback
+        onCacheUpdated(data, eCode);
         return OC_STACK_OK;
     }
 
@@ -211,7 +239,7 @@ namespace OIC
 
             OC::OCResource::Ptr ocResource = OC::OCPlatform::constructResourceObject(rcsResource->getAddress(),
                 rcsResource->getUri(),
-                CT_DEFAULT,
+                rcsResource->m_primitiveResource->getConnectivityType(),
                 rcsResource->isObservable(),
                 rcsResource->getTypes(),
                 rcsResource->getInterfaces());
@@ -299,8 +327,9 @@ namespace OIC
             {
                 m_cacheId = ResourceCacheManager::getInstance()->requestResourceCache(
                         m_primitiveResource,
-                        std::bind(cachingCallback, std::placeholders::_1, std::placeholders::_2,
-                                  std::move(cb)), CACHE_METHOD::OBSERVE_ONLY,
+                        std::bind(cachingCallback, std::placeholders::_1,
+                                  std::placeholders::_2, std::placeholders::_3,
+                                  std::move(cb), shared_from_this()), CACHE_METHOD::OBSERVE_ONLY,
                                   REPORT_FREQUENCY::UPTODATE, 0);
             }
 
@@ -308,8 +337,9 @@ namespace OIC
             {
                 m_cacheId = ResourceCacheManager::getInstance()->requestResourceCache(
                         m_primitiveResource,
-                        std::bind(cachingCallback, std::placeholders::_1, std::placeholders::_2,
-                                std::move(cb)), CACHE_METHOD::ITERATED_GET,
+                        std::bind(cachingCallback, std::placeholders::_1,
+                                std::placeholders::_2, std::placeholders::_3,
+                                std::move(cb), shared_from_this()), CACHE_METHOD::ITERATED_GET,
                                 REPORT_FREQUENCY::UPTODATE, 0);
             }
             else
@@ -332,7 +362,19 @@ namespace OIC
                 return;
             }
 
-            ResourceCacheManager::getInstance()->cancelResourceCache(m_cacheId);
+            try
+            {
+                ResourceCacheManager::getInstance()->cancelResourceCache(m_cacheId);
+            }
+            catch (const RCSInvalidParameterException &)
+            {
+                throw;
+            }
+            catch (...)
+            {
+                m_cacheId = 0;
+                throw;
+            }
             m_cacheId = 0;
         }
 
index 2583fbb..78e443d 100644 (file)
@@ -47,7 +47,7 @@ void getRemoteAttributesCallback(const RCSResourceAttributes&, int) {}
 void setRemoteAttributesCallback(const RCSResourceAttributes&, int) {}
 void setRemoteRepresentationCallback(const HeaderOpts&, const RCSRepresentation&, int) {}
 void resourceStateChanged(ResourceState) { }
-void cacheUpdatedCallback(const RCSResourceAttributes&) {}
+void cacheUpdatedCallback(const RCSResourceAttributes&, int) {}
 
 class RemoteResourceObjectTest: public TestWithMock
 {
@@ -294,7 +294,7 @@ TEST_F(RemoteResourceObjectTest, CacheStateIsUnreadyAfterStartCaching)
 TEST_F(RemoteResourceObjectTest, CacheStateIsReadyAfterCacheUpdated)
 {
     mocks.ExpectCallFunc(cacheUpdatedCallback).
-                Do([this](const RCSResourceAttributes&){ Proceed(); });
+                Do([this](const RCSResourceAttributes&, int){ Proceed(); });
 
     object->startCaching(cacheUpdatedCallback);
     Wait();
@@ -305,7 +305,7 @@ TEST_F(RemoteResourceObjectTest, CacheStateIsReadyAfterCacheUpdated)
 TEST_F(RemoteResourceObjectTest, IsCachedAvailableReturnsTrueWhenCacheIsReady)
 {
     mocks.ExpectCallFunc(cacheUpdatedCallback).
-                Do([this](const RCSResourceAttributes&){ Proceed(); });
+                Do([this](const RCSResourceAttributes&, int){ Proceed(); });
 
     object->startCaching(cacheUpdatedCallback);
     Wait();
@@ -316,12 +316,12 @@ TEST_F(RemoteResourceObjectTest, IsCachedAvailableReturnsTrueWhenCacheIsReady)
 TEST_F(RemoteResourceObjectTest, DISABLED_CacheUpdatedCallbackBeCalledWheneverCacheUpdated)
 {
     mocks.OnCallFunc(cacheUpdatedCallback).
-            Do([this](const RCSResourceAttributes&){ Proceed(); });
+            Do([this](const RCSResourceAttributes&, int){ Proceed(); });
     object->startCaching(cacheUpdatedCallback);
     Wait();
 
     mocks.ExpectCallFunc(cacheUpdatedCallback).
-            Do([this](const RCSResourceAttributes&){ Proceed(); });
+            Do([this](const RCSResourceAttributes&, int){ Proceed(); });
 
     server->setAttribute(ATTR_KEY, ATTR_VALUE + 1);
 
@@ -333,15 +333,15 @@ TEST_F(RemoteResourceObjectTest, DISABLED_CacheUpdatedCallbackBeCalledWithUpdate
     constexpr int newValue = ATTR_VALUE + 1;
 
     mocks.OnCallFunc(cacheUpdatedCallback).
-            Do([this](const RCSResourceAttributes&){ Proceed(); });
+            Do([this](const RCSResourceAttributes&, int){ Proceed(); });
     object->startCaching(cacheUpdatedCallback);
     Wait();
 
     mocks.ExpectCallFunc(cacheUpdatedCallback).
-            Match([this](const RCSResourceAttributes& attrs){
+            Match([this](const RCSResourceAttributes& attrs, int){
                 return attrs.at(ATTR_KEY) == newValue;
             }).
-            Do([this](const RCSResourceAttributes&){ Proceed(); });
+            Do([this](const RCSResourceAttributes&, int){ Proceed(); });
 
     server->setAttribute(ATTR_KEY, newValue);
 
@@ -356,7 +356,7 @@ TEST_F(RemoteResourceObjectTest, GetCachedAttributesThrowsIfCachingIsNotStarted)
 TEST_F(RemoteResourceObjectTest, CachedAttributesHasSameAttributesWithServer)
 {
     mocks.OnCallFunc(cacheUpdatedCallback).
-            Do([this](const RCSResourceAttributes&){ Proceed(); });
+            Do([this](const RCSResourceAttributes&, int){ Proceed(); });
     object->startCaching(cacheUpdatedCallback);
     Wait();
 
@@ -373,7 +373,7 @@ TEST_F(RemoteResourceObjectTest, GetCachedAttributeThrowsIfCachingIsNotStarted)
 TEST_F(RemoteResourceObjectTest, GetCachedAttributeThrowsIfKeyIsInvalid)
 {
     mocks.OnCallFunc(cacheUpdatedCallback).
-            Do([this](const RCSResourceAttributes&){ Proceed(); });
+            Do([this](const RCSResourceAttributes&, int){ Proceed(); });
     object->startCaching(cacheUpdatedCallback);
     Wait();
 
index eefada7..69cf3c8 100755 (executable)
@@ -68,7 +68,6 @@ if target_os not in ['darwin', 'ios', 'windows']:
 
 if target_os in ['linux']:
     scenemanager_env.AppendUnique(LIBS = ['pthread'])
-    
 
 if target_os == 'android':
     scenemanager_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions'])
@@ -81,7 +80,7 @@ if not env.get('RELEASE') and target_os not in ['ios']:
 ######################################################################
 # Source files and Targets
 ######################################################################
-SCENE_SRC_DIR = './src/' 
+SCENE_SRC_DIR = './src/'
 scenemanager_src = Glob(SCENE_SRC_DIR + '*.cpp')
 
 if target_os in ['tizen','android'] :
index 6bb66fc..da90c64 100755 (executable)
 \r
 #include <fstream>\r
 #include <algorithm>\r
+#if defined (__TIZENRT__)\r
+#include <apps/netutils/cJSON.h>\r
+#else\r
 #include "cJSON.h"\r
+#endif\r
 #include "yaml-cpp/yaml.h"\r
 #include "yaml-cpp/exceptions.h"\r
 #include "RamlUtils.h"\r
index 826e67d..bbd1aaf 100755 (executable)
@@ -90,9 +90,9 @@ namespace RAML
 \r
         cJSON *jsonAdditionalProperties = cJSON_GetObjectItem(m_cjson, "additionalProperties");\r
         if (jsonAdditionalProperties)\r
-            m_additionalProperties = jsonAdditionalProperties->type;\r
+            m_additionalProperties = (jsonAdditionalProperties->type == cJSON_True);\r
         else\r
-            m_additionalProperties = cJSON_True;\r
+            m_additionalProperties = true;\r
 \r
         cJSON *jsonReference = cJSON_GetObjectItem(m_cjson, "$ref");\r
         if (jsonReference)\r
@@ -230,11 +230,11 @@ namespace RAML
         std::string attType;\r
         if (propertyType)\r
         {\r
-            if (propertyType->type == 4)\r
+            if (propertyType->type == cJSON_String)\r
             {\r
                 attType = propertyType->valuestring;\r
             }\r
-            else if (propertyType->type == 5)\r
+            else if (propertyType->type == cJSON_Array)\r
             {\r
                 attType = cJSON_GetArrayItem(propertyType, 0)->valuestring;\r
             }\r
@@ -260,22 +260,22 @@ namespace RAML
     void JsonSchema::readDefaultValue(cJSON *defaultValue,  PropertiesPtr &property,\r
                                       const std::string &attType)\r
     {\r
-        if (defaultValue->type == 4)\r
+        if (defaultValue->type == cJSON_String)\r
         {\r
             property->setValue((std::string)defaultValue->valuestring);\r
         }\r
-        else if (defaultValue->type == 3)\r
+        else if (defaultValue->type == cJSON_Number)\r
         {\r
             if (attType == "number")\r
                 property->setValue((double)defaultValue->valuedouble);\r
             else\r
                 property->setValue((int)defaultValue->valueint );\r
         }\r
-        else if (defaultValue->type == 1)\r
+        else if (defaultValue->type == cJSON_True)\r
         {\r
             property->setValue((bool)true);\r
         }\r
-        else if (defaultValue->type == 0)\r
+        else if (defaultValue->type == cJSON_False)\r
         {\r
             property->setValue((bool)false);\r
         }\r
@@ -284,7 +284,7 @@ namespace RAML
     void JsonSchema::readAllowedValues(cJSON *allowedvalues,  PropertiesPtr &property,\r
                                        std::string &attType)\r
     {\r
-        if ((cJSON_GetArrayItem(allowedvalues, 0)->type) == 4)\r
+        if ((cJSON_GetArrayItem(allowedvalues, 0)->type) == cJSON_String)\r
         {\r
             int size = cJSON_GetArraySize(allowedvalues);\r
             int idx = 0;\r
@@ -298,7 +298,7 @@ namespace RAML
             if (attType.empty())\r
                 attType = "string";\r
         }\r
-        else if ((cJSON_GetArrayItem(allowedvalues, 0)->type) == 3)\r
+        else if ((cJSON_GetArrayItem(allowedvalues, 0)->type) == cJSON_Number)\r
         {\r
             int size = cJSON_GetArraySize(allowedvalues);\r
             int idx = 0;\r
@@ -325,15 +325,15 @@ namespace RAML
                     attType = "integer";\r
             }\r
         }\r
-        else if (((cJSON_GetArrayItem(allowedvalues, 0)->type) == 1)\r
-                 || ((cJSON_GetArrayItem(allowedvalues, 0)->type) == 0))\r
+        else if (((cJSON_GetArrayItem(allowedvalues, 0)->type) == cJSON_True)\r
+                 || ((cJSON_GetArrayItem(allowedvalues, 0)->type) == cJSON_False))\r
         {\r
             int size = cJSON_GetArraySize(allowedvalues);\r
             int idx = 0;\r
             std::vector<bool> allwdValues;\r
             do\r
             {\r
-                if (cJSON_GetArrayItem(allowedvalues, idx)->type)\r
+                if (cJSON_GetArrayItem(allowedvalues, idx)->type != cJSON_False)\r
                     allwdValues.push_back(true);\r
                 else\r
                     allwdValues.push_back(false);\r
@@ -508,7 +508,7 @@ namespace RAML
         cJSON *itemValues = cJSON_GetObjectItem(childProperties, "items");\r
         if (itemValues)\r
         {\r
-            if (itemValues->type == 5)\r
+            if (itemValues->type == cJSON_Array)\r
             {\r
                 //int item_size = cJSON_GetArraySize(itemValues);\r
                 int item_index = 0;\r
@@ -527,7 +527,7 @@ namespace RAML
         }\r
         cJSON *itemsMax = cJSON_GetObjectItem(childProperties, "maxItems");\r
         int min = INT_MIN, max = INT_MAX;\r
-        bool unique = cJSON_False, addItems = cJSON_False;\r
+        bool unique = false, addItems = false;\r
         if (itemsMax)\r
         {\r
             cJSON *exclusiveMax = cJSON_GetObjectItem(childProperties, "exclusiveMaximum");\r
@@ -558,12 +558,12 @@ namespace RAML
         cJSON *uniqueItems = cJSON_GetObjectItem(childProperties, "uniqueItems");\r
         if (uniqueItems)\r
         {\r
-            unique = uniqueItems->type;\r
+            unique = (uniqueItems->type == cJSON_True);\r
         }\r
         cJSON *additionalItems = cJSON_GetObjectItem(childProperties, "additionalItems");\r
         if (additionalItems)\r
         {\r
-            addItems = additionalItems->type;\r
+            addItems = (additionalItems->type == cJSON_True);\r
         }\r
         property->setValueProperty(std::make_shared<ValueProperty>\r
                                    (ValueProperty::Type::ARRAY, min, max, unique, addItems));\r
index 333e571..15490d1 100755 (executable)
 #include <map>\r
 #include "Properties.h"\r
 #include "Definitions.h"\r
+#if defined (__TIZENRT__)\r
+#include <apps/netutils/cJSON.h>\r
+#else\r
 #include "cJSON.h"\r
+#endif\r
 #include <memory>\r
 \r
 #include "IncludeResolver.h"\r
index dd784d8..03dd243 100755 (executable)
 #include <boost/variant.hpp>\r
 #include <boost/lexical_cast.hpp>\r
 #include <limits>\r
+#if defined (__TIZENRT__)\r
+#include <apps/netutils/cJSON.h>\r
+#else\r
 #include "cJSON.h"\r
+#endif\r
 #include <memory>\r
 \r
 namespace RAML\r
index 855d8f4..482919b 100755 (executable)
 #include "yaml-cpp/exceptions.h"\r
 #include "RamlExceptions.h"\r
 #include "RamlUtils.h"\r
+#if defined (__TIZENRT__)\r
+#include <apps/netutils/cJSON.h>\r
+#else\r
 #include "cJSON.h"\r
+#endif\r
 \r
 \r
 namespace RAML\r
index b50233e..658538f 100755 (executable)
 #define SCHEMAS_H\r
 \r
 #include <string>\r
+#if defined (__TIZENRT__)\r
+#include <apps/netutils/cJSON.h>\r
+#else\r
 #include "cJSON.h"\r
+#endif\r
 #include "IncludeResolver.h"\r
 \r
 #include "JsonSchema.h"\r
index 6d88723..f824140 100644 (file)
@@ -1,11 +1,12 @@
 # -*- coding: utf-8 -*-
 
+# -- Dual Licence ----------------------------------------------------------
+
 ############################################################################
 # GPL License                                                              #
 #                                                                          #
 # This file is a SCons (http://www.scons.org/) builder                     #
 # Copyright (c) 2012-14, Philipp Kraus, <philipp.kraus@flashpixx.de>       #
-# 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       #
 # along with this program. If not, see <http://www.gnu.org/licenses/>.     #
 ############################################################################
 
-# the URLDownload-Builder can download any data from an URL into a target
-# file. The target name is used are the file name of the downloaded file.
+# --------------------------------------------------------------------------
+
+############################################################################
+# BSD 3-Clause License                                                     #
+#                                                                          #
+# This file is a SCons (http://www.scons.org/) builder                     #
+# Copyright (c) 2012-14, Philipp Kraus, <philipp.kraus@flashpixx.de>       #
+# 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 its         #
+# contributors may be used to endorse or promote products derived from     #
+# this software without specific prior written permission.                 #
+#                                                                          #
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS      #
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT        #
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A  #
+# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT       #
+# 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.             #
+############################################################################
+
+
+
+# the URLDownload-Builder can be download any data from an URL into a target file
+# and can replace the target file name with the URL filename (the setting variable
+# within the environment object is a boolean type with the name "URLDOWNLOAD_USEURLFILENAM", 
+# default setting replaces the target name with the URL filename)
 
-# This builder originated from work by Philipp Kraus and flashpixx project
-# (see https://github.com/flashpixx). It has been modified to leverage
-# the HTTP ETag header to be used as the csig. This allows the download
-# builder to determine if the file should be downloaded again when the
-# ETag header is supported
 
-import os, time
 import urllib2, urlparse
 import SCons.Builder, SCons.Node, SCons.Errors
 
-# Define a source node to represent the remote file. The construction of the
-# node will query the hosting site to get the ETag, size and last-modified
-# date.  This node also defines the method by which we will determine if
-# the file should be downloaded again.
-#
-# This node derives from the Python.Value node
-#
+
+# define an own node, for checking the data behind the URL,
+# we must download only than, if the data is changed, the
+# node derivates from the Python.Value node
 class URLNode(SCons.Node.Python.Value) :
-    def make_ready(self) :
+
+    # overload the get_csig (copy the source from the
+    # Python.Value node and append the data of the URL header
+    def get_csig(self, calc=None): 
+        try: 
+            return self.ninfo.csig 
+        except AttributeError: 
+            pass 
+        
         try :
-            stream = urllib2.urlopen( str(self.value) )
-            info = stream.info()
-
-            self.url_etag = None
-            self.url_last_modified = None
-            self.url_content_length = None
-
-            if 'ETag' in info :
-                self.url_etag = info['ETag']
-            if 'Last-Modified' in info :
-                self.url_last_modified = time.mktime(time.strptime(info['Last-Modified'], '%a, %d %b %Y %H:%M:%S GMT'))
-            if 'Content-Length' in info :
-                self.url_content_legth = info['Content-Length']
+            response = urllib2.urlopen( str(self.value) ).info()
         except Exception, e :
-            raise SCons.Errors.StopError( '%s [%s]' % (e, self.value) )
-
-    def visited(self) :
-        ninfo = self.get_ninfo()
-
-        if self.url_etag :
-            ninfo.csig = self.url_etag
-        if self.url_last_modified :
-            ninfo.timestamp = self.url_last_modified
-        if self.url_content_length :
-            ninfo.size = self.url_content_length
-        SCons.Node.Node.visited(self);
-
-    def changed_since_last_build(self, target, prev_ni):
-        if prev_ni :
-            if self.url_etag :
-                if prev_ni.csig == self.url_etag :
-                    # print 'Matched on ETag:'+prev_ni.csig
-                    return False
-
-            if not self.url_last_modified :
-                # print 'Last modified date is not available'
-                return True
-            if not self.url_content_length :
-                # print 'Content length is not available'
-                return True
-            if prev_ni.timestamp != self.url_last_modified :
-                # print 'Modified since last build'
-                return True
-            if prev_ni.size != self.url_content_length :
-                # print 'Content length has changed'
-                return True
-
-            return False
-
-        # print 'Not previous built'
-        return True
-
-# Creates the output message
+            raise SCons.Errors.StopError( "%s [%s]" % (e, self.value) )
+            
+        contents = ""
+        if "Last-Modified" in response :
+            contents = contents + response["Last-Modified"]
+        if "Content-Length" in response :
+            contents = contents + response["Content-Length"]
+        if not contents :
+            contents = self.get_contents() 
+        self.get_ninfo().csig = contents 
+        return contents 
+
+
+
+# creates the downloading 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 'downloading [%s] from [%s] ...' % (target[0], source[0])
+def __message( s, target, source, env ) : 
+    print "downloading [%s] to [%s] ..." % (source[0], target[0])
 
-# Creates the action ie. the download function.
-# This reads the data from the URL and writes it down to the file
+
+# the download function, which reads the data from the URL
+# and writes it down to the file
 # @param target target file on the local drive
 # @param source URL for download
 # @@param env environment object
 def __action( target, source, env ) :
     try :
-        source_name = str(source[0])
-        target_name = str(target[0])
-        stream = urllib2.urlopen(source_name)
-        file = open( target_name, 'wb' )
+        stream = urllib2.urlopen( str(source[0]) )
+        file   = open( str(target[0]), "wb" )
         file.write(stream.read())
         file.close()
-
-        # Change the access/modified time to match
-        # the date on the downloaded file, if available
-        ninfo = source[0].get_ninfo()
-        if hasattr(ninfo, 'timestamp') :
-            mtime = ninfo.timestamp
-            if mtime :
-                os.utime(target_name, (mtime, mtime))
+        stream.close()
     except Exception, e :
-        raise SCons.Errors.StopError( '%s [%s]' % (e, source[0]) )
+        raise SCons.Errors.StopError( "%s [%s]" % (e, source[0]) )
 
 
-# Defines the emitter of the builder
+# defines the emitter of the builder
 # @param target target file on the local drive
 # @param source URL for download
 # @param env environment object
 def __emitter( target, source, env ) :
-    return target, source
+    # we need a temporary file, because the dependency graph
+    # of Scons need a physical existing file - so we prepare it
+    target[0].prepare()
+
+    if not env.get("URLDOWNLOAD_USEURLFILENAME", False) :
+        return target, source
+
+    try :
+        url = urlparse.urlparse( urllib2.urlopen( str(source[0]) ).geturl() )
+    except Exception, e :
+        raise SCons.Errors.StopError( "%s [%s]" % (e, source[0]) )
+
+    return url.path.split("/")[-1], source
+
+
+
 
 # generate function, that adds the builder to the environment,
+# the value "DOWNLOAD_USEFILENAME" replaces the target name with
+# the filename of the URL
 # @param env environment object
 def generate( env ) :
-    env['BUILDERS']['URLDownload'] = SCons.Builder.Builder( action = __action,  emitter = __emitter,  target_factory = SCons.Node.FS.File,  source_factory = URLNode,  single_source = True,  PRINT_CMD_LINE_FUNC = __message )
+    env["BUILDERS"]["URLDownload"] = SCons.Builder.Builder( action = __action,  emitter = __emitter,  target_factory = SCons.Node.FS.File,  source_factory = URLNode,  single_source = True,  PRINT_CMD_LINE_FUNC = __message )
+    env.Replace(URLDOWNLOAD_USEURLFILENAME =  True )
+
 
 # existing function of the builder
 # @param env environment object
 # @return true
 def exists(env) :
-    return 1
+    return 1
\ No newline at end of file
index f0f0810..1b0557a 100644 (file)
@@ -1,11 +1,12 @@
 # -*- coding: utf-8 -*-
 
+# -- Dual Licence ----------------------------------------------------------
+
 ############################################################################
 # GPL License                                                              #
 #                                                                          #
 # This file is a SCons (http://www.scons.org/) builder                     #
 # Copyright (c) 2012-14, Philipp Kraus, <philipp.kraus@flashpixx.de>       #
-# 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       #
 # along with this program. If not, see <http://www.gnu.org/licenses/>.     #
 ############################################################################
 
-# 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.
+# --------------------------------------------------------------------------
+
+############################################################################
+# BSD 3-Clause License                                                     #
+#                                                                          #
+# This file is a SCons (http://www.scons.org/) builder                     #
+# Copyright (c) 2012-14, Philipp Kraus, <philipp.kraus@flashpixx.de>       #
+# 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 its         #
+# contributors may be used to endorse or promote products derived from     #
+# this software without specific prior written permission.                 #
+#                                                                          #
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS      #
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT        #
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A  #
+# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT       #
+# 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.             #
+############################################################################
+
+
 
 # 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"):
+# 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
 
 
 import subprocess, os
-import SCons.Errors, SCons.Warnings, SCons.Util
+
+import SCons.Errors, SCons.Warnings
+import SCons.Util
+
 
 # enables Scons warning for this builder
 class UnpackWarning(SCons.Warnings.Warning) :
@@ -67,6 +104,8 @@ class UnpackWarning(SCons.Warnings.Warning) :
 
 SCons.Warnings.enableWarningClass(UnpackWarning)
 
+
+
 # extractor function for Tar output
 # @param env environment object
 # @param count number of returning lines
@@ -115,10 +154,11 @@ def __fileextractor_win_7zip( env, count, no, i ) :
 # @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
+    # we check each unpacker and get the correc  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 the run command not set, we continue the extractor search, otherwise we check the extractor parameters
         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"]) :
@@ -159,16 +199,15 @@ def __message( s, target, source, env ) :
 # action function for extracting of the data
 # @param target target packed file
 # @param source extracted files
-# @param env environment object
+# @env environment object
 def __action( target, source, env ) :
     extractor = __getExtractor(source, env)
     if not extractor :
         raise SCons.Errors.StopError( "can not find any extractor value for the source file [%s]" % (source[0]) )
 
-    extractor_cmd = extractor["EXTRACTCMD"]
 
     # if the extract command is empty, we create an error
-    if len(extractor_cmd) == 0 :
+    if len(extractor["EXTRACTCMD"]) == 0 :
         raise SCons.Errors.StopError( "the extractor command for the source file [%s] is empty" % (source[0]) )
 
     # build it now (we need the shell, because some programs need it)
@@ -177,7 +216,7 @@ def __action( target, source, env ) :
     source_path = os.path.realpath(source[0].path)
     target_path = os.path.realpath(target[0].path)
 
-    cmd = env.subst(extractor_cmd, source=source_path, target=target)
+    cmd = env.subst(extractor["EXTRACTCMD"], source=source_path, target=target)
     cwd = os.path.dirname(source_path)
 
     if env["UNPACK"]["VIWEXTRACTOUTPUT"] :
@@ -187,7 +226,7 @@ def __action( target, source, env ) :
         handle  = subprocess.Popen( cmd, shell=True, stdout=devnull, cwd=cwd)
 
     if handle.wait() <> 0 :
-        raise SCons.Errors.BuildError( "error running extractor [%s] on the source [%s]" % (cmd, source[0]) )
+        raise SCons.Errors.BuildError( "error running extractor [%s] on the source [%s]" % (cmd, source[0])  )
 
     fhandle = open(target_path, 'a')
     try:
@@ -200,13 +239,15 @@ def __action( target, source, env ) :
 # within the archive
 # @param target target packed file
 # @param source extracted files
-# @param env environment object
+# @env environment object
 def __emitter( target, source, env ) :
     return target, source
 
 
+
+
 # generate function, that adds the builder to the environment
-# @param env environment object
+# @env environment object
 def generate( env ) :
     # setup environment variable
     toolset = {
@@ -297,7 +338,7 @@ def generate( env ) :
     # read tools for Windows system
     if env["PLATFORM"] <> "darwin" and "win" in env["PLATFORM"] :
 
-        if env.WhereIs("7z") :
+        if env.WhereIs("7z"):
             toolset["EXTRACTOR"]["TARGZ"]["RUN"]           = "7z"
             toolset["EXTRACTOR"]["TARGZ"]["LISTEXTRACTOR"] = __fileextractor_win_7zip
             toolset["EXTRACTOR"]["TARGZ"]["LISTFLAGS"]     = "x"
@@ -396,4 +437,4 @@ def generate( env ) :
 # @param env environment object
 # @return true
 def exists(env) :
-    return 1
+    return 1
\ No newline at end of file
index 4fc2afe..90d704d 100755 (executable)
@@ -1,36 +1,79 @@
 [general]
-#Current profile name which should match a profile section name
-profile = profile.tizen
-
-[profile.tizen]
-#Common authentication info for whole profile
-#user =
-#CAUTION: please use the key name "passwd" to reset plaintext password
-#passwd =
-obs = obs.tizen
-#Comma separated list of repositories
-repos = repo.public_latest, repo.devel-gcc49-base,
-#repos = repo.tizen_main, repo.tizen_base
-#Build config for gbs build
-#buildconf = <patch/to/build-config-file>
-#Comma separated list of additional packages be excluded building
-#exclude_packages = libtool,gettext
-
-
-[obs.tizen]
-#OBS API URL pointing to a remote OBS.
-url = https://api.tizen.org
-#Optional user and password, set if differ from profile's user and password
-#user =
-#passwd =
-
-#Repo section example
-[repo.public_latest]
-#Build against repo's URL
-url = http://download.tizen.org/snapshots/2.4-mobile/common/latest/repos/target-TM1/packages/
-#Optional user and password, set if differ from profile's user and password
-#user =
-#passwd =
-
-[repo.devel-gcc49-base]
-url = http://download.tizen.org/releases/2.4/2.4-base/tizen-2.4-base_20151027.1/repos/standard/packages/
+#profile = profile.Main2017_JazzM
+profile = profile.Main2017_KantM
+#profile = profile.Main2017_KantS
+#profile = profile.Main2017_NT16M
+
+[obs.tizentv]
+url = https://168.219.241.169/api
+user = obs_viewer
+passwd = obs_viewer_169
+
+
+############################################################################################
+[repo.base_Main2017]
+url=http://168.219.244.109/tizen-rsa/tizen-3.0-base-main2017/standard/latest/repos/base/armv7l/packages/
+
+[repo.base_ca9_Main2017]
+url=http://168.219.244.109/tizen-rsa/tizen-3.0-base-main2017/standard-ca9/latest/repos/base/armv7l/packages/
+############################################################################################
+
+
+############################################################################################
+# For Main2017(JazzM)
+[profile.Main2017_JazzM]
+obs = obs.tizentv
+repos = repo.product_Main2017_JazzM, repo.base_Main2017, repo.local_Main2017_JazzM
+buildroot = ~/GBS-ROOT
+
+[repo.product_Main2017_JazzM]
+url=http://168.219.244.109/releases/00_RELEASED_IMAGES/2017/MAIN2017/JazzM/latest/repos/product/armv7l/packages/
+
+[repo.local_Main2017_JazzM]
+url=~/GBS-ROOT/local/repos/Main2017_JazzM/armv7l
+############################################################################################
+
+
+############################################################################################
+# For Main2017(KantM)
+[profile.Main2017_KantM]
+obs = obs.tizentv
+repos = repo.product_Main2017_KantM, repo.base_Main2017, repo.local_Main2017_KantM
+buildroot = ~/GBS-ROOT
+
+[repo.product_Main2017_KantM]
+url=http://168.219.244.109/releases/00_RELEASED_IMAGES/2017/MAIN2017/KantM/latest/repos/product/armv7l/packages/
+
+[repo.local_Main2017_KantM]
+url=~/GBS-ROOT/local/repos/Main2017_KantM/armv7l
+############################################################################################
+
+
+############################################################################################
+# For Main2017(KantS)
+[profile.Main2017_KantS]
+obs = obs.tizentv
+repos = repo.product_Main2017_KantS, repo.base_Main2017, repo.local_Main2017_KantS
+buildroot = ~/GBS-ROOT
+
+[repo.product_Main2017_KantS]
+url=http://168.219.244.109/releases/00_RELEASED_IMAGES/2017/MAIN2017/KantS/latest/repos/product/armv7l/packages/
+
+[repo.local_Main2017_KantS]
+url=~/GBS-ROOT/local/repos/Main2017_KantS/armv7l
+############################################################################################
+
+
+############################################################################################
+# For Main2017(NT16M)
+[profile.Main2017_NT16M]
+obs = obs.tizentv
+repos = repo.product_Main2017_NT16M, repo.base_ca9_Main2017, repo.local_Main2017_NT16M
+buildroot = ~/GBS-ROOT
+
+[repo.product_Main2017_NT16M]
+url=http://168.219.244.109/releases/00_RELEASED_IMAGES/2017/MAIN2017/NT16M/latest/repos/product/armv7l/packages/
+
+[repo.local_Main2017_NT16M]
+url=~/GBS-ROOT/local/repos/Main2017_NT16M/armv7l
+############################################################################################ 
\ No newline at end of file
diff --git a/tools/tizen/.gbs.vd.tv.tizen30.conf b/tools/tizen/.gbs.vd.tv.tizen30.conf
new file mode 100755 (executable)
index 0000000..90d704d
--- /dev/null
@@ -0,0 +1,79 @@
+[general]
+#profile = profile.Main2017_JazzM
+profile = profile.Main2017_KantM
+#profile = profile.Main2017_KantS
+#profile = profile.Main2017_NT16M
+
+[obs.tizentv]
+url = https://168.219.241.169/api
+user = obs_viewer
+passwd = obs_viewer_169
+
+
+############################################################################################
+[repo.base_Main2017]
+url=http://168.219.244.109/tizen-rsa/tizen-3.0-base-main2017/standard/latest/repos/base/armv7l/packages/
+
+[repo.base_ca9_Main2017]
+url=http://168.219.244.109/tizen-rsa/tizen-3.0-base-main2017/standard-ca9/latest/repos/base/armv7l/packages/
+############################################################################################
+
+
+############################################################################################
+# For Main2017(JazzM)
+[profile.Main2017_JazzM]
+obs = obs.tizentv
+repos = repo.product_Main2017_JazzM, repo.base_Main2017, repo.local_Main2017_JazzM
+buildroot = ~/GBS-ROOT
+
+[repo.product_Main2017_JazzM]
+url=http://168.219.244.109/releases/00_RELEASED_IMAGES/2017/MAIN2017/JazzM/latest/repos/product/armv7l/packages/
+
+[repo.local_Main2017_JazzM]
+url=~/GBS-ROOT/local/repos/Main2017_JazzM/armv7l
+############################################################################################
+
+
+############################################################################################
+# For Main2017(KantM)
+[profile.Main2017_KantM]
+obs = obs.tizentv
+repos = repo.product_Main2017_KantM, repo.base_Main2017, repo.local_Main2017_KantM
+buildroot = ~/GBS-ROOT
+
+[repo.product_Main2017_KantM]
+url=http://168.219.244.109/releases/00_RELEASED_IMAGES/2017/MAIN2017/KantM/latest/repos/product/armv7l/packages/
+
+[repo.local_Main2017_KantM]
+url=~/GBS-ROOT/local/repos/Main2017_KantM/armv7l
+############################################################################################
+
+
+############################################################################################
+# For Main2017(KantS)
+[profile.Main2017_KantS]
+obs = obs.tizentv
+repos = repo.product_Main2017_KantS, repo.base_Main2017, repo.local_Main2017_KantS
+buildroot = ~/GBS-ROOT
+
+[repo.product_Main2017_KantS]
+url=http://168.219.244.109/releases/00_RELEASED_IMAGES/2017/MAIN2017/KantS/latest/repos/product/armv7l/packages/
+
+[repo.local_Main2017_KantS]
+url=~/GBS-ROOT/local/repos/Main2017_KantS/armv7l
+############################################################################################
+
+
+############################################################################################
+# For Main2017(NT16M)
+[profile.Main2017_NT16M]
+obs = obs.tizentv
+repos = repo.product_Main2017_NT16M, repo.base_ca9_Main2017, repo.local_Main2017_NT16M
+buildroot = ~/GBS-ROOT
+
+[repo.product_Main2017_NT16M]
+url=http://168.219.244.109/releases/00_RELEASED_IMAGES/2017/MAIN2017/NT16M/latest/repos/product/armv7l/packages/
+
+[repo.local_Main2017_NT16M]
+url=~/GBS-ROOT/local/repos/Main2017_NT16M/armv7l
+############################################################################################ 
\ No newline at end of file
diff --git a/tools/tizen/iotivity-vd-tv-es-tizen30.spec b/tools/tizen/iotivity-vd-tv-es-tizen30.spec
new file mode 100644 (file)
index 0000000..5f5187a
--- /dev/null
@@ -0,0 +1,360 @@
+Name: iotivity
+Version: 1.2.1
+Release: 0
+Summary: IoT Connectivity sponsored by the OCF
+Group: Network & Connectivity / IoT Connectivity
+License: Apache-2.0
+URL: https://www.iotivity.org/
+Source0: http://mirrors.kernel.org/%{name}/%{version}/%{name}-%{version}.tar.gz
+Source1001: %{name}.manifest
+Source1002: %{name}-test.manifest
+
+%if 0%{?tizen:1}
+%define TARGET_OS tizen
+%else
+%define TARGET_OS linux
+%endif
+
+%if "%{tizen}" == "2.3"
+%define TARGET_TRANSPORT IP
+%endif
+
+%if "%{profile}" == "ivi"
+%define TARGET_TRANSPORT IP
+%endif
+
+%if "%{TARGET_OS}" == "linux"
+%define TARGET_TRANSPORT IP
+%endif
+
+%define JOB "-j4"
+%if 0%{?speedpython}
+%define JOB %{?_smp_mflags}
+%endif
+%if 0%{?speedpython:1} && 0%{?en_speedpython:1}
+%en_speedpython
+%endif
+
+# default is RELEASE mode.
+# If DEBUG mode is needed, please use tizen_build_devel_mode
+%define RELEASE True
+# For Example
+%if %{RELEASE} == "True"
+%define build_mode release
+%else
+%define build_mode debug
+%endif
+
+%ifarch armv7l armv7hl armv7nhl armv7tnhl armv7thl
+%define TARGET_ARCH "armeabi-v7a"
+%endif
+%ifarch aarch64
+%define TARGET_ARCH "arm64"
+%endif
+%ifarch x86_64
+%define TARGET_ARCH "x86_64"
+%endif
+%ifarch %{ix86}
+%define TARGET_ARCH "x86"
+%endif
+
+%define ex_install_dir %{buildroot}%{_bindir}
+
+%if ! 0%{?license:0}
+%define license %doc
+%endif
+
+%if ! 0%{?manifest:0}
+%define manifest %doc
+%endif
+
+# Default values to be eventually overiden BEFORE or as gbs params:
+%{!?ES_TARGET_ENROLLEE: %define ES_TARGET_ENROLLEE tizen}
+%{!?LOGGING: %define LOGGING 1}
+%{!?RD_MODE: %define RD_MODE CLIENT}
+%{!?RELEASE: %define RELEASE 1}
+%{!?ROUTING: %define ROUTING EP}
+%{!?SECURED: %define SECURED 1}
+%{!?TARGET_ARCH: %define TARGET_ARCH %{_arch}}
+%{!?TARGET_OS: %define TARGET_OS tizen}
+%{!?TARGET_TRANSPORT: %define TARGET_TRANSPORT IP,BLE}
+%{!?VERBOSE: %define VERBOSE 1}
+%{!?WITH_CLOUD: %define WITH_CLOUD 1}
+%{!?WITH_MQ: %define WITH_MQ OFF}
+%{!?WITH_PROXY: %define WITH_PROXY 0}
+%{!?WITH_TCP: %define WITH_TCP 1}
+%{!?RD_MODE: %define RD_MODE CLIENT}
+%{!?BLE_CUSTOM_ADV: %define BLE_CUSTOM_ADV False}
+%{!?BLE_DIVISION: %define BLE_DIVISION VD}
+%{!?BLE_TIZEN_30: %define BLE_TIZEN_30 True}
+%{!?MULTIPLE_OWNER: %define MULTIPLE_OWNER 0}
+
+BuildRequires:  expat-devel
+BuildRequires:  python, libcurl-devel
+BuildRequires:  scons
+BuildRequires:  openssl-devel
+BuildRequires:  boost-devel
+BuildRequires:  boost-thread
+BuildRequires:  boost-system
+BuildRequires:  boost-filesystem
+BuildRequires:  pkgconfig(uuid)
+BuildRequires:  pkgconfig(glib-2.0)
+BuildRequires:  pkgconfig(sqlite3)
+%if "%{TARGET_OS}" == "tizen"
+BuildRequires:  gettext-tools
+BuildRequires:  pkgconfig(dlog)
+BuildRequires:  pkgconfig(capi-network-connection)
+BuildRequires:  pkgconfig(capi-network-wifi)
+BuildRequires:  pkgconfig(capi-network-bluetooth) >= 0.1.52
+%else
+%if 0%{?fedora:1}
+BuildRequires:  sqlite-devel
+BuildRequires:  gettext-devel
+%endif
+%endif
+Requires(postun): /sbin/ldconfig
+Requires(post): /sbin/ldconfig
+
+%description
+An open source reference implementation of the OIC standard specifications
+IoTivity Base Libraries are included.
+
+
+%package service
+Summary: Development files for %{name}
+Group: Network & Connectivity/Service
+Requires: %{name} = %{version}-%{release}
+
+%description service
+The %{name}-service package contains service libraries files for
+developing applications that use %{name}-service.
+
+%package test
+Summary: Development files for %{name}
+Group: Network & Connectivity/Testing
+Requires: %{name} = %{version}-%{release}
+
+%description test
+The %{name}-test package contains example files to show
+how the iotivity works using %{name}-test
+
+%package devel
+Summary: Development files for %{name}
+Group: Network & Connectivity/Development
+Requires: %{name} = %{version}-%{release}
+Requires: pkgconfig
+
+%description devel
+The %{name}-devel package contains libraries and header files for
+developing applications that use %{name}.
+
+%prep
+%setup -q
+chmod g-w %_sourcedir/*
+
+cp LICENSE.md LICENSE
+
+cp %{SOURCE1001} .
+%if 0%{?tizen_version_major} < 3
+cp %{SOURCE1002} .
+%else
+cp %{SOURCE1001} ./%{name}-test.manifest
+%endif
+
+%build
+scons %{JOB} --prefix=%{_prefix} \
+    ES_TARGET_ENROLLEE=%{ES_TARGET_ENROLLEE} \
+    LIB_INSTALL_DIR=%{_libdir} \
+    LOGGING=%{LOGGING} \
+    RD_MODE=%{RD_MODE} \
+    RELEASE=%{RELEASE} \
+    ROUTING=%{ROUTING} \
+    SECURED=%{SECURED} \
+    TARGET_ARCH=%{TARGET_ARCH} \
+    TARGET_OS=%{TARGET_OS} \
+    TARGET_TRANSPORT=%{TARGET_TRANSPORT} \
+    VERBOSE=%{VERBOSE} \
+    WITH_CLOUD=%{WITH_CLOUD} \
+    WITH_MQ=%{WITH_MQ} \
+    WITH_PROXY=%{WITH_PROXY} \
+    WITH_TCP=%{WITH_TCP} \
+    RD_MODE=%{RD_MODE} \
+    BLE_CUSTOM_ADV=%{BLE_CUSTOM_ADV} \
+    BLE_DIVISION=%{BLE_DIVISION} \
+    BLE_TIZEN_30=%{BLE_TIZEN_30} \
+    MULTIPLE_OWNER=%{MULTIPLE_OWNER} \
+    #eol
+
+
+
+%install
+%if 0%{?tizen_version_major} < 3
+mkdir -p %{buildroot}/%{_datadir}/license
+cp LICENSE %{buildroot}/%{_datadir}/license/%{name}
+%endif
+rm -rf %{buildroot}
+CFLAGS="${CFLAGS:-%optflags}" ; export CFLAGS ;
+scons install --install-sandbox=%{buildroot} --prefix=%{_prefix} \
+    ES_TARGET_ENROLLEE=%{ES_TARGET_ENROLLEE} \
+    LIB_INSTALL_DIR=%{_libdir} \
+    LOGGING=%{LOGGING} \
+    RD_MODE=%{RD_MODE} \
+    RELEASE=%{RELEASE} \
+    ROUTING=%{ROUTING} \
+    SECURED=%{SECURED} \
+    TARGET_ARCH=%{TARGET_ARCH} \
+    TARGET_OS=%{TARGET_OS} \
+    TARGET_TRANSPORT=%{TARGET_TRANSPORT} \
+    VERBOSE=%{VERBOSE} \
+    WITH_CLOUD=%{WITH_CLOUD} \
+    WITH_MQ=%{WITH_MQ} \
+    WITH_PROXY=%{WITH_PROXY} \
+    WITH_TCP=%{WITH_TCP} \
+    RD_MODE=%{RD_MODE} \
+    BLE_CUSTOM_ADV=%{BLE_CUSTOM_ADV} \
+    BLE_DIVISION=%{BLE_DIVISION} \
+    BLE_TIZEN_30=%{BLE_TIZEN_30} \
+    MULTIPLE_OWNER=%{MULTIPLE_OWNER} \
+    #eol
+
+mkdir -p %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/examples/OICMiddle/OICMiddle %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/devicediscoveryclient %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/devicediscoveryserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/fridgeclient %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/fridgeserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/garageclient %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/garageserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/groupclient %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/groupserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/lightserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/presenceclient %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/presenceserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/roomclient %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/roomserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/simpleclient %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/simpleclientHQ %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/simpleclientserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/simpleserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/simpleserverHQ %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/threadingsample %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/oic_svr_db_server.dat %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/oic_svr_db_client.dat %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/libcoap.a %{buildroot}%{_libdir}
+cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/lib*.a  %{buildroot}%{_libdir}
+
+%if 0%{?WITH_PROXY} == 1
+mkdir -p %{ex_install_dir}/proxy-sample
+cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/service/coap-http-proxy/samples/proxy_main %{ex_install_dir}/proxy-sample/
+cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/service/coap-http-proxy/samples/proxy_client %{ex_install_dir}/proxy-sample/
+%endif
+%if 0%{?SECURED} == 1
+mkdir -p %{ex_install_dir}/provisioning
+mkdir -p %{ex_install_dir}/provision-sample
+
+cp -R ./extlibs/mbedtls/mbedtls/include/mbedtls/ %{buildroot}%{_includedir}/mbedtls
+cp ./resource/csdk/security/include/*.h %{buildroot}%{_includedir}
+cp ./resource/csdk/connectivity/api/*.h %{buildroot}%{_includedir}/
+cp ./resource/csdk/security/provisioning/include/oxm/*.h %{buildroot}%{_includedir}
+cp ./resource/csdk/security/provisioning/include/internal/*.h %{buildroot}%{_includedir}
+cp ./resource/csdk/security/provisioning/include/*.h %{buildroot}%{_includedir}
+cp ./resource/csdk/security/provisioning/sample/oic_svr_db_server_justworks.dat %{buildroot}%{_libdir}/oic_svr_db_server.dat
+cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/csdk/security/provisioning/sample/sampleserver_justworks %{ex_install_dir}/provision-sample/
+cp ./resource/csdk/security/provisioning/sample/oic_svr_db_server_justworks.dat %{ex_install_dir}/provision-sample/
+cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/csdk/security/provisioning/sample/sampleserver_randompin %{ex_install_dir}/provision-sample/
+cp ./resource/csdk/security/provisioning/sample/oic_svr_db_server_randompin.dat %{ex_install_dir}/provision-sample/
+
+%endif
+
+cp resource/c_common/*.h %{buildroot}%{_includedir}
+cp resource/c_common/ocrandom/include/*.h %{buildroot}%{_includedir}
+cp resource/c_common/oic_string/include/*.h %{buildroot}%{_includedir}
+cp resource/c_common/oic_malloc/include/*.h %{buildroot}%{_includedir}
+cp resource/csdk/stack/include/*.h %{buildroot}%{_includedir}
+cp resource/csdk/logger/include/*.h %{buildroot}%{_includedir}
+
+cp service/easy-setup/inc/*.h %{buildroot}%{_includedir}
+cp service/easy-setup/enrollee/inc/*.h %{buildroot}%{_includedir}
+cp service/easy-setup/enrollee/inc/samsung/*.h %{buildroot}%{_includedir}
+
+install -d %{buildroot}%{_includedir}/iotivity
+ln -fs ../resource %{buildroot}%{_includedir}/iotivity/
+ln -fs ../service %{buildroot}%{_includedir}/iotivity/
+ln -fs ../c_common %{buildroot}%{_includedir}/iotivity/
+
+rm -rfv out %{buildroot}/out %{buildroot}/${HOME} ||:
+
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+%files
+%manifest %{name}.manifest
+%defattr(-,root,root,-)
+%if 0%{?tizen_version_major} < 3
+%{_datadir}/license/%{name}
+%else
+%license LICENSE
+%endif
+%{_libdir}/liboc.so
+%{_libdir}/liboc_logger.so
+%{_libdir}/liboc_logger_core.so
+%{_libdir}/liboctbstack.so
+%{_libdir}/libconnectivity_abstraction.so
+%if 0%{?SECURED} == 1
+%{_libdir}/libmbedtls.so
+%{_libdir}/libocpmapi.so
+%{_libdir}/libocprovision.so
+%{_libdir}/oic_svr_db_server.dat
+%endif
+
+%files service
+%manifest %{name}.manifest
+%defattr(-,root,root,-)
+%if 0%{?tizen_version_major} < 3
+%{_datadir}/license/%{name}
+%else
+%license LICENSE
+%endif
+#%{_libdir}/libBMISensorBundle.so
+#%{_libdir}/libDISensorBundle.so
+#%{_libdir}/libHueBundle.so
+%{_libdir}/librcs_client.so
+%{_libdir}/librcs_common.so
+#%{_libdir}/librcs_container.so
+%{_libdir}/librcs_server.so
+%{_libdir}/libresource_directory.so
+%{_libdir}/libESEnrolleeSDK.so
+%{_libdir}/libESMediatorRich.so
+%{_libdir}/libnotification*.so
+%if 0%{?WITH_PROXY} == 1
+%{_libdir}/libcoap_http_proxy.so
+%endif
+%if "%{TARGET_OS}" == "linux"
+%{_libdir}/libnotification*.so
+%endif
+
+%files test
+%manifest %{name}-test.manifest
+%defattr(-,root,root,-)
+%if 0%{?tizen_version_major} < 3
+%{_datadir}/license/%{name}
+%else
+%license LICENSE
+%endif
+%{_bindir}/*
+
+%files devel
+%defattr(-,root,root,-)
+%if 0%{?tizen_version_major} < 3
+%{_datadir}/license/%{name}
+%else
+%license LICENSE
+%endif
+%if 0%{?SECURED} == 1
+%{_libdir}/libmbedtls.so
+%endif
+%{_libdir}/*.a
+%{_libdir}/pkgconfig/%{name}.pc
+%{_includedir}/*
diff --git a/tools/tizen/iotivity-vd-tv-tizen30.spec b/tools/tizen/iotivity-vd-tv-tizen30.spec
new file mode 100644 (file)
index 0000000..d220a07
--- /dev/null
@@ -0,0 +1,361 @@
+Name: iotivity
+Version: 1.2.1
+Release: 0
+Summary: IoT Connectivity sponsored by the OCF
+Group: Network & Connectivity / IoT Connectivity
+License: Apache-2.0
+URL: https://www.iotivity.org/
+Source0: http://mirrors.kernel.org/%{name}/%{version}/%{name}-%{version}.tar.gz
+Source1001: %{name}.manifest
+Source1002: %{name}-test.manifest
+
+%if 0%{?tizen:1}
+%define TARGET_OS tizen
+%else
+%define TARGET_OS linux
+%endif
+
+%if "%{tizen}" == "2.3"
+%define TARGET_TRANSPORT IP
+%endif
+
+%if "%{profile}" == "ivi"
+%define TARGET_TRANSPORT IP
+%endif
+
+%if "%{TARGET_OS}" == "linux"
+%define TARGET_TRANSPORT IP
+%endif
+
+%define JOB "-j4"
+%if 0%{?speedpython}
+%define JOB %{?_smp_mflags}
+%endif
+%if 0%{?speedpython:1} && 0%{?en_speedpython:1}
+%en_speedpython
+%endif
+
+# default is RELEASE mode.
+# If DEBUG mode is needed, please use tizen_build_devel_mode
+%define RELEASE True
+# For Example
+%if %{RELEASE} == "True"
+%define build_mode release
+%else
+%define build_mode debug
+%endif
+
+%ifarch armv7l armv7hl armv7nhl armv7tnhl armv7thl
+%define TARGET_ARCH "armeabi-v7a"
+%endif
+%ifarch aarch64
+%define TARGET_ARCH "arm64"
+%endif
+%ifarch x86_64
+%define TARGET_ARCH "x86_64"
+%endif
+%ifarch %{ix86}
+%define TARGET_ARCH "x86"
+%endif
+
+%define ex_install_dir %{buildroot}%{_bindir}
+
+%if ! 0%{?license:0}
+%define license %doc
+%endif
+
+%if ! 0%{?manifest:0}
+%define manifest %doc
+%endif
+
+# Default values to be eventually overiden BEFORE or as gbs params:
+%{!?ES_TARGET_ENROLLEE: %define ES_TARGET_ENROLLEE tizen}
+%{!?LOGGING: %define LOGGING 1}
+%{!?RD_MODE: %define RD_MODE CLIENT}
+%{!?RELEASE: %define RELEASE 1}
+%{!?ROUTING: %define ROUTING EP}
+%{!?SECURED: %define SECURED 1}
+%{!?TARGET_ARCH: %define TARGET_ARCH %{_arch}}
+%{!?TARGET_OS: %define TARGET_OS tizen}
+%{!?TARGET_TRANSPORT: %define TARGET_TRANSPORT IP,BLE}
+%{!?VERBOSE: %define VERBOSE 1}
+%{!?WITH_CLOUD: %define WITH_CLOUD 1}
+%{!?WITH_MQ: %define WITH_MQ OFF}
+%{!?WITH_PROXY: %define WITH_PROXY 0}
+%{!?WITH_TCP: %define WITH_TCP 1}
+%{!?RD_MODE: %define RD_MODE CLIENT}
+%{!?BLE_CUSTOM_ADV: %define BLE_CUSTOM_ADV False}
+%{!?BLE_DIVISION: %define BLE_DIVISION VD}
+%{!?BLE_TIZEN_30: %define BLE_TIZEN_30 True}
+%{!?MULTIPLE_OWNER: %define MULTIPLE_OWNER 0}
+
+BuildRequires:  expat-devel
+BuildRequires:  python, libcurl-devel
+BuildRequires:  scons
+BuildRequires:  openssl-devel
+BuildRequires:  boost-devel
+BuildRequires:  boost-thread
+BuildRequires:  boost-system
+BuildRequires:  boost-filesystem
+BuildRequires:  pkgconfig(uuid)
+BuildRequires:  pkgconfig(glib-2.0)
+BuildRequires:  pkgconfig(sqlite3)
+%if "%{TARGET_OS}" == "tizen"
+BuildRequires:  gettext-tools
+BuildRequires:  pkgconfig(dlog)
+BuildRequires:  pkgconfig(capi-network-connection)
+BuildRequires:  pkgconfig(capi-network-wifi)
+BuildRequires:  pkgconfig(capi-network-bluetooth) >= 0.1.52
+%else
+%if 0%{?fedora:1}
+BuildRequires:  sqlite-devel
+BuildRequires:  gettext-devel
+%endif
+%endif
+Requires(postun): /sbin/ldconfig
+Requires(post): /sbin/ldconfig
+
+%description
+An open source reference implementation of the OIC standard specifications
+IoTivity Base Libraries are included.
+
+
+%package service
+Summary: Development files for %{name}
+Group: Network & Connectivity/Service
+Requires: %{name} = %{version}-%{release}
+
+%description service
+The %{name}-service package contains service libraries files for
+developing applications that use %{name}-service.
+
+%package test
+Summary: Development files for %{name}
+Group: Network & Connectivity/Testing
+Requires: %{name} = %{version}-%{release}
+
+%description test
+The %{name}-test package contains example files to show
+how the iotivity works using %{name}-test
+
+%package devel
+Summary: Development files for %{name}
+Group: Network & Connectivity/Development
+Requires: %{name} = %{version}-%{release}
+Requires: pkgconfig
+
+%description devel
+The %{name}-devel package contains libraries and header files for
+developing applications that use %{name}.
+
+%prep
+%setup -q
+chmod g-w %_sourcedir/*
+
+cp LICENSE.md LICENSE
+
+cp %{SOURCE1001} .
+%if 0%{?tizen_version_major} < 3
+cp %{SOURCE1002} .
+%else
+cp %{SOURCE1001} ./%{name}-test.manifest
+%endif
+
+%build
+scons %{JOB} --prefix=%{_prefix} \
+    ES_TARGET_ENROLLEE=%{ES_TARGET_ENROLLEE} \
+    LIB_INSTALL_DIR=%{_libdir} \
+    LOGGING=%{LOGGING} \
+    RD_MODE=%{RD_MODE} \
+    RELEASE=%{RELEASE} \
+    ROUTING=%{ROUTING} \
+    SECURED=%{SECURED} \
+    TARGET_ARCH=%{TARGET_ARCH} \
+    TARGET_OS=%{TARGET_OS} \
+    TARGET_TRANSPORT=%{TARGET_TRANSPORT} \
+    VERBOSE=%{VERBOSE} \
+    WITH_CLOUD=%{WITH_CLOUD} \
+    WITH_MQ=%{WITH_MQ} \
+    WITH_PROXY=%{WITH_PROXY} \
+    WITH_TCP=%{WITH_TCP} \
+    RD_MODE=%{RD_MODE} \
+    BLE_CUSTOM_ADV=%{BLE_CUSTOM_ADV} \
+    BLE_DIVISION=%{BLE_DIVISION} \
+    BLE_TIZEN_30=%{BLE_TIZEN_30} \
+    MULTIPLE_OWNER=%{MULTIPLE_OWNER} \
+    #eol
+
+
+
+%install
+%if 0%{?tizen_version_major} < 3
+mkdir -p %{buildroot}/%{_datadir}/license
+cp LICENSE %{buildroot}/%{_datadir}/license/%{name}
+%endif
+rm -rf %{buildroot}
+CFLAGS="${CFLAGS:-%optflags}" ; export CFLAGS ;
+scons install --install-sandbox=%{buildroot} --prefix=%{_prefix} \
+    ES_TARGET_ENROLLEE=%{ES_TARGET_ENROLLEE} \
+    LIB_INSTALL_DIR=%{_libdir} \
+    LOGGING=%{LOGGING} \
+    RD_MODE=%{RD_MODE} \
+    RELEASE=%{RELEASE} \
+    ROUTING=%{ROUTING} \
+    SECURED=%{SECURED} \
+    TARGET_ARCH=%{TARGET_ARCH} \
+    TARGET_OS=%{TARGET_OS} \
+    TARGET_TRANSPORT=%{TARGET_TRANSPORT} \
+    VERBOSE=%{VERBOSE} \
+    WITH_CLOUD=%{WITH_CLOUD} \
+    WITH_MQ=%{WITH_MQ} \
+    WITH_PROXY=%{WITH_PROXY} \
+    WITH_TCP=%{WITH_TCP} \
+    RD_MODE=%{RD_MODE} \
+    BLE_CUSTOM_ADV=%{BLE_CUSTOM_ADV} \
+    BLE_DIVISION=%{BLE_DIVISION} \
+    BLE_TIZEN_30=%{BLE_TIZEN_30} \
+    MULTIPLE_OWNER=%{MULTIPLE_OWNER} \
+    #eol
+
+mkdir -p %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/examples/OICMiddle/OICMiddle %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/devicediscoveryclient %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/devicediscoveryserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/fridgeclient %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/fridgeserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/garageclient %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/garageserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/groupclient %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/groupserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/lightserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/presenceclient %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/presenceserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/roomclient %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/roomserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/simpleclient %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/simpleclientHQ %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/simpleclientserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/simpleserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/simpleserverHQ %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/threadingsample %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/oic_svr_db_server.dat %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/oic_svr_db_client.dat %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/libcoap.a %{buildroot}%{_libdir}
+cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/lib*.a  %{buildroot}%{_libdir}
+
+%if 0%{?WITH_PROXY} == 1
+mkdir -p %{ex_install_dir}/proxy-sample
+cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/service/coap-http-proxy/samples/proxy_main %{ex_install_dir}/proxy-sample/
+cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/service/coap-http-proxy/samples/proxy_client %{ex_install_dir}/proxy-sample/
+%endif
+%if 0%{?SECURED} == 1
+mkdir -p %{ex_install_dir}/provisioning
+mkdir -p %{ex_install_dir}/provision-sample
+
+cp -R ./extlibs/mbedtls/mbedtls/include/mbedtls/ %{buildroot}%{_includedir}/mbedtls
+cp ./resource/csdk/security/include/*.h %{buildroot}%{_includedir}
+cp ./resource/csdk/connectivity/api/*.h %{buildroot}%{_includedir}/
+cp ./resource/csdk/security/provisioning/include/oxm/*.h %{buildroot}%{_includedir}
+cp ./resource/csdk/security/provisioning/include/internal/*.h %{buildroot}%{_includedir}
+cp ./resource/csdk/security/provisioning/include/*.h %{buildroot}%{_includedir}
+cp ./resource/csdk/security/provisioning/sample/oic_svr_db_server_justworks.dat %{buildroot}%{_libdir}/oic_svr_db_server.dat
+cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/csdk/security/provisioning/sample/sampleserver_justworks %{ex_install_dir}/provision-sample/
+cp ./resource/csdk/security/provisioning/sample/oic_svr_db_server_justworks.dat %{ex_install_dir}/provision-sample/
+cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/csdk/security/provisioning/sample/sampleserver_randompin %{ex_install_dir}/provision-sample/
+cp ./resource/csdk/security/provisioning/sample/oic_svr_db_server_randompin.dat %{ex_install_dir}/provision-sample/
+
+%endif
+
+cp resource/c_common/*.h %{buildroot}%{_includedir}
+cp resource/c_common/ocrandom/include/*.h %{buildroot}%{_includedir}
+cp resource/c_common/oic_string/include/*.h %{buildroot}%{_includedir}
+cp resource/c_common/oic_malloc/include/*.h %{buildroot}%{_includedir}
+cp resource/csdk/stack/include/*.h %{buildroot}%{_includedir}
+cp resource/csdk/logger/include/*.h %{buildroot}%{_includedir}
+
+cp service/easy-setup/inc/*.h %{buildroot}%{_includedir}
+cp service/easy-setup/enrollee/inc/*.h %{buildroot}%{_includedir}
+cp service/easy-setup/mediator/richsdk/inc/*.h %{buildroot}%{_includedir}
+cp service/easy-setup/enrollee/inc/samsung/*.h %{buildroot}%{_includedir}
+
+install -d %{buildroot}%{_includedir}/iotivity
+ln -fs ../resource %{buildroot}%{_includedir}/iotivity/
+ln -fs ../service %{buildroot}%{_includedir}/iotivity/
+ln -fs ../c_common %{buildroot}%{_includedir}/iotivity/
+
+rm -rfv out %{buildroot}/out %{buildroot}/${HOME} ||:
+
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+%files
+%manifest %{name}.manifest
+%defattr(-,root,root,-)
+%if 0%{?tizen_version_major} < 3
+%{_datadir}/license/%{name}
+%else
+%license LICENSE
+%endif
+%{_libdir}/liboc.so
+%{_libdir}/liboc_logger.so
+%{_libdir}/liboc_logger_core.so
+%{_libdir}/liboctbstack.so
+%{_libdir}/libconnectivity_abstraction.so
+%if 0%{?SECURED} == 1
+%{_libdir}/libmbedtls.so
+%{_libdir}/libocpmapi.so
+%{_libdir}/libocprovision.so
+%{_libdir}/oic_svr_db_server.dat
+%endif
+
+%files service
+%manifest %{name}.manifest
+%defattr(-,root,root,-)
+%if 0%{?tizen_version_major} < 3
+%{_datadir}/license/%{name}
+%else
+%license LICENSE
+%endif
+#%{_libdir}/libBMISensorBundle.so
+#%{_libdir}/libDISensorBundle.so
+#%{_libdir}/libHueBundle.so
+%{_libdir}/librcs_client.so
+%{_libdir}/librcs_common.so
+#%{_libdir}/librcs_container.so
+%{_libdir}/librcs_server.so
+%{_libdir}/libresource_directory.so
+%{_libdir}/libESEnrolleeSDK.so
+%{_libdir}/libESMediatorRich.so
+%{_libdir}/libnotification*.so
+%if 0%{?WITH_PROXY} == 1
+%{_libdir}/libcoap_http_proxy.so
+%endif
+%if "%{TARGET_OS}" == "linux"
+%{_libdir}/libnotification*.so
+%endif
+
+%files test
+%manifest %{name}-test.manifest
+%defattr(-,root,root,-)
+%if 0%{?tizen_version_major} < 3
+%{_datadir}/license/%{name}
+%else
+%license LICENSE
+%endif
+%{_bindir}/*
+
+%files devel
+%defattr(-,root,root,-)
+%if 0%{?tizen_version_major} < 3
+%{_datadir}/license/%{name}
+%else
+%license LICENSE
+%endif
+%if 0%{?SECURED} == 1
+%{_libdir}/libmbedtls.so
+%endif
+%{_libdir}/*.a
+%{_libdir}/pkgconfig/%{name}.pc
+%{_includedir}/*
old mode 100755 (executable)
new mode 100644 (file)
index f8e46b1..d220a07
@@ -60,6 +60,14 @@ Source1002: %{name}-test.manifest
 
 %define ex_install_dir %{buildroot}%{_bindir}
 
+%if ! 0%{?license:0}
+%define license %doc
+%endif
+
+%if ! 0%{?manifest:0}
+%define manifest %doc
+%endif
+
 # Default values to be eventually overiden BEFORE or as gbs params:
 %{!?ES_TARGET_ENROLLEE: %define ES_TARGET_ENROLLEE tizen}
 %{!?LOGGING: %define LOGGING 1}
@@ -69,12 +77,17 @@ Source1002: %{name}-test.manifest
 %{!?SECURED: %define SECURED 1}
 %{!?TARGET_ARCH: %define TARGET_ARCH %{_arch}}
 %{!?TARGET_OS: %define TARGET_OS tizen}
-%{!?TARGET_TRANSPORT: %define TARGET_TRANSPORT IP,BT}
+%{!?TARGET_TRANSPORT: %define TARGET_TRANSPORT IP,BLE}
 %{!?VERBOSE: %define VERBOSE 1}
 %{!?WITH_CLOUD: %define WITH_CLOUD 1}
 %{!?WITH_MQ: %define WITH_MQ OFF}
 %{!?WITH_PROXY: %define WITH_PROXY 0}
 %{!?WITH_TCP: %define WITH_TCP 1}
+%{!?RD_MODE: %define RD_MODE CLIENT}
+%{!?BLE_CUSTOM_ADV: %define BLE_CUSTOM_ADV False}
+%{!?BLE_DIVISION: %define BLE_DIVISION VD}
+%{!?BLE_TIZEN_30: %define BLE_TIZEN_30 True}
+%{!?MULTIPLE_OWNER: %define MULTIPLE_OWNER 0}
 
 BuildRequires:  expat-devel
 BuildRequires:  python, libcurl-devel
@@ -91,6 +104,7 @@ BuildRequires:  pkgconfig(sqlite3)
 BuildRequires:  gettext-tools
 BuildRequires:  pkgconfig(dlog)
 BuildRequires:  pkgconfig(capi-network-connection)
+BuildRequires:  pkgconfig(capi-network-wifi)
 BuildRequires:  pkgconfig(capi-network-bluetooth) >= 0.1.52
 %else
 %if 0%{?fedora:1}
@@ -164,11 +178,20 @@ scons %{JOB} --prefix=%{_prefix} \
     WITH_MQ=%{WITH_MQ} \
     WITH_PROXY=%{WITH_PROXY} \
     WITH_TCP=%{WITH_TCP} \
+    RD_MODE=%{RD_MODE} \
+    BLE_CUSTOM_ADV=%{BLE_CUSTOM_ADV} \
+    BLE_DIVISION=%{BLE_DIVISION} \
+    BLE_TIZEN_30=%{BLE_TIZEN_30} \
+    MULTIPLE_OWNER=%{MULTIPLE_OWNER} \
     #eol
 
 
 
 %install
+%if 0%{?tizen_version_major} < 3
+mkdir -p %{buildroot}/%{_datadir}/license
+cp LICENSE %{buildroot}/%{_datadir}/license/%{name}
+%endif
 rm -rf %{buildroot}
 CFLAGS="${CFLAGS:-%optflags}" ; export CFLAGS ;
 scons install --install-sandbox=%{buildroot} --prefix=%{_prefix} \
@@ -187,32 +210,38 @@ scons install --install-sandbox=%{buildroot} --prefix=%{_prefix} \
     WITH_MQ=%{WITH_MQ} \
     WITH_PROXY=%{WITH_PROXY} \
     WITH_TCP=%{WITH_TCP} \
+    RD_MODE=%{RD_MODE} \
+    BLE_CUSTOM_ADV=%{BLE_CUSTOM_ADV} \
+    BLE_DIVISION=%{BLE_DIVISION} \
+    BLE_TIZEN_30=%{BLE_TIZEN_30} \
+    MULTIPLE_OWNER=%{MULTIPLE_OWNER} \
     #eol
 
 mkdir -p %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/examples/OICMiddle/OICMiddle %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/devicediscoveryclient %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/devicediscoveryserver %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/fridgeclient %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/fridgeserver %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/garageclient %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/garageserver %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/groupclient %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/groupserver %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/lightserver %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/presenceclient %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/presenceserver %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/roomclient %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/roomserver %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/simpleclient %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/simpleclientHQ %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/simpleclientserver %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/simpleserver %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/simpleserverHQ %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/threadingsample %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/oic_svr_db_server.dat %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/oic_svr_db_client.dat %{ex_install_dir}
-cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/libcoap.a %{buildroot}%{_libdir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/examples/OICMiddle/OICMiddle %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/devicediscoveryclient %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/devicediscoveryserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/fridgeclient %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/fridgeserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/garageclient %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/garageserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/groupclient %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/groupserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/lightserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/presenceclient %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/presenceserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/roomclient %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/roomserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/simpleclient %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/simpleclientHQ %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/simpleclientserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/simpleserver %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/simpleserverHQ %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/threadingsample %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/oic_svr_db_server.dat %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/examples/oic_svr_db_client.dat %{ex_install_dir}
+#cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/libcoap.a %{buildroot}%{_libdir}
+cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/lib*.a  %{buildroot}%{_libdir}
 
 %if 0%{?WITH_PROXY} == 1
 mkdir -p %{ex_install_dir}/proxy-sample
@@ -223,10 +252,9 @@ cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/service/coap-http-proxy/samples
 mkdir -p %{ex_install_dir}/provisioning
 mkdir -p %{ex_install_dir}/provision-sample
 
-
+cp -R ./extlibs/mbedtls/mbedtls/include/mbedtls/ %{buildroot}%{_includedir}/mbedtls
 cp ./resource/csdk/security/include/*.h %{buildroot}%{_includedir}
 cp ./resource/csdk/connectivity/api/*.h %{buildroot}%{_includedir}/
-cp ./resource/csdk/security/include/internal/*.h %{buildroot}%{_includedir}/
 cp ./resource/csdk/security/provisioning/include/oxm/*.h %{buildroot}%{_includedir}
 cp ./resource/csdk/security/provisioning/include/internal/*.h %{buildroot}%{_includedir}
 cp ./resource/csdk/security/provisioning/include/*.h %{buildroot}%{_includedir}
@@ -235,12 +263,21 @@ cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/csdk/security/provisio
 cp ./resource/csdk/security/provisioning/sample/oic_svr_db_server_justworks.dat %{ex_install_dir}/provision-sample/
 cp out/%{TARGET_OS}/%{TARGET_ARCH}/%{build_mode}/resource/csdk/security/provisioning/sample/sampleserver_randompin %{ex_install_dir}/provision-sample/
 cp ./resource/csdk/security/provisioning/sample/oic_svr_db_server_randompin.dat %{ex_install_dir}/provision-sample/
+
 %endif
 
 cp resource/c_common/*.h %{buildroot}%{_includedir}
+cp resource/c_common/ocrandom/include/*.h %{buildroot}%{_includedir}
+cp resource/c_common/oic_string/include/*.h %{buildroot}%{_includedir}
+cp resource/c_common/oic_malloc/include/*.h %{buildroot}%{_includedir}
 cp resource/csdk/stack/include/*.h %{buildroot}%{_includedir}
 cp resource/csdk/logger/include/*.h %{buildroot}%{_includedir}
 
+cp service/easy-setup/inc/*.h %{buildroot}%{_includedir}
+cp service/easy-setup/enrollee/inc/*.h %{buildroot}%{_includedir}
+cp service/easy-setup/mediator/richsdk/inc/*.h %{buildroot}%{_includedir}
+cp service/easy-setup/enrollee/inc/samsung/*.h %{buildroot}%{_includedir}
+
 install -d %{buildroot}%{_includedir}/iotivity
 ln -fs ../resource %{buildroot}%{_includedir}/iotivity/
 ln -fs ../service %{buildroot}%{_includedir}/iotivity/
@@ -256,13 +293,18 @@ rm -rfv out %{buildroot}/out %{buildroot}/${HOME} ||:
 %files
 %manifest %{name}.manifest
 %defattr(-,root,root,-)
+%if 0%{?tizen_version_major} < 3
+%{_datadir}/license/%{name}
+%else
 %license LICENSE
+%endif
 %{_libdir}/liboc.so
 %{_libdir}/liboc_logger.so
 %{_libdir}/liboc_logger_core.so
 %{_libdir}/liboctbstack.so
 %{_libdir}/libconnectivity_abstraction.so
 %if 0%{?SECURED} == 1
+%{_libdir}/libmbedtls.so
 %{_libdir}/libocpmapi.so
 %{_libdir}/libocprovision.so
 %{_libdir}/oic_svr_db_server.dat
@@ -271,13 +313,17 @@ rm -rfv out %{buildroot}/out %{buildroot}/${HOME} ||:
 %files service
 %manifest %{name}.manifest
 %defattr(-,root,root,-)
+%if 0%{?tizen_version_major} < 3
+%{_datadir}/license/%{name}
+%else
 %license LICENSE
-%{_libdir}/libBMISensorBundle.so
-%{_libdir}/libDISensorBundle.so
-%{_libdir}/libHueBundle.so
+%endif
+#%{_libdir}/libBMISensorBundle.so
+#%{_libdir}/libDISensorBundle.so
+#%{_libdir}/libHueBundle.so
 %{_libdir}/librcs_client.so
 %{_libdir}/librcs_common.so
-%{_libdir}/librcs_container.so
+#%{_libdir}/librcs_container.so
 %{_libdir}/librcs_server.so
 %{_libdir}/libresource_directory.so
 %{_libdir}/libESEnrolleeSDK.so
@@ -293,12 +339,23 @@ rm -rfv out %{buildroot}/out %{buildroot}/${HOME} ||:
 %files test
 %manifest %{name}-test.manifest
 %defattr(-,root,root,-)
+%if 0%{?tizen_version_major} < 3
+%{_datadir}/license/%{name}
+%else
 %license LICENSE
+%endif
 %{_bindir}/*
 
 %files devel
 %defattr(-,root,root,-)
+%if 0%{?tizen_version_major} < 3
+%{_datadir}/license/%{name}
+%else
 %license LICENSE
-%{_libdir}/lib*.a
+%endif
+%if 0%{?SECURED} == 1
+%{_libdir}/libmbedtls.so
+%endif
+%{_libdir}/*.a
 %{_libdir}/pkgconfig/%{name}.pc
 %{_includedir}/*